enclave-link 0.2.3 → 0.2.4
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/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</picture>
|
|
6
6
|
</h1>
|
|
7
7
|
|
|
8
|
-
Your AI agent needs your Netflix password. Instead of asking in chat, it sends you a link. You
|
|
8
|
+
Your AI agent needs your Netflix password. Instead of asking in chat, it sends you a link. You type the password (or your password manager fills it) and tap **Send**. It's locked in your browser before it leaves, so only your agent can open it. The agent keeps it in a vault of its own, next to 2FA codes and passkeys, and uses it later without seeing it.
|
|
9
9
|
|
|
10
10
|
<p>
|
|
11
11
|
<picture>
|
|
@@ -34,7 +34,7 @@ It works out of the box with a hosted relay. No accounts, no keys to set up, not
|
|
|
34
34
|
npx skills add AVGVSTVS96/enclave
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
It runs enclave with `npx`, so there's nothing else to install.
|
|
38
38
|
|
|
39
39
|
**Agents that use MCP** get the same thing as tools. Add the server below, and add this line to the agent's instructions, because tools alone don't stop a model from asking in chat:
|
|
40
40
|
|
|
@@ -63,7 +63,7 @@ claude mcp add enclave -- npx -y enclave-link mcp
|
|
|
63
63
|
codex mcp add enclave -- npx -y enclave-link mcp
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
Codex stops a tool after 60 seconds by default
|
|
66
|
+
Codex stops a tool after 60 seconds by default, and `wait_for_secret` can wait 25 minutes, so add this under `[mcp_servers.enclave]` in `~/.codex/config.toml`:
|
|
67
67
|
|
|
68
68
|
```toml
|
|
69
69
|
tool_timeout_sec = 1800
|
|
@@ -188,7 +188,7 @@ Run `goose configure`, choose **Add Extension → Command-line Extension**, ente
|
|
|
188
188
|
|
|
189
189
|
</details>
|
|
190
190
|
|
|
191
|
-
**ChatGPT, Claude.ai and the Gemini and Grok apps** can't use enclave yet
|
|
191
|
+
**ChatGPT, Claude.ai and the Gemini and Grok apps** can't use enclave yet: they run in the cloud, and the vault lives on the computer where the agent runs. Their desktop and coding-agent versions above work.
|
|
192
192
|
|
|
193
193
|
**Your own code** can use the TypeScript SDK; see [SDK](#sdk).
|
|
194
194
|
|
|
@@ -232,11 +232,9 @@ A field named `passkey` holds a passkey, and the agent signs in with it in Chrom
|
|
|
232
232
|
enclave passkey GitHub # then click the site's passkey sign-in
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
-
`enclave passkey` arms the passkey for one sign-in, for up to 5 minutes. When the site asks for a passkey, enclave's Chrome extension hands the request to `enclave sign`, which signs it inside the vault and disarms the passkey. The private key never
|
|
235
|
+
`enclave passkey` arms the passkey for one sign-in, for up to 5 minutes. When the site asks for a passkey, enclave's Chrome extension hands the request to `enclave sign`, which signs it inside the vault and disarms the passkey. The private key never leaves the vault: `enclave get` and `enclave run` refuse passkey fields.
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
A passkey's private key never comes out: `enclave get` and `enclave run` refuse passkey fields, and only `enclave sign` uses them.
|
|
237
|
+
A passkey keeps working in Proton Pass and enclave side by side.
|
|
240
238
|
|
|
241
239
|
Install the extension once per machine, from a clone of this repo, with Google Chrome on Linux. It's force-installed through Chrome's policy, so it loads in every profile:
|
|
242
240
|
|
|
@@ -252,9 +250,9 @@ enclave import proton # every vault
|
|
|
252
250
|
enclave import proton Work # or just the ones you name
|
|
253
251
|
```
|
|
254
252
|
|
|
255
|
-
copies [Proton Pass](https://proton.me/pass) in through [pass-cli](https://github.com/protonpass/pass-cli): logins, 2FA, passkeys, notes, cards, SSH keys and custom fields, one item per Proton item, named by its title
|
|
253
|
+
copies [Proton Pass](https://proton.me/pass) in through [pass-cli](https://github.com/protonpass/pass-cli): logins, 2FA, passkeys, notes, cards, SSH keys and custom fields, one item per Proton item, named by its title. Proton keeps everything. Run it again to bring in what changed: names stay the same, renames follow, items deleted in Proton leave enclave too, and anything you saved yourself is kept.
|
|
256
254
|
|
|
257
|
-
2FA comes in as a `totp` field, so `enclave get <name> totp` gives the current code
|
|
255
|
+
2FA comes in as a `totp` field, so `enclave get <name> totp` gives the current code, and passkeys as a `passkey` field.
|
|
258
256
|
|
|
259
257
|
## CLI
|
|
260
258
|
|
|
@@ -329,7 +327,7 @@ The vault keeps each item encrypted in `~/.enclave/items`, sealed to the vault's
|
|
|
329
327
|
|
|
330
328
|
What enclave can't protect against:
|
|
331
329
|
|
|
332
|
-
- **Whoever runs the relay sends you the page.** Your browser downloads the page, including the code that locks your password, from the relay each time you open a link. What the relay stores can't be read, but if someone took over the relay's Convex account, they could change the page to copy what you type before locking it.
|
|
330
|
+
- **Whoever runs the relay sends you the page.** Your browser downloads the page, including the code that locks your password, from the relay each time you open a link. What the relay stores can't be read, but if someone took over the relay's Convex account, they could change the page to copy what you type before locking it. The page's script is 128 lines in [`page/page.ts`](page/page.ts) plus the encryption in [`src/hpke.ts`](src/hpke.ts), served as one file with a strict Content Security Policy, so you can read exactly what it runs. If you'd rather trust nobody's relay, [host your own](#host-your-own).
|
|
333
331
|
- **Anyone with the link can answer it first.** They still can't read anything, but they could send a fake answer. If that happens, the page says "This link doesn't work anymore" when you open it.
|
|
334
332
|
- **Phishing.** A link can say anyone is asking. Only send secrets to agents you asked for help.
|
|
335
333
|
- **An agent that wants to see a secret can.** enclave keeps secrets out of the chat and out of tool results, and `run` hides their exact values in output. But an agent with a shell on the same computer could still read its own vault. enclave stops secrets from leaking by accident, not a model that's trying.
|
|
@@ -28,7 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
mod
|
|
29
29
|
));
|
|
30
30
|
|
|
31
|
-
// node_modules/zod/v4/core/util.js
|
|
31
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/util.js
|
|
32
32
|
var util_exports = {};
|
|
33
33
|
__export(util_exports, {
|
|
34
34
|
BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
|
|
@@ -871,7 +871,7 @@ function constantCatch(value) {
|
|
|
871
871
|
return fn;
|
|
872
872
|
}
|
|
873
873
|
|
|
874
|
-
// node_modules/zod/v4/core/core.js
|
|
874
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/core.js
|
|
875
875
|
var _a;
|
|
876
876
|
var _zodDesc = { value: void 0, enumerable: false };
|
|
877
877
|
var _E = "captureStackTrace" in Error ? Error : null;
|
|
@@ -989,7 +989,7 @@ function config(newConfig) {
|
|
|
989
989
|
return globalConfig;
|
|
990
990
|
}
|
|
991
991
|
|
|
992
|
-
// node_modules/zod/v4/core/errors.js
|
|
992
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/errors.js
|
|
993
993
|
function _getMessage() {
|
|
994
994
|
const internals = this._zod;
|
|
995
995
|
internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2));
|
|
@@ -1104,7 +1104,7 @@ function formatError(error2, mapper = (issue2) => issue2.message) {
|
|
|
1104
1104
|
return fieldErrors;
|
|
1105
1105
|
}
|
|
1106
1106
|
|
|
1107
|
-
// node_modules/zod/v4/core/parse.js
|
|
1107
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/parse.js
|
|
1108
1108
|
function finalizeParams(callee, params) {
|
|
1109
1109
|
return { callee: params?.callee ?? callee, Err: params?.Err };
|
|
1110
1110
|
}
|
|
@@ -1256,7 +1256,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
|
|
|
1256
1256
|
return _safeParseAsync(_Err)(schema, value, _ctx);
|
|
1257
1257
|
};
|
|
1258
1258
|
|
|
1259
|
-
// node_modules/zod/v4/core/regexes.js
|
|
1259
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/regexes.js
|
|
1260
1260
|
var cuid = /^[cC][0-9a-z]{6,}$/;
|
|
1261
1261
|
var cuid2 = /^[0-9a-z]+$/;
|
|
1262
1262
|
var ulid = /^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/;
|
|
@@ -1315,7 +1315,7 @@ var _null = /^null$/i;
|
|
|
1315
1315
|
var lowercase = /^[^A-Z]*$/;
|
|
1316
1316
|
var uppercase = /^[^a-z]*$/;
|
|
1317
1317
|
|
|
1318
|
-
// node_modules/zod/v4/core/checks.js
|
|
1318
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/checks.js
|
|
1319
1319
|
var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
|
|
1320
1320
|
var _a3;
|
|
1321
1321
|
inst._zod ?? (inst._zod = {});
|
|
@@ -1635,7 +1635,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
|
|
|
1635
1635
|
};
|
|
1636
1636
|
});
|
|
1637
1637
|
|
|
1638
|
-
// node_modules/zod/v4/core/doc.js
|
|
1638
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/doc.js
|
|
1639
1639
|
var Doc = class {
|
|
1640
1640
|
constructor(args = [], closed = {}) {
|
|
1641
1641
|
this.content = [];
|
|
@@ -1676,14 +1676,14 @@ ${content.join("\n")}
|
|
|
1676
1676
|
}
|
|
1677
1677
|
};
|
|
1678
1678
|
|
|
1679
|
-
// node_modules/zod/v4/core/versions.js
|
|
1679
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/versions.js
|
|
1680
1680
|
var version = {
|
|
1681
1681
|
major: 4,
|
|
1682
1682
|
minor: 6,
|
|
1683
1683
|
patch: 5
|
|
1684
1684
|
};
|
|
1685
1685
|
|
|
1686
|
-
// node_modules/zod/v4/core/schemas.js
|
|
1686
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/schemas.js
|
|
1687
1687
|
var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
1688
1688
|
var _a3;
|
|
1689
1689
|
inst ?? (inst = {});
|
|
@@ -3449,7 +3449,7 @@ function handleRefineResult(result, payload, input, inst) {
|
|
|
3449
3449
|
}
|
|
3450
3450
|
}
|
|
3451
3451
|
|
|
3452
|
-
// node_modules/zod/v4/core/memoizer.js
|
|
3452
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/memoizer.js
|
|
3453
3453
|
var $ZodCyclicError = class extends Error {
|
|
3454
3454
|
constructor() {
|
|
3455
3455
|
super(`Cannot parse a reference cycle that closes through a transform`);
|
|
@@ -3723,7 +3723,7 @@ function isBackEdge(ctx, value) {
|
|
|
3723
3723
|
return backEdges !== void 0 && isRef(value) && backEdges.has(value);
|
|
3724
3724
|
}
|
|
3725
3725
|
|
|
3726
|
-
// node_modules/zod/v4/locales/en.js
|
|
3726
|
+
// ../../../Developer/enclave/node_modules/zod/v4/locales/en.js
|
|
3727
3727
|
var error = () => {
|
|
3728
3728
|
const Sizable = {
|
|
3729
3729
|
string: { unit: "characters", verb: "to have" },
|
|
@@ -3848,7 +3848,7 @@ function en_default() {
|
|
|
3848
3848
|
};
|
|
3849
3849
|
}
|
|
3850
3850
|
|
|
3851
|
-
// node_modules/zod/v4/core/registries.js
|
|
3851
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/registries.js
|
|
3852
3852
|
var _a2;
|
|
3853
3853
|
var $ZodRegistry = class {
|
|
3854
3854
|
constructor() {
|
|
@@ -3896,7 +3896,7 @@ function registry() {
|
|
|
3896
3896
|
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
|
|
3897
3897
|
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
3898
3898
|
|
|
3899
|
-
// node_modules/zod/v4/core/api.js
|
|
3899
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/api.js
|
|
3900
3900
|
function snapshotChecks(def) {
|
|
3901
3901
|
if (def.checks)
|
|
3902
3902
|
def.checks = [...def.checks];
|
|
@@ -4423,7 +4423,7 @@ function _check(fn, params) {
|
|
|
4423
4423
|
return ch;
|
|
4424
4424
|
}
|
|
4425
4425
|
|
|
4426
|
-
// node_modules/zod/v4/core/to-json-schema.js
|
|
4426
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/to-json-schema.js
|
|
4427
4427
|
function assignProps(target, ...sources) {
|
|
4428
4428
|
for (const source of sources) {
|
|
4429
4429
|
for (const key of Reflect.ownKeys(source)) {
|
|
@@ -4953,7 +4953,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
|
|
|
4953
4953
|
return finalize(ctx, schema);
|
|
4954
4954
|
};
|
|
4955
4955
|
|
|
4956
|
-
// node_modules/zod/v4/core/json-schema-processors.js
|
|
4956
|
+
// ../../../Developer/enclave/node_modules/zod/v4/core/json-schema-processors.js
|
|
4957
4957
|
var narrowMin = (agg, key, value) => {
|
|
4958
4958
|
if (agg[key] === void 0 || value > agg[key])
|
|
4959
4959
|
agg[key] = value;
|
|
@@ -5701,7 +5701,7 @@ function toJSONSchema(input, params) {
|
|
|
5701
5701
|
return finalize(ctx, input);
|
|
5702
5702
|
}
|
|
5703
5703
|
|
|
5704
|
-
// node_modules/zod/v4/classic/errors.js
|
|
5704
|
+
// ../../../Developer/enclave/node_modules/zod/v4/classic/errors.js
|
|
5705
5705
|
var _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
|
|
5706
5706
|
function _lazyMethod(proto, key, make) {
|
|
5707
5707
|
Object.defineProperty(proto, key, {
|
|
@@ -5746,7 +5746,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, void 0
|
|
|
5746
5746
|
Parent: Error
|
|
5747
5747
|
});
|
|
5748
5748
|
|
|
5749
|
-
// node_modules/zod/v4/classic/parse.js
|
|
5749
|
+
// ../../../Developer/enclave/node_modules/zod/v4/classic/parse.js
|
|
5750
5750
|
var parse2 = /* @__PURE__ */ _parse(ZodRealError);
|
|
5751
5751
|
var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
5752
5752
|
var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
@@ -5760,7 +5760,7 @@ var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
|
|
|
5760
5760
|
var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
|
|
5761
5761
|
var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
|
|
5762
5762
|
|
|
5763
|
-
// node_modules/zod/v4/classic/schemas.js
|
|
5763
|
+
// ../../../Developer/enclave/node_modules/zod/v4/classic/schemas.js
|
|
5764
5764
|
function _ensureDefaultLocale() {
|
|
5765
5765
|
if (!globalConfig.localeError)
|
|
5766
5766
|
config(en_default());
|