@techsologic/unolock-agent 0.1.32 → 0.1.34
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
|
@@ -14,7 +14,6 @@ For skill-aware agents, the primary starting point is the UnoLock agent-access s
|
|
|
14
14
|
* `https://github.com/TechSologic/unolock-agent/blob/main/skills/unolock-agent-access/SKILL.md`
|
|
15
15
|
|
|
16
16
|
That skill is the agent-facing onboarding layer.
|
|
17
|
-
The local UnoLock `stdio` MCP is the implementation layer underneath it.
|
|
18
17
|
|
|
19
18
|
For OpenClaw, this package can also be installed as a plugin so OpenClaw can load the same skill natively.
|
|
20
19
|
|
|
@@ -49,7 +48,7 @@ For normal customer use, the strongest deployment uses a production-ready:
|
|
|
49
48
|
* Secure Enclave
|
|
50
49
|
* or equivalent platform-backed non-exportable key store
|
|
51
50
|
|
|
52
|
-
If the host cannot provide one of those,
|
|
51
|
+
If the host cannot provide one of those, UnoLock Agent can still fall back to a lower-assurance software provider. When that happens, UnoLock reports the reduced assurance clearly and makes the reduced-assurance tradeoff visible instead of pretending it met UnoLock's preferred key-storage requirements.
|
|
53
52
|
|
|
54
53
|
That tradeoff is intentional. Agentic Safe Access exists to keep AI access as close as possible to UnoLock's normal device-bound security model without pretending every host can satisfy the same storage guarantees.
|
|
55
54
|
|
|
@@ -60,7 +59,7 @@ UnoLock Agent is designed to work across a wide range of agent environments.
|
|
|
60
59
|
The strongest deployments are environments that can provide device-bound, non-exportable key storage in a normal user-controlled session. That includes:
|
|
61
60
|
|
|
62
61
|
* desktop AI assistants
|
|
63
|
-
* local
|
|
62
|
+
* local AI hosts such as Claude Desktop or Cursor
|
|
64
63
|
* user-controlled workstations, laptops, and VMs with TPM/vTPM access
|
|
65
64
|
* macOS hosts that can use either Secure Enclave or a non-exportable Keychain-backed key
|
|
66
65
|
* Windows or WSL hosts that can use either TPM-backed keys or the non-exportable Windows CNG fallback
|
|
@@ -104,7 +103,7 @@ Prerequisite:
|
|
|
104
103
|
* Free and Inheritance can share their single included Safe space with one extra Agent Key.
|
|
105
104
|
* Sovereign and HighRisk are still the right tiers for broader multi-Space and collaboration-heavy agent workflows.
|
|
106
105
|
|
|
107
|
-
The current
|
|
106
|
+
The current agent runtime proves the hardest integration seam first:
|
|
108
107
|
|
|
109
108
|
* live local `/start` flow compatibility
|
|
110
109
|
* ML-DSA signature verification
|
|
@@ -117,8 +116,8 @@ Safe creation remains a human/browser responsibility, matching the product model
|
|
|
117
116
|
|
|
118
117
|
* human admin creates a Safe
|
|
119
118
|
* human admin creates an agent access key for that Safe
|
|
120
|
-
*
|
|
121
|
-
*
|
|
119
|
+
* UnoLock Agent registers to the existing Safe
|
|
120
|
+
* UnoLock Agent later authenticates and uses the shared Safe API surface for agent memory, notes, checklists, and secrets
|
|
122
121
|
|
|
123
122
|
## Quick start
|
|
124
123
|
|
|
@@ -131,7 +130,7 @@ Run this from the repo root after the local server is up on `http://127.0.0.1:30
|
|
|
131
130
|
./scripts/run_local_e2e_readonly.sh
|
|
132
131
|
```
|
|
133
132
|
|
|
134
|
-
For
|
|
133
|
+
For host configuration and implementation details, see:
|
|
135
134
|
|
|
136
135
|
* [Install Guide](docs/install.md)
|
|
137
136
|
* [macOS Quick Start](docs/macos.md)
|
|
@@ -154,14 +153,14 @@ npx -y @techsologic/unolock-agent@latest list-notes
|
|
|
154
153
|
npx -y @techsologic/unolock-agent@latest list-files
|
|
155
154
|
```
|
|
156
155
|
|
|
157
|
-
|
|
156
|
+
Only if a host needs the explicit host-command form, use the same executable with:
|
|
158
157
|
|
|
159
|
-
*
|
|
158
|
+
* Hosts that require this command shape launch `npx -y @techsologic/unolock-agent@latest mcp`.
|
|
160
159
|
* The host writes JSON-RPC to `stdin` and reads JSON-RPC from `stdout`.
|
|
161
|
-
* The `mcp` subcommand uses the local UnoLock
|
|
160
|
+
* The `mcp` subcommand starts and uses the local UnoLock runtime automatically.
|
|
162
161
|
* On a fresh host, the first start can take longer because local cryptographic code may need to be compiled or prepared.
|
|
163
162
|
|
|
164
|
-
That keeps the user PIN in process memory
|
|
163
|
+
That keeps the user PIN in process memory and keeps the current Space selected.
|
|
165
164
|
|
|
166
165
|
The same executable also supports explicit CLI commands, for example:
|
|
167
166
|
|
|
@@ -173,13 +172,13 @@ unolock-agent create-note "Todo" "Buy milk"
|
|
|
173
172
|
unolock-agent list-files
|
|
174
173
|
```
|
|
175
174
|
|
|
176
|
-
Use the explicit `mcp` subcommand for
|
|
175
|
+
Use the explicit `mcp` subcommand only for hosts that require that command shape. Running `unolock-agent` with no arguments prints usage.
|
|
177
176
|
|
|
178
|
-
Once the local
|
|
177
|
+
Once the local UnoLock Agent is running, the normal flow is:
|
|
179
178
|
|
|
180
179
|
* call normal UnoLock tools
|
|
181
|
-
* provide the one-time Agent Key URL and PIN together when
|
|
182
|
-
* let
|
|
180
|
+
* provide the one-time Agent Key URL and PIN together when UnoLock asks for setup
|
|
181
|
+
* let UnoLock keep and use the current Space by default for normal work
|
|
183
182
|
|
|
184
183
|
If you prefer manual install from source:
|
|
185
184
|
|
|
@@ -197,9 +196,9 @@ python3 -m unolock_mcp config-check
|
|
|
197
196
|
```
|
|
198
197
|
|
|
199
198
|
For normal customer and agent onboarding, do not drive the CLI `bootstrap` command directly.
|
|
200
|
-
Let
|
|
199
|
+
Let UnoLock guide the normal flow.
|
|
201
200
|
|
|
202
|
-
macOS support is still alpha.
|
|
201
|
+
macOS support is still alpha. UnoLock Agent now prefers Secure Enclave when it works cleanly and otherwise falls back to a non-exportable macOS Keychain key for broader compatibility. If you are evaluating it on Apple Silicon, start with:
|
|
203
202
|
|
|
204
203
|
* [macOS Quick Start](docs/macos.md)
|
|
205
204
|
|
|
@@ -231,7 +230,7 @@ On restart, the npm wrapper now checks GitHub Releases for a newer stable binary
|
|
|
231
230
|
|
|
232
231
|
The npm package is both:
|
|
233
232
|
|
|
234
|
-
* the normal
|
|
233
|
+
* the normal UnoLock executable package
|
|
235
234
|
* an OpenClaw plugin package that ships the UnoLock skill
|
|
236
235
|
|
|
237
236
|
Project home:
|
|
@@ -244,7 +243,7 @@ Use it as a command that OpenClaw can launch, for example:
|
|
|
244
243
|
npx -y @techsologic/unolock-agent@latest mcp
|
|
245
244
|
```
|
|
246
245
|
|
|
247
|
-
For
|
|
246
|
+
For hosts that require the command form, use the explicit `mcp` argument:
|
|
248
247
|
|
|
249
248
|
```bash
|
|
250
249
|
npx -y @techsologic/unolock-agent@latest mcp
|
package/bin/unolock-agent.js
CHANGED
|
@@ -7,9 +7,48 @@ const path = require("path");
|
|
|
7
7
|
const https = require("https");
|
|
8
8
|
const { spawn } = require("child_process");
|
|
9
9
|
|
|
10
|
-
const PACKAGE_VERSION = "0.1.
|
|
11
|
-
const FALLBACK_BINARY_VERSION = "0.1.
|
|
10
|
+
const PACKAGE_VERSION = "0.1.34";
|
|
11
|
+
const FALLBACK_BINARY_VERSION = "0.1.34";
|
|
12
12
|
const REPO = "TechSologic/unolock-agent";
|
|
13
|
+
const TOP_LEVEL_USAGE = `usage: unolock-agent [-h] [--version] {link-agent-key,set-agent-pin,list-spaces,get-current-space,set-current-space,list-records,list-notes,list-checklists,get-record,create-note,update-note,append-note,rename-record,create-checklist,set-checklist-item-done,add-checklist-item,remove-checklist-item,list-files,get-file,download-file,upload-file,rename-file,replace-file,delete-file,tpm-diagnose,tpm-check,self-test,mcp} ...
|
|
14
|
+
|
|
15
|
+
UnoLock Agent commands.
|
|
16
|
+
|
|
17
|
+
positional arguments:
|
|
18
|
+
link-agent-key Link a one-time UnoLock Agent Key URL and PIN to this device.
|
|
19
|
+
set-agent-pin Set the in-memory UnoLock agent PIN.
|
|
20
|
+
list-spaces List accessible UnoLock spaces.
|
|
21
|
+
get-current-space Show the current UnoLock space.
|
|
22
|
+
set-current-space Set the current UnoLock space.
|
|
23
|
+
list-records List notes and checklists in the current space.
|
|
24
|
+
list-notes List notes in the current space.
|
|
25
|
+
list-checklists List checklists in the current space.
|
|
26
|
+
get-record Get one note or checklist by record_ref.
|
|
27
|
+
create-note Create a note in the current space.
|
|
28
|
+
update-note Update an existing note.
|
|
29
|
+
append-note Append text to an existing note.
|
|
30
|
+
rename-record Rename a note or checklist.
|
|
31
|
+
create-checklist Create a checklist in the current space.
|
|
32
|
+
set-checklist-item-done
|
|
33
|
+
Set one checklist item's done state.
|
|
34
|
+
add-checklist-item Add an item to a checklist.
|
|
35
|
+
remove-checklist-item Remove an item from a checklist.
|
|
36
|
+
list-files List Cloud files in the current space.
|
|
37
|
+
get-file Get metadata for one Cloud file.
|
|
38
|
+
download-file Download a Cloud file to the local filesystem.
|
|
39
|
+
upload-file Upload a local file into the current space.
|
|
40
|
+
rename-file Rename a Cloud file.
|
|
41
|
+
replace-file Replace a Cloud file with local content.
|
|
42
|
+
delete-file Delete a Cloud file.
|
|
43
|
+
tpm-diagnose Diagnose TPM/vTPM readiness for the UnoLock agent MCP.
|
|
44
|
+
tpm-check Fail-fast check for production-ready TPM/vTPM/platform-backed key access.
|
|
45
|
+
self-test Run a one-shot UnoLock Agent readiness check.
|
|
46
|
+
mcp Run the UnoLock stdio MCP server.
|
|
47
|
+
|
|
48
|
+
options:
|
|
49
|
+
-h, --help show this help message and exit
|
|
50
|
+
--version show program's version number and exit
|
|
51
|
+
`;
|
|
13
52
|
|
|
14
53
|
function platformAssetInfo() {
|
|
15
54
|
const platform = process.platform;
|
|
@@ -173,12 +212,26 @@ function writeReleaseMetadata(releaseVersion) {
|
|
|
173
212
|
);
|
|
174
213
|
}
|
|
175
214
|
|
|
176
|
-
|
|
215
|
+
function cachedReleaseVersion() {
|
|
177
216
|
const override = normalizeVersion(process.env.UNOLOCK_AGENT_BINARY_VERSION);
|
|
178
217
|
if (override) {
|
|
179
218
|
return override;
|
|
180
219
|
}
|
|
181
220
|
const metadata = readReleaseMetadata();
|
|
221
|
+
if (metadata && typeof metadata.releaseVersion === "string" && fs.existsSync(binaryPath(metadata.releaseVersion))) {
|
|
222
|
+
return metadata.releaseVersion;
|
|
223
|
+
}
|
|
224
|
+
if (fs.existsSync(binaryPath(FALLBACK_BINARY_VERSION))) {
|
|
225
|
+
return FALLBACK_BINARY_VERSION;
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async function resolveReleaseVersion() {
|
|
231
|
+
const cached = cachedReleaseVersion();
|
|
232
|
+
if (cached) {
|
|
233
|
+
return cached;
|
|
234
|
+
}
|
|
182
235
|
try {
|
|
183
236
|
const payload = await fetchJson(`https://api.github.com/repos/${REPO}/releases/latest`);
|
|
184
237
|
const latest = normalizeVersion(payload && payload.tag_name);
|
|
@@ -187,9 +240,6 @@ async function resolveReleaseVersion() {
|
|
|
187
240
|
return latest;
|
|
188
241
|
}
|
|
189
242
|
} catch (error) {
|
|
190
|
-
if (metadata && typeof metadata.releaseVersion === "string" && fs.existsSync(binaryPath(metadata.releaseVersion))) {
|
|
191
|
-
return metadata.releaseVersion;
|
|
192
|
-
}
|
|
193
243
|
process.stderr.write(`Warning: ${error.message}. Falling back to bundled release ${FALLBACK_BINARY_VERSION}.\n`);
|
|
194
244
|
}
|
|
195
245
|
writeReleaseMetadata(FALLBACK_BINARY_VERSION);
|
|
@@ -209,8 +259,16 @@ async function ensureBinary() {
|
|
|
209
259
|
}
|
|
210
260
|
|
|
211
261
|
async function main() {
|
|
212
|
-
const { dest, releaseVersion } = await ensureBinary();
|
|
213
262
|
const forwardedArgs = process.argv.length > 2 ? process.argv.slice(2) : [];
|
|
263
|
+
if (forwardedArgs.length === 0 || forwardedArgs[0] === "-h" || forwardedArgs[0] === "--help") {
|
|
264
|
+
process.stdout.write(TOP_LEVEL_USAGE);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (forwardedArgs[0] === "--version") {
|
|
268
|
+
process.stdout.write(`${PACKAGE_VERSION}\n`);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const { dest, releaseVersion } = await ensureBinary();
|
|
214
272
|
const child = spawn(dest, forwardedArgs, {
|
|
215
273
|
stdio: "inherit",
|
|
216
274
|
env: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "unolock-agent-access",
|
|
3
3
|
"name": "UnoLock Agent Access",
|
|
4
|
-
"description": "Ships the UnoLock agent-access skill for OpenClaw.
|
|
4
|
+
"description": "Ships the UnoLock agent-access skill for OpenClaw.",
|
|
5
5
|
"configSchema": {
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
@@ -6,7 +6,7 @@ description: Guides an AI agent through connecting to a user's UnoLock Safe with
|
|
|
6
6
|
# UnoLock Agent Access
|
|
7
7
|
|
|
8
8
|
Use this skill when a user wants to give their agent access to a UnoLock Safe.
|
|
9
|
-
This skill uses the local `unolock-agent` executable on the user's device.
|
|
9
|
+
This skill uses the local `unolock-agent` executable on the user's device.
|
|
10
10
|
|
|
11
11
|
## Preferred Workflow
|
|
12
12
|
|
|
@@ -30,20 +30,12 @@ This skill uses the local `unolock-agent` executable on the user's device. The C
|
|
|
30
30
|
- `unolock-agent list-files`, `unolock-agent get-file <archive_id>`, `unolock-agent download-file ...`, `unolock-agent upload-file ...`, `unolock-agent rename-file ...`, `unolock-agent replace-file ...`, `unolock-agent delete-file ...`: read and manage Cloud files
|
|
31
31
|
- `unolock-agent get-record <record_ref>` and `unolock-agent rename-record ...`: inspect or rename an existing note or checklist
|
|
32
32
|
|
|
33
|
-
## MCP Fallback
|
|
34
|
-
|
|
35
|
-
If the host specifically requires MCP instead of CLI:
|
|
36
|
-
|
|
37
|
-
- run `npx -y @techsologic/unolock-agent@latest mcp`
|
|
38
|
-
- write MCP JSON-RPC to `stdin` and read it from `stdout`
|
|
39
|
-
- let the `mcp` subcommand auto-start and proxy through the local UnoLock daemon
|
|
40
|
-
|
|
41
33
|
## Key Rules
|
|
42
34
|
|
|
43
|
-
- prefer CLI commands over MCP when the host supports direct command execution
|
|
44
35
|
- give the agent the Agent Key URL and PIN together for first setup
|
|
45
36
|
- if a command reports that the PIN is needed, run `unolock-agent set-agent-pin '<pin>'` and retry the original command
|
|
46
37
|
- keep the PIN in UnoLock process memory only
|
|
38
|
+
- if a host explicitly requires the host-command form, use `npx -y @techsologic/unolock-agent@latest mcp`
|
|
47
39
|
|
|
48
40
|
## User-Facing Model
|
|
49
41
|
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ description: Guides an AI agent through connecting to a user's UnoLock Safe with
|
|
|
6
6
|
# UnoLock Agent Access
|
|
7
7
|
|
|
8
8
|
Use this skill when a user wants to give their agent access to a UnoLock Safe.
|
|
9
|
-
This skill uses the local `unolock-agent` executable on the user's device.
|
|
9
|
+
This skill uses the local `unolock-agent` executable on the user's device.
|
|
10
10
|
|
|
11
11
|
## Preferred Workflow
|
|
12
12
|
|
|
@@ -31,20 +31,12 @@ This skill uses the local `unolock-agent` executable on the user's device. The C
|
|
|
31
31
|
- `unolock-agent list-files`, `unolock-agent get-file <archive_id>`, `unolock-agent download-file ...`, `unolock-agent upload-file ...`, `unolock-agent rename-file ...`, `unolock-agent replace-file ...`, `unolock-agent delete-file ...`: read and manage Cloud files
|
|
32
32
|
- `unolock-agent get-record <record_ref>` and `unolock-agent rename-record ...`: inspect or rename an existing note or checklist
|
|
33
33
|
|
|
34
|
-
## MCP Fallback
|
|
35
|
-
|
|
36
|
-
If the host specifically requires MCP instead of CLI:
|
|
37
|
-
|
|
38
|
-
- run `npx -y @techsologic/unolock-agent@latest mcp`
|
|
39
|
-
- write MCP JSON-RPC to `stdin` and read it from `stdout`
|
|
40
|
-
- let the `mcp` subcommand auto-start and proxy through the local UnoLock daemon
|
|
41
|
-
|
|
42
34
|
## Key Rules
|
|
43
35
|
|
|
44
|
-
- prefer CLI commands over MCP when the host supports direct command execution
|
|
45
36
|
- give the agent the Agent Key URL and PIN together for first setup
|
|
46
37
|
- if a command reports that the PIN is needed, run `unolock-agent set-agent-pin '<pin>'` and retry the original command
|
|
47
38
|
- keep the PIN in UnoLock process memory only
|
|
39
|
+
- if a host explicitly requires the host-command form, use `npx -y @techsologic/unolock-agent@latest mcp`
|
|
48
40
|
|
|
49
41
|
## User-Facing Model
|
|
50
42
|
|