@pinchpass/cli 1.0.0

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/SKILL.md ADDED
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: pinchpass
3
+ description: Generate one-time E2E-encrypted secret request links via pinchpass. Use when an agent needs to collect API keys, tokens, passwords, connection strings, or any sensitive value from the user. Trigger on keywords: API key, secret, token, credentials, password, .env.
4
+ version: 1.0.0
5
+ homepage: https://github.com/rubybear-lgtm/PinchPass
6
+ metadata: { "openclaw": { "requires": { "bins": ["pinchpass"] } } }
7
+ ---
8
+
9
+ # pinchpass
10
+
11
+ Securely collect sensitive values from users with end-to-end encryption. The
12
+ relay never sees the secret — encryption happens in the browser, the key lives
13
+ only in the URL fragment.
14
+
15
+ ## When to use
16
+
17
+ - An agent needs a value it does not have (API key, token, password, etc.)
18
+ - The user says "I need to give you a secret" or "where do I put my key?"
19
+ - A `.env` file needs to be populated with credentials
20
+
21
+ Do **not** use for non-sensitive plaintext — there is no reason to go through
22
+ E2E encryption for a public value.
23
+
24
+ ## CLI
25
+
26
+ ```bash
27
+ pinchpass request <secret-name>... [flags]
28
+ ```
29
+
30
+ Bare `pinchpass <name>` also works (auto-detects missing subcommand).
31
+
32
+ ### Flags
33
+
34
+ | Flag | Default | Description |
35
+ |---------------|---------------|------------------------------------------|
36
+ | `-tunnel` | false | Open a bore.pub tunnel for a public URL |
37
+ | `-note` | — | Description shown on the form |
38
+ | `-out` | `.env` | Output .env file path |
39
+ | `-ttl` | 30 | Minutes until the link expires |
40
+ | `-port` | random | Local port to bind |
41
+ | `-listen-addr`| `127.0.0.1` | Address to listen on |
42
+ | `-json` | false | Machine-readable JSON output |
43
+
44
+ ## Workflow
45
+
46
+ 1. Run `pinchpass request <name> -json` to get a link
47
+ 2. Give the link to the user (the fragment `#k=<hex>` is the decryption key)
48
+ 3. User opens the link in a browser, fills in the value, submits
49
+ 4. Server waits for the submission or TTL expiry
50
+ 5. On success, the value is decrypted and written to `.env`
51
+
52
+ ### JSON output mode
53
+
54
+ Use `-json` for machine parsing. The JSON is printed twice:
55
+ - **Before waiting**: `{ "success": true, "url": "...", "port": N }`
56
+ - **After completion**: `{ "success": true/false, "names": [...], "message": "..." }`
57
+
58
+ ## Workflow example
59
+
60
+ ```bash
61
+ # Collect an API key via public tunnel
62
+ pinchpass request GEMINI_API_KEY -tunnel -json
63
+ # → Prints link object with url field
64
+ # → Agent gives url to user
65
+ # → Agent waits for result
66
+ # → On completion, value in .env
67
+ ```
68
+
69
+ ## Edge cases
70
+
71
+ - **One-time use**: after the first POST, the token is consumed. Retry
72
+ generates a 404. If it fails, generate a new link.
73
+ - **TTL expiry**: server shuts down after the TTL. No value is saved and exit
74
+ code is 1. Generate a new link with a longer `-ttl` if needed.
75
+ - **No tunnel**: without `-tunnel`, the link is only reachable on
76
+ `127.0.0.1:<port>`. Use for local-only workflows or when the user is on the
77
+ same machine.
78
+ - **Bore.pub unreachable**: tunnel startup fails if bore.pub is down. Fall
79
+ back to local mode or retry.
80
+ - **Shell escaping**: values written to `.env` are shell-escaped for `\`,
81
+ `"`, `$`, and backtick.
@@ -0,0 +1,20 @@
1
+ declare const _default: () => Promise<{
2
+ tool: {
3
+ request_secret: {
4
+ description: string;
5
+ args: {
6
+ names: import("zod").ZodArray<import("zod").ZodString>;
7
+ tunnel: import("zod").ZodOptional<import("zod").ZodBoolean>;
8
+ note: import("zod").ZodOptional<import("zod").ZodString>;
9
+ ttl: import("zod").ZodOptional<import("zod").ZodNumber>;
10
+ };
11
+ execute(args: {
12
+ names: string[];
13
+ tunnel?: boolean | undefined;
14
+ note?: string | undefined;
15
+ ttl?: number | undefined;
16
+ }, context: import("@opencode-ai/plugin/tool").ToolContext): Promise<import("@opencode-ai/plugin/tool").ToolResult>;
17
+ };
18
+ };
19
+ }>;
20
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,52 @@
1
+ import { tool } from "@opencode-ai/plugin/tool";
2
+ import { execSync } from "child_process";
3
+ export default async () => {
4
+ return {
5
+ tool: {
6
+ request_secret: tool({
7
+ description: "Generate a one-time E2E-encrypted secret request link. " +
8
+ "Use when you need to collect sensitive values (API keys, tokens, passwords) from the user. " +
9
+ "The tool starts a local server, prints a link, and blocks until the user submits or the TTL expires. " +
10
+ "On success the secret is saved to .env and the tool returns the result.",
11
+ args: {
12
+ names: tool.schema
13
+ .array(tool.schema.string())
14
+ .min(1)
15
+ .describe("Secret name(s) to collect, e.g. ['GEMINI_API_KEY']"),
16
+ tunnel: tool.schema
17
+ .boolean()
18
+ .optional()
19
+ .describe("Create a public URL via bore.pub tunnel (default: false)"),
20
+ note: tool.schema
21
+ .string()
22
+ .optional()
23
+ .describe("Description shown on the form to help the user"),
24
+ ttl: tool.schema
25
+ .number()
26
+ .optional()
27
+ .describe("Minutes until the link expires (default: 30)"),
28
+ },
29
+ async execute(args) {
30
+ const cmd = ["pinchpass", "request", ...args.names, "-json"];
31
+ if (args.tunnel)
32
+ cmd.push("-tunnel");
33
+ if (args.note)
34
+ cmd.push("-note", args.note);
35
+ if (args.ttl)
36
+ cmd.push("-ttl", String(args.ttl));
37
+ try {
38
+ const stdout = execSync(cmd.join(" "), {
39
+ encoding: "utf-8",
40
+ timeout: (args.ttl ?? 30) * 60 * 1000,
41
+ });
42
+ return stdout;
43
+ }
44
+ catch (err) {
45
+ const msg = err instanceof Error ? err.message : String(err);
46
+ return `Failed to generate secret request: ${msg}`;
47
+ }
48
+ },
49
+ }),
50
+ },
51
+ };
52
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@pinchpass/cli",
3
+ "version": "1.0.0",
4
+ "description": "One-time E2E-encrypted secret request links for OpenClaw agents",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "files": [
8
+ "dist",
9
+ "SKILL.md"
10
+ ],
11
+ "openclaw": {
12
+ "extensions": [
13
+ "./dist/index.js"
14
+ ]
15
+ },
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "dependencies": {
21
+ "@opencode-ai/plugin": "^1.16.2"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^25.9.2",
25
+ "typescript": "^5.9.0"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ }
30
+ }