@elizaos/plugin-browser 2.0.0-alpha.9 → 2.0.3-beta.2
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/LICENSE +21 -0
- package/README.md +98 -83
- package/auto-enable.ts +24 -0
- package/dist/actions/browser-autofill-login.d.ts +43 -0
- package/dist/actions/browser-autofill-login.d.ts.map +1 -0
- package/dist/actions/browser-autofill-login.js +278 -0
- package/dist/actions/browser-autofill-login.js.map +1 -0
- package/dist/actions/browser.d.ts +11 -0
- package/dist/actions/browser.d.ts.map +1 -0
- package/dist/actions/browser.js +412 -0
- package/dist/actions/browser.js.map +1 -0
- package/dist/actions/manage-browser-bridge.d.ts +34 -0
- package/dist/actions/manage-browser-bridge.d.ts.map +1 -0
- package/dist/actions/manage-browser-bridge.js +572 -0
- package/dist/actions/manage-browser-bridge.js.map +1 -0
- package/dist/bridge-policy.d.ts +10 -0
- package/dist/bridge-policy.d.ts.map +1 -0
- package/dist/bridge-policy.js +37 -0
- package/dist/bridge-policy.js.map +1 -0
- package/dist/bridge-readiness.d.ts +16 -0
- package/dist/bridge-readiness.d.ts.map +1 -0
- package/dist/bridge-readiness.js +82 -0
- package/dist/bridge-readiness.js.map +1 -0
- package/dist/bridge-records.d.ts +9 -0
- package/dist/bridge-records.d.ts.map +1 -0
- package/dist/bridge-records.js +37 -0
- package/dist/bridge-records.js.map +1 -0
- package/dist/browser-capture-hooks.d.ts +9 -0
- package/dist/browser-capture-hooks.d.ts.map +1 -0
- package/dist/browser-capture-hooks.js +15 -0
- package/dist/browser-capture-hooks.js.map +1 -0
- package/dist/browser-service.d.ts +103 -0
- package/dist/browser-service.d.ts.map +1 -0
- package/dist/browser-service.js +186 -0
- package/dist/browser-service.js.map +1 -0
- package/dist/browser-workspace-hooks.d.ts +14 -0
- package/dist/browser-workspace-hooks.d.ts.map +1 -0
- package/dist/browser-workspace-hooks.js +15 -0
- package/dist/browser-workspace-hooks.js.map +1 -0
- package/dist/companion-auth.d.ts +34 -0
- package/dist/companion-auth.d.ts.map +1 -0
- package/dist/companion-auth.js +98 -0
- package/dist/companion-auth.js.map +1 -0
- package/dist/contracts.d.ts +284 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +56 -0
- package/dist/contracts.js.map +1 -0
- package/dist/index.d.ts +30 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -90
- package/dist/index.js.map +1 -1
- package/dist/lifeops-session-contracts.d.ts +46 -0
- package/dist/lifeops-session-contracts.d.ts.map +1 -0
- package/dist/lifeops-session-contracts.js +1 -0
- package/dist/lifeops-session-contracts.js.map +1 -0
- package/dist/message-adapter.d.ts +9 -0
- package/dist/message-adapter.d.ts.map +1 -0
- package/dist/message-adapter.js +104 -0
- package/dist/message-adapter.js.map +1 -0
- package/dist/packaging.d.ts +27 -0
- package/dist/packaging.d.ts.map +1 -0
- package/dist/packaging.js +571 -0
- package/dist/packaging.js.map +1 -0
- package/dist/password-manager-bridge.d.ts +50 -0
- package/dist/password-manager-bridge.d.ts.map +1 -0
- package/dist/password-manager-bridge.js +437 -0
- package/dist/password-manager-bridge.js.map +1 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +168 -0
- package/dist/plugin.js.map +1 -0
- package/dist/providers/workspace.d.ts +13 -0
- package/dist/providers/workspace.d.ts.map +1 -0
- package/dist/providers/workspace.js +64 -0
- package/dist/providers/workspace.js.map +1 -0
- package/dist/routes/bridge.d.ts +37 -0
- package/dist/routes/bridge.d.ts.map +1 -0
- package/dist/routes/bridge.js +844 -0
- package/dist/routes/bridge.js.map +1 -0
- package/dist/routes/workspace-account-gate.d.ts +29 -0
- package/dist/routes/workspace-account-gate.d.ts.map +1 -0
- package/dist/routes/workspace-account-gate.js +147 -0
- package/dist/routes/workspace-account-gate.js.map +1 -0
- package/dist/routes/workspace-setup.d.ts +10 -0
- package/dist/routes/workspace-setup.d.ts.map +1 -0
- package/dist/routes/workspace-setup.js +65 -0
- package/dist/routes/workspace-setup.js.map +1 -0
- package/dist/routes/workspace.d.ts +20 -0
- package/dist/routes/workspace.d.ts.map +1 -0
- package/dist/routes/workspace.js +276 -0
- package/dist/routes/workspace.js.map +1 -0
- package/dist/schema.d.ts +2326 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +133 -0
- package/dist/schema.js.map +1 -0
- package/dist/service.d.ts +30 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +5 -0
- package/dist/service.js.map +1 -0
- package/dist/targets/bridge-target.d.ts +31 -0
- package/dist/targets/bridge-target.d.ts.map +1 -0
- package/dist/targets/bridge-target.js +98 -0
- package/dist/targets/bridge-target.js.map +1 -0
- package/dist/targets/stagehand-target.d.ts +3 -0
- package/dist/targets/stagehand-target.d.ts.map +1 -0
- package/dist/targets/stagehand-target.js +187 -0
- package/dist/targets/stagehand-target.js.map +1 -0
- package/dist/workspace/browser-capture.d.ts +41 -0
- package/dist/workspace/browser-capture.d.ts.map +1 -0
- package/dist/workspace/browser-capture.js +159 -0
- package/dist/workspace/browser-capture.js.map +1 -0
- package/dist/workspace/browser-workspace-desktop.d.ts +19 -0
- package/dist/workspace/browser-workspace-desktop.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-desktop.js +1578 -0
- package/dist/workspace/browser-workspace-desktop.js.map +1 -0
- package/dist/workspace/browser-workspace-elements.d.ts +42 -0
- package/dist/workspace/browser-workspace-elements.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-elements.js +547 -0
- package/dist/workspace/browser-workspace-elements.js.map +1 -0
- package/dist/workspace/browser-workspace-forms.d.ts +19 -0
- package/dist/workspace/browser-workspace-forms.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-forms.js +277 -0
- package/dist/workspace/browser-workspace-forms.js.map +1 -0
- package/dist/workspace/browser-workspace-helpers.d.ts +32 -0
- package/dist/workspace/browser-workspace-helpers.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-helpers.js +232 -0
- package/dist/workspace/browser-workspace-helpers.js.map +1 -0
- package/dist/workspace/browser-workspace-jsdom.d.ts +16 -0
- package/dist/workspace/browser-workspace-jsdom.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-jsdom.js +233 -0
- package/dist/workspace/browser-workspace-jsdom.js.map +1 -0
- package/dist/workspace/browser-workspace-network.d.ts +7 -0
- package/dist/workspace/browser-workspace-network.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-network.js +145 -0
- package/dist/workspace/browser-workspace-network.js.map +1 -0
- package/dist/workspace/browser-workspace-snapshots.d.ts +14 -0
- package/dist/workspace/browser-workspace-snapshots.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-snapshots.js +144 -0
- package/dist/workspace/browser-workspace-snapshots.js.map +1 -0
- package/dist/workspace/browser-workspace-state.d.ts +24 -0
- package/dist/workspace/browser-workspace-state.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-state.js +155 -0
- package/dist/workspace/browser-workspace-state.js.map +1 -0
- package/dist/workspace/browser-workspace-types.d.ts +345 -0
- package/dist/workspace/browser-workspace-types.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-types.js +11 -0
- package/dist/workspace/browser-workspace-types.js.map +1 -0
- package/dist/workspace/browser-workspace-web.d.ts +8 -0
- package/dist/workspace/browser-workspace-web.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-web.js +1342 -0
- package/dist/workspace/browser-workspace-web.js.map +1 -0
- package/dist/workspace/browser-workspace.d.ts +39 -0
- package/dist/workspace/browser-workspace.d.ts.map +1 -0
- package/dist/workspace/browser-workspace.js +958 -0
- package/dist/workspace/browser-workspace.js.map +1 -0
- package/dist/workspace/index.d.ts +26 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +3 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace.d.ts +2 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +2 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +71 -110
- package/dist/actions/click.d.ts +0 -3
- package/dist/actions/click.d.ts.map +0 -1
- package/dist/actions/click.js +0 -158
- package/dist/actions/click.js.map +0 -1
- package/dist/actions/extract.d.ts +0 -3
- package/dist/actions/extract.d.ts.map +0 -1
- package/dist/actions/extract.js +0 -168
- package/dist/actions/extract.js.map +0 -1
- package/dist/actions/index.d.ts +0 -7
- package/dist/actions/index.d.ts.map +0 -1
- package/dist/actions/index.js +0 -7
- package/dist/actions/index.js.map +0 -1
- package/dist/actions/navigate.d.ts +0 -3
- package/dist/actions/navigate.d.ts.map +0 -1
- package/dist/actions/navigate.js +0 -187
- package/dist/actions/navigate.js.map +0 -1
- package/dist/actions/screenshot.d.ts +0 -3
- package/dist/actions/screenshot.d.ts.map +0 -1
- package/dist/actions/screenshot.js +0 -167
- package/dist/actions/screenshot.js.map +0 -1
- package/dist/actions/select.d.ts +0 -3
- package/dist/actions/select.d.ts.map +0 -1
- package/dist/actions/select.js +0 -167
- package/dist/actions/select.js.map +0 -1
- package/dist/actions/type.d.ts +0 -3
- package/dist/actions/type.d.ts.map +0 -1
- package/dist/actions/type.js +0 -167
- package/dist/actions/type.js.map +0 -1
- package/dist/cli/index.d.ts +0 -8
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -13
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/register.d.ts +0 -20
- package/dist/cli/register.d.ts.map +0 -1
- package/dist/cli/register.js +0 -403
- package/dist/cli/register.js.map +0 -1
- package/dist/providerRelevance.d.ts +0 -4
- package/dist/providerRelevance.d.ts.map +0 -1
- package/dist/providerRelevance.js +0 -33
- package/dist/providerRelevance.js.map +0 -1
- package/dist/providers/browser-state.d.ts +0 -3
- package/dist/providers/browser-state.d.ts.map +0 -1
- package/dist/providers/browser-state.js +0 -72
- package/dist/providers/browser-state.js.map +0 -1
- package/dist/providers/index.d.ts +0 -2
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -2
- package/dist/providers/index.js.map +0 -1
- package/dist/services/browser-service.d.ts +0 -32
- package/dist/services/browser-service.d.ts.map +0 -1
- package/dist/services/browser-service.js +0 -213
- package/dist/services/browser-service.js.map +0 -1
- package/dist/services/index.d.ts +0 -4
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js +0 -4
- package/dist/services/index.js.map +0 -1
- package/dist/services/process-manager.d.ts +0 -24
- package/dist/services/process-manager.d.ts.map +0 -1
- package/dist/services/process-manager.js +0 -270
- package/dist/services/process-manager.js.map +0 -1
- package/dist/services/websocket-client.d.ts +0 -35
- package/dist/services/websocket-client.d.ts.map +0 -1
- package/dist/services/websocket-client.js +0 -221
- package/dist/services/websocket-client.js.map +0 -1
- package/dist/types.d.ts +0 -101
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/captcha.d.ts +0 -33
- package/dist/utils/captcha.d.ts.map +0 -1
- package/dist/utils/captcha.js +0 -219
- package/dist/utils/captcha.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -37
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -81
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -5
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/retry.d.ts +0 -26
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/retry.js +0 -55
- package/dist/utils/retry.js.map +0 -1
- package/dist/utils/security.d.ts +0 -27
- package/dist/utils/security.d.ts.map +0 -1
- package/dist/utils/security.js +0 -139
- package/dist/utils/security.js.map +0 -1
- package/dist/utils/url.d.ts +0 -12
- package/dist/utils/url.d.ts.map +0 -1
- package/dist/utils/url.js +0 -39
- package/dist/utils/url.js.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password manager bridge — dual-backend (1Password CLI `op` or ProtonPass CLI).
|
|
3
|
+
*
|
|
4
|
+
* Security posture:
|
|
5
|
+
* - Plaintext credentials NEVER enter return values.
|
|
6
|
+
* - `injectCredentialToClipboard` pipes the secret from the backend CLI
|
|
7
|
+
* directly into the OS clipboard via `execFile` without ever surfacing
|
|
8
|
+
* the value to the Node process beyond a narrow buffer that is
|
|
9
|
+
* discarded immediately.
|
|
10
|
+
* - Nothing is logged that could contain secret material.
|
|
11
|
+
* - All subprocess invocations use `execFile` with an args array.
|
|
12
|
+
*/
|
|
13
|
+
export type PasswordManagerBackend = "1password" | "protonpass" | "fixture" | "none";
|
|
14
|
+
export interface PasswordManagerItem {
|
|
15
|
+
id: string;
|
|
16
|
+
title: string;
|
|
17
|
+
url?: string;
|
|
18
|
+
username?: string;
|
|
19
|
+
/** Metadata flag only — the actual password is never returned. */
|
|
20
|
+
hasPassword: boolean;
|
|
21
|
+
tags?: string[];
|
|
22
|
+
metadata?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface PasswordManagerBridgeConfig {
|
|
25
|
+
preferredBackend?: PasswordManagerBackend;
|
|
26
|
+
/** Passed via `op --account`. Sourced from env `ELIZA_1PASSWORD_ACCOUNT`. */
|
|
27
|
+
onePasswordAccount?: string;
|
|
28
|
+
/** Binary override for 1Password CLI (default: "op"). */
|
|
29
|
+
opPath?: string;
|
|
30
|
+
/** Binary override for ProtonPass CLI (default: "protonpass" then "pass"). */
|
|
31
|
+
protonPassPath?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare class PasswordManagerError extends Error {
|
|
34
|
+
readonly backend: PasswordManagerBackend;
|
|
35
|
+
readonly cause?: unknown;
|
|
36
|
+
constructor(message: string, backend: PasswordManagerBackend, cause?: unknown);
|
|
37
|
+
}
|
|
38
|
+
export declare function detectPasswordManagerBackend(config?: PasswordManagerBridgeConfig): Promise<PasswordManagerBackend>;
|
|
39
|
+
/** Clear the backend detection cache. Exposed for tests. */
|
|
40
|
+
export declare function clearPasswordManagerBackendCache(): void;
|
|
41
|
+
export declare function searchPasswordItems(query: string, config?: PasswordManagerBridgeConfig): Promise<PasswordManagerItem[]>;
|
|
42
|
+
export declare function listPasswordItems(opts: {
|
|
43
|
+
limit?: number;
|
|
44
|
+
}, config?: PasswordManagerBridgeConfig): Promise<PasswordManagerItem[]>;
|
|
45
|
+
export declare function injectCredentialToClipboard(itemId: string, field: "username" | "password", config?: PasswordManagerBridgeConfig): Promise<{
|
|
46
|
+
ok: true;
|
|
47
|
+
expiresInSeconds: number;
|
|
48
|
+
fixtureMode?: boolean;
|
|
49
|
+
}>;
|
|
50
|
+
//# sourceMappingURL=password-manager-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-manager-bridge.d.ts","sourceRoot":"","sources":["../src/password-manager-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,MAAM,MAAM,sBAAsB,GAC9B,WAAW,GACX,YAAY,GACZ,SAAS,GACT,MAAM,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;gBAGvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,sBAAsB,EAC/B,KAAK,CAAC,EAAE,OAAO;CAOlB;AA0HD,wBAAsB,4BAA4B,CAChD,MAAM,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAyCjC;AAED,4DAA4D;AAC5D,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAoSD,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAShC;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EACxB,MAAM,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAahC;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,GAAG,UAAU,EAC9B,MAAM,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CA6DxE"}
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { logger } from "@elizaos/core";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
class PasswordManagerError extends Error {
|
|
6
|
+
backend;
|
|
7
|
+
cause;
|
|
8
|
+
constructor(message, backend, cause) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "PasswordManagerError";
|
|
11
|
+
this.backend = backend;
|
|
12
|
+
this.cause = cause;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const CLIPBOARD_TTL_SECONDS = 30;
|
|
16
|
+
const PASSWORD_MANAGER_FIXTURE_ITEMS = [
|
|
17
|
+
{
|
|
18
|
+
id: "pm-github",
|
|
19
|
+
title: "GitHub",
|
|
20
|
+
url: "https://github.com/login",
|
|
21
|
+
username: "benchmark-user",
|
|
22
|
+
hasPassword: true,
|
|
23
|
+
tags: ["dev", "github", "code"],
|
|
24
|
+
metadata: { vault: "Mocked Benchmark" }
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "pm-google-workspace",
|
|
28
|
+
title: "Google Workspace",
|
|
29
|
+
url: "https://mail.google.com",
|
|
30
|
+
username: "owner@example.com",
|
|
31
|
+
hasPassword: true,
|
|
32
|
+
tags: ["google", "email"],
|
|
33
|
+
metadata: { vault: "Mocked Benchmark" }
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "pm-aws-prod",
|
|
37
|
+
title: "AWS Console",
|
|
38
|
+
url: "https://signin.aws.amazon.com",
|
|
39
|
+
username: "infra@example.com",
|
|
40
|
+
hasPassword: true,
|
|
41
|
+
tags: ["aws", "cloud"],
|
|
42
|
+
metadata: { vault: "Mocked Benchmark" }
|
|
43
|
+
}
|
|
44
|
+
];
|
|
45
|
+
function isTruthyEnv(value) {
|
|
46
|
+
if (!value) return false;
|
|
47
|
+
const normalized = value.trim().toLowerCase();
|
|
48
|
+
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on" || normalized === "fixture";
|
|
49
|
+
}
|
|
50
|
+
function isFalsyEnv(value) {
|
|
51
|
+
if (!value) return false;
|
|
52
|
+
const normalized = value.trim().toLowerCase();
|
|
53
|
+
return normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off";
|
|
54
|
+
}
|
|
55
|
+
function isFixturePasswordManagerEnabled() {
|
|
56
|
+
const explicit = process.env.ELIZA_TEST_PASSWORD_MANAGER_BACKEND;
|
|
57
|
+
if (isFalsyEnv(explicit)) return false;
|
|
58
|
+
if (isTruthyEnv(explicit)) return true;
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
function listItemsViaFixture() {
|
|
62
|
+
return PASSWORD_MANAGER_FIXTURE_ITEMS.map((item) => ({
|
|
63
|
+
...item,
|
|
64
|
+
tags: item.tags ? [...item.tags] : void 0,
|
|
65
|
+
metadata: item.metadata ? { ...item.metadata } : void 0
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
const detectionCache = /* @__PURE__ */ new Map();
|
|
69
|
+
function cacheKey(config) {
|
|
70
|
+
const c = config ?? {};
|
|
71
|
+
return [
|
|
72
|
+
c.preferredBackend ?? "",
|
|
73
|
+
c.onePasswordAccount ?? "",
|
|
74
|
+
c.opPath ?? "",
|
|
75
|
+
c.protonPassPath ?? ""
|
|
76
|
+
].join("|");
|
|
77
|
+
}
|
|
78
|
+
function resolveOpBinary(config) {
|
|
79
|
+
return config?.opPath?.trim() || "op";
|
|
80
|
+
}
|
|
81
|
+
function resolveProtonPassBinary(config) {
|
|
82
|
+
return config?.protonPassPath?.trim() || "protonpass";
|
|
83
|
+
}
|
|
84
|
+
async function probeBinary(binary, args) {
|
|
85
|
+
try {
|
|
86
|
+
await execFileAsync(binary, args, { timeout: 3e3 });
|
|
87
|
+
return true;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function probeOp(config) {
|
|
93
|
+
return probeBinary(resolveOpBinary(config), ["--version"]);
|
|
94
|
+
}
|
|
95
|
+
async function probeProtonPass(config) {
|
|
96
|
+
if (await probeBinary(resolveProtonPassBinary(config), ["--version"])) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
if (!config?.protonPassPath) {
|
|
100
|
+
return probeBinary("pass", ["--version"]);
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
async function detectPasswordManagerBackend(config) {
|
|
105
|
+
const key = cacheKey(config);
|
|
106
|
+
const cached = detectionCache.get(key);
|
|
107
|
+
if (cached !== void 0) return cached;
|
|
108
|
+
const preferred = config?.preferredBackend;
|
|
109
|
+
if (preferred === "none") {
|
|
110
|
+
detectionCache.set(key, "none");
|
|
111
|
+
return "none";
|
|
112
|
+
}
|
|
113
|
+
if (preferred === "fixture") {
|
|
114
|
+
detectionCache.set(key, "fixture");
|
|
115
|
+
return "fixture";
|
|
116
|
+
}
|
|
117
|
+
if (isFixturePasswordManagerEnabled()) {
|
|
118
|
+
detectionCache.set(key, "fixture");
|
|
119
|
+
return "fixture";
|
|
120
|
+
}
|
|
121
|
+
if (preferred === "1password") {
|
|
122
|
+
const ok = await probeOp(config);
|
|
123
|
+
const result = ok ? "1password" : "none";
|
|
124
|
+
detectionCache.set(key, result);
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
if (preferred === "protonpass") {
|
|
128
|
+
const ok = await probeProtonPass(config);
|
|
129
|
+
const result = ok ? "protonpass" : "none";
|
|
130
|
+
detectionCache.set(key, result);
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
if (await probeOp(config)) {
|
|
134
|
+
detectionCache.set(key, "1password");
|
|
135
|
+
return "1password";
|
|
136
|
+
}
|
|
137
|
+
if (await probeProtonPass(config)) {
|
|
138
|
+
detectionCache.set(key, "protonpass");
|
|
139
|
+
return "protonpass";
|
|
140
|
+
}
|
|
141
|
+
detectionCache.set(key, "none");
|
|
142
|
+
return "none";
|
|
143
|
+
}
|
|
144
|
+
function clearPasswordManagerBackendCache() {
|
|
145
|
+
detectionCache.clear();
|
|
146
|
+
}
|
|
147
|
+
function opBaseArgs(config) {
|
|
148
|
+
const args = [];
|
|
149
|
+
const account = config?.onePasswordAccount?.trim();
|
|
150
|
+
if (account) args.push("--account", account);
|
|
151
|
+
return args;
|
|
152
|
+
}
|
|
153
|
+
async function runOp(args, config) {
|
|
154
|
+
const binary = resolveOpBinary(config);
|
|
155
|
+
const fullArgs = [...opBaseArgs(config), ...args];
|
|
156
|
+
try {
|
|
157
|
+
const { stdout } = await execFileAsync(binary, fullArgs, {
|
|
158
|
+
timeout: 15e3,
|
|
159
|
+
maxBuffer: 16 * 1024 * 1024
|
|
160
|
+
});
|
|
161
|
+
return stdout;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
throw new PasswordManagerError(
|
|
164
|
+
`1Password CLI failed for "${args[0] ?? ""}": ${error instanceof Error ? error.message : String(error)}`,
|
|
165
|
+
"1password",
|
|
166
|
+
error
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function normalizeOpListEntry(raw) {
|
|
171
|
+
const id = raw.id ?? "";
|
|
172
|
+
if (!id) {
|
|
173
|
+
throw new PasswordManagerError("1Password item missing id", "1password");
|
|
174
|
+
}
|
|
175
|
+
const primaryUrl = raw.urls?.find((u) => u.primary)?.href ?? raw.urls?.[0]?.href;
|
|
176
|
+
return {
|
|
177
|
+
id,
|
|
178
|
+
title: raw.title ?? id,
|
|
179
|
+
url: primaryUrl,
|
|
180
|
+
username: raw.additional_information,
|
|
181
|
+
hasPassword: (raw.category ?? "").toUpperCase() === "LOGIN",
|
|
182
|
+
tags: raw.tags,
|
|
183
|
+
metadata: {
|
|
184
|
+
category: raw.category,
|
|
185
|
+
vault: raw.vault?.name
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
async function listItemsVia1Password(config) {
|
|
190
|
+
const stdout = await runOp(["item", "list", "--format", "json"], config);
|
|
191
|
+
const trimmed = stdout.trim();
|
|
192
|
+
if (!trimmed) return [];
|
|
193
|
+
let parsed;
|
|
194
|
+
try {
|
|
195
|
+
parsed = JSON.parse(trimmed);
|
|
196
|
+
} catch (error) {
|
|
197
|
+
throw new PasswordManagerError(
|
|
198
|
+
"1Password returned invalid JSON from item list",
|
|
199
|
+
"1password",
|
|
200
|
+
error
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (!Array.isArray(parsed)) {
|
|
204
|
+
throw new PasswordManagerError(
|
|
205
|
+
"1Password item list was not an array",
|
|
206
|
+
"1password"
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return parsed.map(normalizeOpListEntry);
|
|
210
|
+
}
|
|
211
|
+
function matchesQuery(item, q) {
|
|
212
|
+
if (!q) return true;
|
|
213
|
+
const needle = q.toLowerCase();
|
|
214
|
+
if (item.title.toLowerCase().includes(needle)) return true;
|
|
215
|
+
if (item.url?.toLowerCase().includes(needle)) return true;
|
|
216
|
+
if (item.username?.toLowerCase().includes(needle)) return true;
|
|
217
|
+
if (item.tags?.some((t) => t.toLowerCase().includes(needle))) return true;
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
async function listItemsViaProtonPass(config) {
|
|
221
|
+
const binary = resolveProtonPassBinary(config);
|
|
222
|
+
let stdout;
|
|
223
|
+
try {
|
|
224
|
+
const result = await execFileAsync(binary, ["list"], {
|
|
225
|
+
timeout: 1e4,
|
|
226
|
+
maxBuffer: 8 * 1024 * 1024
|
|
227
|
+
});
|
|
228
|
+
stdout = result.stdout;
|
|
229
|
+
} catch (error) {
|
|
230
|
+
if (!config?.protonPassPath) {
|
|
231
|
+
try {
|
|
232
|
+
const result = await execFileAsync("pass", ["ls"], {
|
|
233
|
+
timeout: 1e4,
|
|
234
|
+
maxBuffer: 8 * 1024 * 1024
|
|
235
|
+
});
|
|
236
|
+
stdout = result.stdout;
|
|
237
|
+
} catch (inner) {
|
|
238
|
+
throw new PasswordManagerError(
|
|
239
|
+
`ProtonPass/pass list failed: ${inner instanceof Error ? inner.message : String(inner)}`,
|
|
240
|
+
"protonpass",
|
|
241
|
+
inner
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
throw new PasswordManagerError(
|
|
246
|
+
`ProtonPass list failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
247
|
+
"protonpass",
|
|
248
|
+
error
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const items = [];
|
|
253
|
+
for (const rawLine of stdout.split("\n")) {
|
|
254
|
+
const line = rawLine.replace(/[│├└─]+/g, "").replace(/\u00a0/g, " ").trim();
|
|
255
|
+
if (!line) continue;
|
|
256
|
+
if (line.toLowerCase().startsWith("password store")) continue;
|
|
257
|
+
items.push({
|
|
258
|
+
id: line,
|
|
259
|
+
title: line,
|
|
260
|
+
hasPassword: true
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return items;
|
|
264
|
+
}
|
|
265
|
+
function clipboardCommand() {
|
|
266
|
+
switch (process.platform) {
|
|
267
|
+
case "darwin":
|
|
268
|
+
return { cmd: "pbcopy", args: [] };
|
|
269
|
+
case "win32":
|
|
270
|
+
return { cmd: "clip", args: [] };
|
|
271
|
+
default:
|
|
272
|
+
return { cmd: "xclip", args: ["-selection", "clipboard"] };
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async function pipeToClipboard(producer, backend) {
|
|
276
|
+
const clip = clipboardCommand();
|
|
277
|
+
await new Promise((resolve, reject) => {
|
|
278
|
+
const source = spawn(producer.cmd, producer.args, {
|
|
279
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
280
|
+
});
|
|
281
|
+
const sink = spawn(clip.cmd, clip.args, {
|
|
282
|
+
stdio: ["pipe", "ignore", "pipe"]
|
|
283
|
+
});
|
|
284
|
+
let settled = false;
|
|
285
|
+
const settle = (err) => {
|
|
286
|
+
if (settled) return;
|
|
287
|
+
settled = true;
|
|
288
|
+
if (err) {
|
|
289
|
+
source.kill();
|
|
290
|
+
sink.kill();
|
|
291
|
+
reject(err);
|
|
292
|
+
} else {
|
|
293
|
+
resolve();
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
source.on(
|
|
297
|
+
"error",
|
|
298
|
+
(err) => settle(
|
|
299
|
+
new PasswordManagerError(
|
|
300
|
+
`Failed to run ${producer.cmd}: ${err.message}`,
|
|
301
|
+
backend,
|
|
302
|
+
err
|
|
303
|
+
)
|
|
304
|
+
)
|
|
305
|
+
);
|
|
306
|
+
sink.on(
|
|
307
|
+
"error",
|
|
308
|
+
(err) => settle(
|
|
309
|
+
new PasswordManagerError(
|
|
310
|
+
`Failed to run clipboard command ${clip.cmd}: ${err.message}`,
|
|
311
|
+
backend,
|
|
312
|
+
err
|
|
313
|
+
)
|
|
314
|
+
)
|
|
315
|
+
);
|
|
316
|
+
source.stdout.pipe(sink.stdin);
|
|
317
|
+
let sourceExit = null;
|
|
318
|
+
let sinkExit = null;
|
|
319
|
+
const maybeDone = () => {
|
|
320
|
+
if (sourceExit === null || sinkExit === null) return;
|
|
321
|
+
if (sourceExit !== 0) {
|
|
322
|
+
settle(
|
|
323
|
+
new PasswordManagerError(
|
|
324
|
+
`${producer.cmd} exited with code ${sourceExit}`,
|
|
325
|
+
backend
|
|
326
|
+
)
|
|
327
|
+
);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (sinkExit !== 0) {
|
|
331
|
+
settle(
|
|
332
|
+
new PasswordManagerError(
|
|
333
|
+
`${clip.cmd} exited with code ${sinkExit}`,
|
|
334
|
+
backend
|
|
335
|
+
)
|
|
336
|
+
);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
settle();
|
|
340
|
+
};
|
|
341
|
+
source.on("close", (code) => {
|
|
342
|
+
sourceExit = code ?? 0;
|
|
343
|
+
maybeDone();
|
|
344
|
+
});
|
|
345
|
+
sink.on("close", (code) => {
|
|
346
|
+
sinkExit = code ?? 0;
|
|
347
|
+
maybeDone();
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
async function resolveActiveBackend(config) {
|
|
352
|
+
const backend = await detectPasswordManagerBackend(config);
|
|
353
|
+
if (backend === "none") {
|
|
354
|
+
throw new PasswordManagerError(
|
|
355
|
+
"No password manager backend available (install 1Password CLI `op` or ProtonPass/`pass`)",
|
|
356
|
+
"none"
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
return backend;
|
|
360
|
+
}
|
|
361
|
+
async function searchPasswordItems(query, config) {
|
|
362
|
+
const backend = await resolveActiveBackend(config);
|
|
363
|
+
const items = backend === "fixture" ? listItemsViaFixture() : backend === "1password" ? await listItemsVia1Password(config) : await listItemsViaProtonPass(config);
|
|
364
|
+
return items.filter((item) => matchesQuery(item, query));
|
|
365
|
+
}
|
|
366
|
+
async function listPasswordItems(opts, config) {
|
|
367
|
+
const backend = await resolveActiveBackend(config);
|
|
368
|
+
const items = backend === "fixture" ? listItemsViaFixture() : backend === "1password" ? await listItemsVia1Password(config) : await listItemsViaProtonPass(config);
|
|
369
|
+
const limit = opts.limit;
|
|
370
|
+
if (typeof limit === "number" && limit >= 0) {
|
|
371
|
+
return items.slice(0, limit);
|
|
372
|
+
}
|
|
373
|
+
return items;
|
|
374
|
+
}
|
|
375
|
+
async function injectCredentialToClipboard(itemId, field, config) {
|
|
376
|
+
if (!itemId || typeof itemId !== "string") {
|
|
377
|
+
throw new PasswordManagerError(
|
|
378
|
+
"itemId is required",
|
|
379
|
+
config?.preferredBackend ?? "none"
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
const backend = await resolveActiveBackend(config);
|
|
383
|
+
if (backend === "fixture") {
|
|
384
|
+
logger.warn(
|
|
385
|
+
{
|
|
386
|
+
itemId,
|
|
387
|
+
field,
|
|
388
|
+
boundary: "browser",
|
|
389
|
+
component: "password-manager-bridge"
|
|
390
|
+
},
|
|
391
|
+
"[password-manager-bridge] fixture backend active: no clipboard write performed. Set ELIZA_TEST_PASSWORD_MANAGER_BACKEND=0 for real injection."
|
|
392
|
+
);
|
|
393
|
+
return {
|
|
394
|
+
ok: true,
|
|
395
|
+
expiresInSeconds: CLIPBOARD_TTL_SECONDS,
|
|
396
|
+
fixtureMode: true
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
if (backend === "1password") {
|
|
400
|
+
const binary2 = resolveOpBinary(config);
|
|
401
|
+
const args = [
|
|
402
|
+
...opBaseArgs(config),
|
|
403
|
+
"item",
|
|
404
|
+
"get",
|
|
405
|
+
itemId,
|
|
406
|
+
"--fields",
|
|
407
|
+
field === "password" ? "password" : "username",
|
|
408
|
+
"--reveal"
|
|
409
|
+
];
|
|
410
|
+
await pipeToClipboard({ cmd: binary2, args }, "1password");
|
|
411
|
+
return { ok: true, expiresInSeconds: CLIPBOARD_TTL_SECONDS };
|
|
412
|
+
}
|
|
413
|
+
const binary = resolveProtonPassBinary(config);
|
|
414
|
+
if (field === "username") {
|
|
415
|
+
throw new PasswordManagerError(
|
|
416
|
+
"Username injection is not supported by the ProtonPass/pass backend",
|
|
417
|
+
"protonpass"
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
let producerCmd = binary;
|
|
421
|
+
const producerArgs = ["show", itemId];
|
|
422
|
+
if (!config?.protonPassPath) {
|
|
423
|
+
const hasProton = await probeBinary(binary, ["--version"]);
|
|
424
|
+
if (!hasProton) producerCmd = "pass";
|
|
425
|
+
}
|
|
426
|
+
await pipeToClipboard({ cmd: producerCmd, args: producerArgs }, "protonpass");
|
|
427
|
+
return { ok: true, expiresInSeconds: CLIPBOARD_TTL_SECONDS };
|
|
428
|
+
}
|
|
429
|
+
export {
|
|
430
|
+
PasswordManagerError,
|
|
431
|
+
clearPasswordManagerBackendCache,
|
|
432
|
+
detectPasswordManagerBackend,
|
|
433
|
+
injectCredentialToClipboard,
|
|
434
|
+
listPasswordItems,
|
|
435
|
+
searchPasswordItems
|
|
436
|
+
};
|
|
437
|
+
//# sourceMappingURL=password-manager-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/password-manager-bridge.ts"],"sourcesContent":["/**\n * Password manager bridge — dual-backend (1Password CLI `op` or ProtonPass CLI).\n *\n * Security posture:\n * - Plaintext credentials NEVER enter return values.\n * - `injectCredentialToClipboard` pipes the secret from the backend CLI\n * directly into the OS clipboard via `execFile` without ever surfacing\n * the value to the Node process beyond a narrow buffer that is\n * discarded immediately.\n * - Nothing is logged that could contain secret material.\n * - All subprocess invocations use `execFile` with an args array.\n */\n\nimport { execFile, spawn } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { logger } from \"@elizaos/core\";\n\nconst execFileAsync = promisify(execFile);\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PasswordManagerBackend =\n | \"1password\"\n | \"protonpass\"\n | \"fixture\"\n | \"none\";\n\nexport interface PasswordManagerItem {\n id: string;\n title: string;\n url?: string;\n username?: string;\n /** Metadata flag only — the actual password is never returned. */\n hasPassword: boolean;\n tags?: string[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface PasswordManagerBridgeConfig {\n preferredBackend?: PasswordManagerBackend;\n /** Passed via `op --account`. Sourced from env `ELIZA_1PASSWORD_ACCOUNT`. */\n onePasswordAccount?: string;\n /** Binary override for 1Password CLI (default: \"op\"). */\n opPath?: string;\n /** Binary override for ProtonPass CLI (default: \"protonpass\" then \"pass\"). */\n protonPassPath?: string;\n}\n\nexport class PasswordManagerError extends Error {\n readonly backend: PasswordManagerBackend;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n backend: PasswordManagerBackend,\n cause?: unknown,\n ) {\n super(message);\n this.name = \"PasswordManagerError\";\n this.backend = backend;\n this.cause = cause;\n }\n}\n\nconst CLIPBOARD_TTL_SECONDS = 30;\n\nconst PASSWORD_MANAGER_FIXTURE_ITEMS: ReadonlyArray<PasswordManagerItem> = [\n {\n id: \"pm-github\",\n title: \"GitHub\",\n url: \"https://github.com/login\",\n username: \"benchmark-user\",\n hasPassword: true,\n tags: [\"dev\", \"github\", \"code\"],\n metadata: { vault: \"Mocked Benchmark\" },\n },\n {\n id: \"pm-google-workspace\",\n title: \"Google Workspace\",\n url: \"https://mail.google.com\",\n username: \"owner@example.com\",\n hasPassword: true,\n tags: [\"google\", \"email\"],\n metadata: { vault: \"Mocked Benchmark\" },\n },\n {\n id: \"pm-aws-prod\",\n title: \"AWS Console\",\n url: \"https://signin.aws.amazon.com\",\n username: \"infra@example.com\",\n hasPassword: true,\n tags: [\"aws\", \"cloud\"],\n metadata: { vault: \"Mocked Benchmark\" },\n },\n];\n\nfunction isTruthyEnv(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return (\n normalized === \"1\" ||\n normalized === \"true\" ||\n normalized === \"yes\" ||\n normalized === \"on\" ||\n normalized === \"fixture\"\n );\n}\n\nfunction isFalsyEnv(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return (\n normalized === \"0\" ||\n normalized === \"false\" ||\n normalized === \"no\" ||\n normalized === \"off\"\n );\n}\n\nfunction isFixturePasswordManagerEnabled(): boolean {\n const explicit = process.env.ELIZA_TEST_PASSWORD_MANAGER_BACKEND;\n if (isFalsyEnv(explicit)) return false;\n if (isTruthyEnv(explicit)) return true;\n return false;\n}\n\nfunction listItemsViaFixture(): PasswordManagerItem[] {\n return PASSWORD_MANAGER_FIXTURE_ITEMS.map((item) => ({\n ...item,\n tags: item.tags ? [...item.tags] : undefined,\n metadata: item.metadata ? { ...item.metadata } : undefined,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Detection\n// ---------------------------------------------------------------------------\n\nconst detectionCache = new Map<string, PasswordManagerBackend>();\n\nfunction cacheKey(config?: PasswordManagerBridgeConfig): string {\n const c = config ?? {};\n return [\n c.preferredBackend ?? \"\",\n c.onePasswordAccount ?? \"\",\n c.opPath ?? \"\",\n c.protonPassPath ?? \"\",\n ].join(\"|\");\n}\n\nfunction resolveOpBinary(config?: PasswordManagerBridgeConfig): string {\n return config?.opPath?.trim() || \"op\";\n}\n\nfunction resolveProtonPassBinary(config?: PasswordManagerBridgeConfig): string {\n return config?.protonPassPath?.trim() || \"protonpass\";\n}\n\nasync function probeBinary(binary: string, args: string[]): Promise<boolean> {\n try {\n await execFileAsync(binary, args, { timeout: 3_000 });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function probeOp(config?: PasswordManagerBridgeConfig): Promise<boolean> {\n return probeBinary(resolveOpBinary(config), [\"--version\"]);\n}\n\nasync function probeProtonPass(\n config?: PasswordManagerBridgeConfig,\n): Promise<boolean> {\n if (await probeBinary(resolveProtonPassBinary(config), [\"--version\"])) {\n return true;\n }\n // `pass` — classic Unix password-store — also supported as a fallback.\n if (!config?.protonPassPath) {\n return probeBinary(\"pass\", [\"--version\"]);\n }\n return false;\n}\n\nexport async function detectPasswordManagerBackend(\n config?: PasswordManagerBridgeConfig,\n): Promise<PasswordManagerBackend> {\n const key = cacheKey(config);\n const cached = detectionCache.get(key);\n if (cached !== undefined) return cached;\n\n const preferred = config?.preferredBackend;\n if (preferred === \"none\") {\n detectionCache.set(key, \"none\");\n return \"none\";\n }\n if (preferred === \"fixture\") {\n detectionCache.set(key, \"fixture\");\n return \"fixture\";\n }\n if (isFixturePasswordManagerEnabled()) {\n detectionCache.set(key, \"fixture\");\n return \"fixture\";\n }\n if (preferred === \"1password\") {\n const ok = await probeOp(config);\n const result: PasswordManagerBackend = ok ? \"1password\" : \"none\";\n detectionCache.set(key, result);\n return result;\n }\n if (preferred === \"protonpass\") {\n const ok = await probeProtonPass(config);\n const result: PasswordManagerBackend = ok ? \"protonpass\" : \"none\";\n detectionCache.set(key, result);\n return result;\n }\n\n if (await probeOp(config)) {\n detectionCache.set(key, \"1password\");\n return \"1password\";\n }\n if (await probeProtonPass(config)) {\n detectionCache.set(key, \"protonpass\");\n return \"protonpass\";\n }\n detectionCache.set(key, \"none\");\n return \"none\";\n}\n\n/** Clear the backend detection cache. Exposed for tests. */\nexport function clearPasswordManagerBackendCache(): void {\n detectionCache.clear();\n}\n\n// ---------------------------------------------------------------------------\n// 1Password CLI backend\n// ---------------------------------------------------------------------------\n\ninterface OpItemListEntry {\n id?: string;\n title?: string;\n tags?: string[];\n urls?: Array<{ href?: string; primary?: boolean }>;\n additional_information?: string;\n category?: string;\n vault?: { id?: string; name?: string };\n}\n\nfunction opBaseArgs(config?: PasswordManagerBridgeConfig): string[] {\n const args: string[] = [];\n const account = config?.onePasswordAccount?.trim();\n if (account) args.push(\"--account\", account);\n return args;\n}\n\nasync function runOp(\n args: string[],\n config?: PasswordManagerBridgeConfig,\n): Promise<string> {\n const binary = resolveOpBinary(config);\n const fullArgs = [...opBaseArgs(config), ...args];\n try {\n const { stdout } = await execFileAsync(binary, fullArgs, {\n timeout: 15_000,\n maxBuffer: 16 * 1024 * 1024,\n });\n return stdout;\n } catch (error) {\n throw new PasswordManagerError(\n `1Password CLI failed for \"${args[0] ?? \"\"}\": ${\n error instanceof Error ? error.message : String(error)\n }`,\n \"1password\",\n error,\n );\n }\n}\n\nfunction normalizeOpListEntry(raw: OpItemListEntry): PasswordManagerItem {\n const id = raw.id ?? \"\";\n if (!id) {\n throw new PasswordManagerError(\"1Password item missing id\", \"1password\");\n }\n const primaryUrl =\n raw.urls?.find((u) => u.primary)?.href ?? raw.urls?.[0]?.href;\n return {\n id,\n title: raw.title ?? id,\n url: primaryUrl,\n username: raw.additional_information,\n hasPassword: (raw.category ?? \"\").toUpperCase() === \"LOGIN\",\n tags: raw.tags,\n metadata: {\n category: raw.category,\n vault: raw.vault?.name,\n },\n };\n}\n\nasync function listItemsVia1Password(\n config?: PasswordManagerBridgeConfig,\n): Promise<PasswordManagerItem[]> {\n const stdout = await runOp([\"item\", \"list\", \"--format\", \"json\"], config);\n const trimmed = stdout.trim();\n if (!trimmed) return [];\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch (error) {\n throw new PasswordManagerError(\n \"1Password returned invalid JSON from item list\",\n \"1password\",\n error,\n );\n }\n if (!Array.isArray(parsed)) {\n throw new PasswordManagerError(\n \"1Password item list was not an array\",\n \"1password\",\n );\n }\n return (parsed as OpItemListEntry[]).map(normalizeOpListEntry);\n}\n\nfunction matchesQuery(item: PasswordManagerItem, q: string): boolean {\n if (!q) return true;\n const needle = q.toLowerCase();\n if (item.title.toLowerCase().includes(needle)) return true;\n if (item.url?.toLowerCase().includes(needle)) return true;\n if (item.username?.toLowerCase().includes(needle)) return true;\n if (item.tags?.some((t) => t.toLowerCase().includes(needle))) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// ProtonPass / pass backend\n// ---------------------------------------------------------------------------\n//\n// Both `protonpass` and classic `pass` support listing entries by name.\n// Neither exposes rich metadata; we emit title-only items with the entry\n// path used as the id. Per the contract, we never include plaintext\n// secrets in returned objects.\n\nasync function listItemsViaProtonPass(\n config?: PasswordManagerBridgeConfig,\n): Promise<PasswordManagerItem[]> {\n const binary = resolveProtonPassBinary(config);\n let stdout: string;\n try {\n const result = await execFileAsync(binary, [\"list\"], {\n timeout: 10_000,\n maxBuffer: 8 * 1024 * 1024,\n });\n stdout = result.stdout;\n } catch (error) {\n // Try classic `pass` if protonpass failed and user didn't pin a binary.\n if (!config?.protonPassPath) {\n try {\n const result = await execFileAsync(\"pass\", [\"ls\"], {\n timeout: 10_000,\n maxBuffer: 8 * 1024 * 1024,\n });\n stdout = result.stdout;\n } catch (inner) {\n throw new PasswordManagerError(\n `ProtonPass/pass list failed: ${\n inner instanceof Error ? inner.message : String(inner)\n }`,\n \"protonpass\",\n inner,\n );\n }\n } else {\n throw new PasswordManagerError(\n `ProtonPass list failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n \"protonpass\",\n error,\n );\n }\n }\n\n const items: PasswordManagerItem[] = [];\n for (const rawLine of stdout.split(\"\\n\")) {\n // Strip tree characters from `pass ls` output (├── └── │ etc.).\n const line = rawLine\n .replace(/[│├└─]+/g, \"\")\n .replace(/\\u00a0/g, \" \")\n .trim();\n if (!line) continue;\n if (line.toLowerCase().startsWith(\"password store\")) continue;\n items.push({\n id: line,\n title: line,\n hasPassword: true,\n });\n }\n return items;\n}\n\n// ---------------------------------------------------------------------------\n// Clipboard injection\n// ---------------------------------------------------------------------------\n\nfunction clipboardCommand(): { cmd: string; args: string[] } {\n switch (process.platform) {\n case \"darwin\":\n return { cmd: \"pbcopy\", args: [] };\n case \"win32\":\n return { cmd: \"clip\", args: [] };\n default:\n // Linux/BSD — prefer xclip, but the command must be present on PATH.\n return { cmd: \"xclip\", args: [\"-selection\", \"clipboard\"] };\n }\n}\n\n/**\n * Pipe stdout of a producer subprocess directly into the clipboard command.\n *\n * The plaintext secret passes through this process's memory only as kernel\n * pipe buffers between the two children — it is never buffered as a JS\n * string, never logged, and never returned.\n */\nasync function pipeToClipboard(\n producer: { cmd: string; args: string[] },\n backend: PasswordManagerBackend,\n): Promise<void> {\n const clip = clipboardCommand();\n\n await new Promise<void>((resolve, reject) => {\n const source = spawn(producer.cmd, producer.args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const sink = spawn(clip.cmd, clip.args, {\n stdio: [\"pipe\", \"ignore\", \"pipe\"],\n });\n\n let settled = false;\n const settle = (err?: Error) => {\n if (settled) return;\n settled = true;\n if (err) {\n source.kill();\n sink.kill();\n reject(err);\n } else {\n resolve();\n }\n };\n\n source.on(\"error\", (err) =>\n settle(\n new PasswordManagerError(\n `Failed to run ${producer.cmd}: ${err.message}`,\n backend,\n err,\n ),\n ),\n );\n sink.on(\"error\", (err) =>\n settle(\n new PasswordManagerError(\n `Failed to run clipboard command ${clip.cmd}: ${err.message}`,\n backend,\n err,\n ),\n ),\n );\n\n source.stdout.pipe(sink.stdin);\n\n let sourceExit: number | null = null;\n let sinkExit: number | null = null;\n const maybeDone = () => {\n if (sourceExit === null || sinkExit === null) return;\n if (sourceExit !== 0) {\n settle(\n new PasswordManagerError(\n `${producer.cmd} exited with code ${sourceExit}`,\n backend,\n ),\n );\n return;\n }\n if (sinkExit !== 0) {\n settle(\n new PasswordManagerError(\n `${clip.cmd} exited with code ${sinkExit}`,\n backend,\n ),\n );\n return;\n }\n settle();\n };\n source.on(\"close\", (code) => {\n sourceExit = code ?? 0;\n maybeDone();\n });\n sink.on(\"close\", (code) => {\n sinkExit = code ?? 0;\n maybeDone();\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Public dispatch\n// ---------------------------------------------------------------------------\n\nasync function resolveActiveBackend(\n config?: PasswordManagerBridgeConfig,\n): Promise<PasswordManagerBackend> {\n const backend = await detectPasswordManagerBackend(config);\n if (backend === \"none\") {\n throw new PasswordManagerError(\n \"No password manager backend available (install 1Password CLI `op` or ProtonPass/`pass`)\",\n \"none\",\n );\n }\n return backend;\n}\n\nexport async function searchPasswordItems(\n query: string,\n config?: PasswordManagerBridgeConfig,\n): Promise<PasswordManagerItem[]> {\n const backend = await resolveActiveBackend(config);\n const items =\n backend === \"fixture\"\n ? listItemsViaFixture()\n : backend === \"1password\"\n ? await listItemsVia1Password(config)\n : await listItemsViaProtonPass(config);\n return items.filter((item) => matchesQuery(item, query));\n}\n\nexport async function listPasswordItems(\n opts: { limit?: number },\n config?: PasswordManagerBridgeConfig,\n): Promise<PasswordManagerItem[]> {\n const backend = await resolveActiveBackend(config);\n const items =\n backend === \"fixture\"\n ? listItemsViaFixture()\n : backend === \"1password\"\n ? await listItemsVia1Password(config)\n : await listItemsViaProtonPass(config);\n const limit = opts.limit;\n if (typeof limit === \"number\" && limit >= 0) {\n return items.slice(0, limit);\n }\n return items;\n}\n\nexport async function injectCredentialToClipboard(\n itemId: string,\n field: \"username\" | \"password\",\n config?: PasswordManagerBridgeConfig,\n): Promise<{ ok: true; expiresInSeconds: number; fixtureMode?: boolean }> {\n if (!itemId || typeof itemId !== \"string\") {\n throw new PasswordManagerError(\n \"itemId is required\",\n config?.preferredBackend ?? \"none\",\n );\n }\n const backend = await resolveActiveBackend(config);\n\n if (backend === \"fixture\") {\n logger.warn(\n {\n itemId,\n field,\n boundary: \"browser\",\n component: \"password-manager-bridge\",\n },\n \"[password-manager-bridge] fixture backend active: no clipboard write performed. Set ELIZA_TEST_PASSWORD_MANAGER_BACKEND=0 for real injection.\",\n );\n return {\n ok: true,\n expiresInSeconds: CLIPBOARD_TTL_SECONDS,\n fixtureMode: true,\n };\n }\n\n if (backend === \"1password\") {\n const binary = resolveOpBinary(config);\n const args = [\n ...opBaseArgs(config),\n \"item\",\n \"get\",\n itemId,\n \"--fields\",\n field === \"password\" ? \"password\" : \"username\",\n \"--reveal\",\n ];\n await pipeToClipboard({ cmd: binary, args }, \"1password\");\n return { ok: true, expiresInSeconds: CLIPBOARD_TTL_SECONDS };\n }\n\n // protonpass / pass\n const binary = resolveProtonPassBinary(config);\n // Both `protonpass show <id>` and `pass show <id>` print the secret on the\n // first line. Username retrieval is not uniformly supported in classic\n // pass; callers must store username in the entry body to retrieve it.\n if (field === \"username\") {\n throw new PasswordManagerError(\n \"Username injection is not supported by the ProtonPass/pass backend\",\n \"protonpass\",\n );\n }\n let producerCmd = binary;\n const producerArgs = [\"show\", itemId];\n // Fallback to classic `pass` when protonpass isn't pinned and missing.\n if (!config?.protonPassPath) {\n const hasProton = await probeBinary(binary, [\"--version\"]);\n if (!hasProton) producerCmd = \"pass\";\n }\n await pipeToClipboard({ cmd: producerCmd, args: producerArgs }, \"protonpass\");\n return { ok: true, expiresInSeconds: CLIPBOARD_TTL_SECONDS };\n}\n"],"mappings":"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","names":["binary"]}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @elizaos/plugin-browser plugin export.
|
|
3
|
+
*
|
|
4
|
+
* plugin-collector discovers `routes` and `schema` at runtime. Eliza loads
|
|
5
|
+
* this as a core plugin so the Browser Workspace UI and browser companion
|
|
6
|
+
* extension share one route surface.
|
|
7
|
+
*/
|
|
8
|
+
import type { Plugin } from "@elizaos/core";
|
|
9
|
+
export declare const browserPlugin: Plugin;
|
|
10
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAGV,MAAM,EAIP,MAAM,eAAe,CAAC;AAgLvB,eAAO,MAAM,aAAa,EAAE,MA6B3B,CAAC"}
|