@passwd/passwd-agent-cli 1.3.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.
@@ -0,0 +1,3 @@
1
+ export declare function envsCommand(opts: {
2
+ json?: boolean;
3
+ }): Promise<void>;
@@ -0,0 +1,24 @@
1
+ import { getTokenDir } from "@passwd/passwd-lib";
2
+ import { scanTokenFiles } from "../util/envs.js";
3
+ export async function envsCommand(opts) {
4
+ const envs = await scanTokenFiles(getTokenDir());
5
+ if (envs.length === 0) {
6
+ console.log("No known environments. Log in with PASSWD_ORIGIN set first.");
7
+ return;
8
+ }
9
+ const currentOrigin = process.env.PASSWD_ORIGIN?.replace(/\/+$/, "");
10
+ if (opts.json) {
11
+ const out = envs.map((e) => ({
12
+ origin: e.origin,
13
+ current: e.origin === currentOrigin,
14
+ savedAt: e.savedAt,
15
+ }));
16
+ console.log(JSON.stringify(out, null, 2));
17
+ return;
18
+ }
19
+ for (const env of envs) {
20
+ const marker = env.origin === currentOrigin ? " *" : "";
21
+ console.log(`${env.origin}${marker}`);
22
+ }
23
+ }
24
+ //# sourceMappingURL=envs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envs.js","sourceRoot":"","sources":["../../src/commands/envs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAwB;IACxD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;IAEjD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;QAC3E,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAErE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,CAAC,CAAC,MAAM,KAAK,aAAa;YACnC,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function execCommand(args: string[], opts: {
2
+ inject?: string[];
3
+ }): Promise<void>;
@@ -0,0 +1,60 @@
1
+ import { spawn } from "node:child_process";
2
+ import { getSecret } from "@passwd/passwd-lib";
3
+ export async function execCommand(args, opts) {
4
+ if (!args.length) {
5
+ console.error("Usage: passwd-agent exec --inject VAR=SECRET_ID:FIELD -- command [args...]");
6
+ process.exitCode = 1;
7
+ return;
8
+ }
9
+ const injections = opts.inject ?? [];
10
+ const env = { ...process.env };
11
+ // Scrub passwd credentials so the child only gets the specific fields requested
12
+ delete env.PASSWD_ACCESS_TOKEN;
13
+ delete env.PASSWD_API_URL;
14
+ delete env.PASSWD_CLIENT_ID;
15
+ // Parse and fetch all injections in parallel
16
+ const tasks = injections.map(async (spec) => {
17
+ const eqIdx = spec.indexOf("=");
18
+ if (eqIdx === -1) {
19
+ throw new Error(`Invalid --inject format: '${spec}'. Expected VAR=SECRET_ID:FIELD`);
20
+ }
21
+ const varName = spec.slice(0, eqIdx);
22
+ const rest = spec.slice(eqIdx + 1);
23
+ const colonIdx = rest.indexOf(":");
24
+ if (colonIdx === -1) {
25
+ throw new Error(`Invalid --inject format: '${spec}'. Expected VAR=SECRET_ID:FIELD`);
26
+ }
27
+ const secretId = rest.slice(0, colonIdx);
28
+ const field = rest.slice(colonIdx + 1);
29
+ const secret = await getSecret(secretId);
30
+ const value = secret[field];
31
+ if (value === undefined) {
32
+ throw new Error(`Field '${field}' not found in secret '${secretId}'`);
33
+ }
34
+ return { varName, value: String(value) };
35
+ });
36
+ const resolved = await Promise.all(tasks);
37
+ for (const { varName, value } of resolved) {
38
+ env[varName] = value;
39
+ }
40
+ const secretValues = resolved.map((r) => r.value).filter((v) => v.length > 0);
41
+ const [cmd, ...cmdArgs] = args;
42
+ // Always mask — no --no-masking flag exists in the agent CLI
43
+ const child = spawn(cmd, cmdArgs, {
44
+ env,
45
+ stdio: ["inherit", "pipe", "pipe"],
46
+ });
47
+ const mask = (chunk) => {
48
+ let str = chunk.toString();
49
+ for (const v of secretValues) {
50
+ str = str.replaceAll(v, "<concealed by passwd>");
51
+ }
52
+ return Buffer.from(str);
53
+ };
54
+ child.stdout?.on("data", (chunk) => process.stdout.write(mask(chunk)));
55
+ child.stderr?.on("data", (chunk) => process.stderr.write(mask(chunk)));
56
+ child.on("close", (code) => {
57
+ process.exitCode = code ?? 1;
58
+ });
59
+ }
60
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/commands/exec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function getCommand(id: string, opts: {
2
+ json?: boolean;
3
+ }): Promise<void>;
@@ -0,0 +1,8 @@
1
+ import { getSecret, redactSecret } from "@passwd/passwd-lib";
2
+ import { formatJson } from "../util/format.js";
3
+ export async function getCommand(id, opts) {
4
+ const secret = await getSecret(id);
5
+ // Always redacted — no --field flag exists in the agent CLI
6
+ console.log(formatJson(redactSecret(secret)));
7
+ }
8
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAU,EACV,IAAwB;IAExB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,CAAC;IACnC,4DAA4D;IAC5D,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function listCommand(opts: {
2
+ query?: string;
3
+ type?: string;
4
+ limit?: string;
5
+ offset?: string;
6
+ json?: boolean;
7
+ }): Promise<void>;
@@ -0,0 +1,20 @@
1
+ import { listSecrets } from "@passwd/passwd-lib";
2
+ import { formatJson, formatSecretRow } from "../util/format.js";
3
+ export async function listCommand(opts) {
4
+ const result = await listSecrets({
5
+ query: opts.query,
6
+ secretType: opts.type,
7
+ limit: opts.limit !== undefined ? Number(opts.limit) : undefined,
8
+ offset: opts.offset !== undefined ? Number(opts.offset) : undefined,
9
+ });
10
+ if (opts.json) {
11
+ console.log(formatJson(result));
12
+ }
13
+ else {
14
+ console.log(`Total: ${result.totalCount}`);
15
+ for (const s of result.secrets) {
16
+ console.log(formatSecretRow(s));
17
+ }
18
+ }
19
+ }
20
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAMjC;IACC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,UAAU,EAAE,IAAI,CAAC,IAAI;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;QAChE,MAAM,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;KACpE,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function loginCommand(): Promise<void>;
@@ -0,0 +1,20 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { stdin, stdout } from "node:process";
3
+ import { buildOAuthUrl, extractCodeFromRedirectUrl, exchangeCode } from "@passwd/passwd-lib";
4
+ export async function loginCommand() {
5
+ const oauthUrl = await buildOAuthUrl();
6
+ console.log("Open this URL in your browser to authenticate:\n");
7
+ console.log(oauthUrl);
8
+ console.log();
9
+ const rl = createInterface({ input: stdin, output: stdout });
10
+ try {
11
+ const redirectUrl = await rl.question("Paste the redirect URL here: ");
12
+ const code = extractCodeFromRedirectUrl(redirectUrl.trim());
13
+ await exchangeCode(code);
14
+ console.log("Authenticated successfully. Token saved to ~/.passwd/");
15
+ }
16
+ finally {
17
+ rl.close();
18
+ }
19
+ }
20
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7F,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;IAEvC,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC;QACvE,MAAM,IAAI,GAAG,0BAA0B,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5D,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACvE,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * OpenClaw exec secrets provider protocol.
3
+ *
4
+ * Reads a JSON request from stdin:
5
+ * { "protocolVersion": 1, "provider": "passwd", "ids": ["secretId:field", ...] }
6
+ *
7
+ * Writes a JSON response to stdout:
8
+ * { "protocolVersion": 1, "values": { "secretId:field": "value", ... }, "errors": { "id": "msg", ... } }
9
+ */
10
+ export declare function resolveCommand(): Promise<void>;
@@ -0,0 +1,81 @@
1
+ import { getSecret } from "@passwd/passwd-lib";
2
+ /**
3
+ * OpenClaw exec secrets provider protocol.
4
+ *
5
+ * Reads a JSON request from stdin:
6
+ * { "protocolVersion": 1, "provider": "passwd", "ids": ["secretId:field", ...] }
7
+ *
8
+ * Writes a JSON response to stdout:
9
+ * { "protocolVersion": 1, "values": { "secretId:field": "value", ... }, "errors": { "id": "msg", ... } }
10
+ */
11
+ export async function resolveCommand() {
12
+ const input = await readStdin();
13
+ let request;
14
+ try {
15
+ request = JSON.parse(input);
16
+ }
17
+ catch {
18
+ writeResponse({}, { _parse: "Invalid JSON on stdin" });
19
+ return;
20
+ }
21
+ const ids = request.ids ?? [];
22
+ if (!Array.isArray(ids) || ids.length === 0) {
23
+ writeResponse({}, {});
24
+ return;
25
+ }
26
+ // Deduplicate secret IDs to minimize API calls
27
+ const secretIds = [...new Set(ids.map((id) => id.split(":")[0]))];
28
+ const secrets = new Map();
29
+ const fetchErrors = new Map();
30
+ const results = await Promise.allSettled(secretIds.map(async (sid) => {
31
+ const secret = await getSecret(sid);
32
+ return { sid, secret };
33
+ }));
34
+ for (const result of results) {
35
+ if (result.status === "fulfilled") {
36
+ secrets.set(result.value.sid, result.value.secret);
37
+ }
38
+ else {
39
+ const sid = secretIds[results.indexOf(result)];
40
+ fetchErrors.set(sid, String(result.reason));
41
+ }
42
+ }
43
+ const values = {};
44
+ const errors = {};
45
+ for (const id of ids) {
46
+ const [secretId, field = "password"] = id.split(":");
47
+ const fetchError = fetchErrors.get(secretId);
48
+ if (fetchError) {
49
+ errors[id] = fetchError;
50
+ continue;
51
+ }
52
+ const secret = secrets.get(secretId);
53
+ if (!secret) {
54
+ errors[id] = "Secret not found";
55
+ continue;
56
+ }
57
+ const value = secret[field];
58
+ if (value === undefined || value === null) {
59
+ errors[id] = `Field '${field}' not found`;
60
+ continue;
61
+ }
62
+ values[id] = String(value);
63
+ }
64
+ writeResponse(values, errors);
65
+ }
66
+ function writeResponse(values, errors) {
67
+ const response = { protocolVersion: 1, values };
68
+ if (Object.keys(errors).length > 0) {
69
+ response.errors = errors;
70
+ }
71
+ process.stdout.write(JSON.stringify(response) + "\n");
72
+ }
73
+ function readStdin() {
74
+ return new Promise((resolve, reject) => {
75
+ const chunks = [];
76
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
77
+ process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
78
+ process.stdin.on("error", reject);
79
+ });
80
+ }
81
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/commands/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function totpCommand(id: string, opts: {
2
+ json?: boolean;
3
+ }): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { getTotpCode } from "@passwd/passwd-lib";
2
+ import { formatJson } from "../util/format.js";
3
+ export async function totpCommand(id, opts) {
4
+ const codes = await getTotpCode(id);
5
+ if (opts.json) {
6
+ console.log(formatJson(codes));
7
+ }
8
+ else {
9
+ // Find the currently valid code
10
+ const now = Math.floor(Date.now() / 1000);
11
+ const current = codes.find((c) => now >= c.validityStart && now < c.validityEnd);
12
+ if (current) {
13
+ const remaining = current.validityEnd - now;
14
+ console.log(`${current.code} (${remaining}s remaining)`);
15
+ }
16
+ else if (codes.length > 0) {
17
+ // Fallback: show the first code
18
+ console.log(codes[0].code);
19
+ }
20
+ else {
21
+ console.error("No TOTP codes returned");
22
+ process.exitCode = 1;
23
+ }
24
+ }
25
+ }
26
+ //# sourceMappingURL=totp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"totp.js","sourceRoot":"","sources":["../../src/commands/totp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,EAAU,EACV,IAAwB;IAExB,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,gCAAgC;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;QACjF,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,cAAc,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,gCAAgC;YAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACxC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function whoamiCommand(opts: {
2
+ json?: boolean;
3
+ }): Promise<void>;
@@ -0,0 +1,12 @@
1
+ import { getCurrentUser } from "@passwd/passwd-lib";
2
+ import { formatJson } from "../util/format.js";
3
+ export async function whoamiCommand(opts) {
4
+ const user = await getCurrentUser();
5
+ if (opts.json) {
6
+ console.log(formatJson(user));
7
+ }
8
+ else {
9
+ console.log(`${user.name} <${user.email}>`);
10
+ }
11
+ }
12
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAwB;IAC1D,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { loginCommand } from "./commands/login.js";
4
+ import { whoamiCommand } from "./commands/whoami.js";
5
+ import { listCommand } from "./commands/list.js";
6
+ import { getCommand } from "./commands/get.js";
7
+ import { totpCommand } from "./commands/totp.js";
8
+ import { execCommand } from "./commands/exec.js";
9
+ import { envsCommand } from "./commands/envs.js";
10
+ import { resolveCommand } from "./commands/resolve.js";
11
+ import { formatError } from "./util/format.js";
12
+ import { resolveEnv } from "./util/envs.js";
13
+ import { resetDiscoveryCache, getTokenDir } from "@passwd/passwd-lib";
14
+ const program = new Command();
15
+ program
16
+ .name("passwd-agent")
17
+ .description("Agent-safe CLI for passwd.team — no command exposes raw credential values")
18
+ .version("1.3.0")
19
+ .enablePositionalOptions()
20
+ .option("--env <name>", "Target a specific environment (substring match against known origins)");
21
+ program.hook("preAction", async (thisCommand) => {
22
+ const envName = thisCommand.opts().env;
23
+ if (envName) {
24
+ const origin = await resolveEnv(envName, getTokenDir());
25
+ process.env.PASSWD_ORIGIN = origin;
26
+ resetDiscoveryCache();
27
+ }
28
+ });
29
+ program
30
+ .command("login")
31
+ .description("Authenticate with Google OAuth")
32
+ .action(() => loginCommand().catch(die));
33
+ program
34
+ .command("whoami")
35
+ .description("Show current user")
36
+ .option("--json", "Output as JSON")
37
+ .action((opts) => whoamiCommand(opts).catch(die));
38
+ program
39
+ .command("list")
40
+ .description("List secrets")
41
+ .option("-q, --query <text>", "Search by name, username, or URL")
42
+ .option("-t, --type <type>", "Filter by secret type")
43
+ .option("-l, --limit <n>", "Maximum results")
44
+ .option("-o, --offset <n>", "Skip first N results")
45
+ .option("--json", "Output as JSON")
46
+ .action((opts) => listCommand(opts).catch(die));
47
+ program
48
+ .command("get <id>")
49
+ .description("Get a secret (credentials always redacted)")
50
+ .option("--json", "Output as JSON")
51
+ .action((id, opts) => getCommand(id, opts).catch(die));
52
+ program
53
+ .command("totp <id>")
54
+ .description("Get current TOTP code")
55
+ .option("--json", "Output as JSON (includes remaining seconds)")
56
+ .action((id, opts) => totpCommand(id, opts).catch(die));
57
+ program
58
+ .command("exec")
59
+ .description("Run a command with secrets injected as environment variables")
60
+ .option("--inject <mapping...>", "VAR=SECRET_ID:FIELD (repeatable)")
61
+ .argument("[args...]", "Command to execute (after --)")
62
+ .passThroughOptions()
63
+ .action((args, opts) => {
64
+ execCommand(args, opts).catch(die);
65
+ });
66
+ program
67
+ .command("envs")
68
+ .description("List known environments")
69
+ .option("--json", "Output as JSON")
70
+ .action((opts) => envsCommand(opts).catch(die));
71
+ program
72
+ .command("resolve", { hidden: true })
73
+ .description("Resolve secrets for exec secrets provider (reads JSON from stdin)")
74
+ .action(() => resolveCommand().catch(die));
75
+ function die(err) {
76
+ console.error(`Error: ${formatError(err)}`);
77
+ process.exitCode = 1;
78
+ }
79
+ program.parse();
80
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface EnvInfo {
2
+ origin: string;
3
+ file: string;
4
+ savedAt?: number;
5
+ }
6
+ export declare function scanTokenFiles(tokenDir: string): Promise<EnvInfo[]>;
7
+ export declare function resolveEnv(name: string, tokenDir: string): Promise<string>;
@@ -0,0 +1,49 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ export async function scanTokenFiles(tokenDir) {
4
+ let files;
5
+ try {
6
+ files = await readdir(tokenDir);
7
+ }
8
+ catch {
9
+ return [];
10
+ }
11
+ const results = [];
12
+ for (const file of files) {
13
+ if (!file.startsWith("tokens-") || !file.endsWith(".json"))
14
+ continue;
15
+ try {
16
+ const content = await readFile(join(tokenDir, file), "utf-8");
17
+ const tokens = JSON.parse(content);
18
+ if (tokens.origin) {
19
+ results.push({
20
+ origin: tokens.origin,
21
+ file,
22
+ savedAt: tokens.saved_at,
23
+ });
24
+ }
25
+ }
26
+ catch {
27
+ // skip unreadable/corrupt files
28
+ }
29
+ }
30
+ return results;
31
+ }
32
+ export async function resolveEnv(name, tokenDir) {
33
+ const envs = await scanTokenFiles(tokenDir);
34
+ if (envs.length === 0) {
35
+ throw new Error("No known environments. Log in with PASSWD_ORIGIN set first.");
36
+ }
37
+ const lower = name.toLowerCase();
38
+ const matches = envs.filter((e) => e.origin.toLowerCase().includes(lower));
39
+ if (matches.length === 0) {
40
+ const known = envs.map((e) => ` ${e.origin}`).join("\n");
41
+ throw new Error(`No environment matching "${name}". Known environments:\n${known}`);
42
+ }
43
+ if (matches.length > 1) {
44
+ const list = matches.map((e) => ` ${e.origin}`).join("\n");
45
+ throw new Error(`Ambiguous match for "${name}". Matching environments:\n${list}\nBe more specific.`);
46
+ }
47
+ return matches[0].origin;
48
+ }
49
+ //# sourceMappingURL=envs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envs.js","sourceRoot":"","sources":["../../src/util/envs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QACrE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAe,CAAC;YACjD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC;oBACX,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,IAAI;oBACJ,OAAO,EAAE,MAAM,CAAC,QAAQ;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,QAAgB;IAEhB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAE3E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,2BAA2B,KAAK,EAAE,CACnE,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,8BAA8B,IAAI,qBAAqB,CACpF,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { SecretListItem } from "@passwd/passwd-lib";
2
+ export declare function formatError(error: unknown): string;
3
+ export declare function formatJson(data: unknown): string;
4
+ export declare function formatSecretRow(s: SecretListItem): string;
@@ -0,0 +1,15 @@
1
+ export function formatError(error) {
2
+ return error instanceof Error ? error.message : String(error);
3
+ }
4
+ export function formatJson(data) {
5
+ return JSON.stringify(data, null, 2);
6
+ }
7
+ export function formatSecretRow(s) {
8
+ const parts = [s.id, s.type, s.name];
9
+ if (s.username)
10
+ parts.push(s.username);
11
+ if (s.web)
12
+ parts.push(s.web);
13
+ return parts.join("\t");
14
+ }
15
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/util/format.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAiB;IAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,CAAC,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@passwd/passwd-agent-cli",
3
+ "version": "1.3.0",
4
+ "description": "Agent-safe CLI for passwd.team — no command exposes raw credential values",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "passwd-agent": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc -b"
15
+ },
16
+ "keywords": [
17
+ "passwd",
18
+ "password-manager",
19
+ "cli",
20
+ "agent",
21
+ "passwd-team"
22
+ ],
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "@passwd/passwd-lib": "1.3.0",
26
+ "commander": "^13.1.0"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/pepuscz/passwd.git",
31
+ "directory": "packages/passwd-agent-cli"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ }
36
+ }