@agentcred-ai/cli 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 AgentCred Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ declare const version = "0.0.1";
2
+ declare function main(): Promise<void>;
3
+
4
+ export { main, version };
package/dist/index.js ADDED
@@ -0,0 +1,273 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/init.ts
4
+ import { parseArgs } from "util";
5
+ import { createIdentity, FileSystemKeyStorage } from "@agentcred-ai/sdk";
6
+ var HELP = `agentcred init \u2014 Initialize identity with GitHub token
7
+
8
+ Usage: agentcred init --token <github_token>
9
+
10
+ Options:
11
+ --token <token> GitHub personal access token (required)
12
+ --help, -h Show this help message`;
13
+ async function initCommand(args) {
14
+ if (args.includes("--help") || args.includes("-h")) {
15
+ console.log(HELP);
16
+ return;
17
+ }
18
+ const { values } = parseArgs({
19
+ args,
20
+ options: {
21
+ token: { type: "string" }
22
+ },
23
+ strict: false
24
+ });
25
+ const token = values.token ?? process.env["AGENTCRED_GITHUB_TOKEN"];
26
+ if (!token) {
27
+ throw new Error("GitHub token required. Use --token <token> or set AGENTCRED_GITHUB_TOKEN");
28
+ }
29
+ if (typeof token !== "string") {
30
+ throw new Error("Invalid token: --token flag must be provided with a value");
31
+ }
32
+ const storage = new FileSystemKeyStorage();
33
+ const identity = await createIdentity(token, { storage });
34
+ console.log(`\u2713 Identity created for @${identity.github.username}`);
35
+ }
36
+
37
+ // src/commands/sign.ts
38
+ import { parseArgs as parseArgs2 } from "util";
39
+ import * as fs from "fs/promises";
40
+ import { loadIdentity, sign, FileSystemKeyStorage as FileSystemKeyStorage2 } from "@agentcred-ai/sdk";
41
+ var HELP2 = `agentcred sign \u2014 Sign content with your AgentCred identity
42
+
43
+ Usage: agentcred sign [file] [options]
44
+ cat file.txt | agentcred sign
45
+
46
+ Options:
47
+ --agent <name> Agent name (default: "default")
48
+ --help, -h Show this help message
49
+
50
+ If no file is given, reads from stdin.`;
51
+ async function readStdin() {
52
+ const chunks = [];
53
+ for await (const chunk of process.stdin) {
54
+ chunks.push(chunk);
55
+ }
56
+ return Buffer.concat(chunks).toString("utf-8");
57
+ }
58
+ async function signCommand(args) {
59
+ if (args.includes("--help") || args.includes("-h")) {
60
+ console.log(HELP2);
61
+ return;
62
+ }
63
+ const { values, positionals } = parseArgs2({
64
+ args,
65
+ options: {
66
+ agent: { type: "string" }
67
+ },
68
+ allowPositionals: true,
69
+ strict: false
70
+ });
71
+ const filePath = positionals[0];
72
+ let content;
73
+ if (filePath) {
74
+ content = await fs.readFile(filePath, "utf-8");
75
+ } else if (!process.stdin.isTTY) {
76
+ content = await readStdin();
77
+ } else {
78
+ throw new Error("No input provided. Pass a file argument or pipe content via stdin.");
79
+ }
80
+ const storage = new FileSystemKeyStorage2();
81
+ const usernames = await storage.list();
82
+ if (usernames.length === 0) {
83
+ throw new Error("No identity found. Run 'agentcred init' first.");
84
+ }
85
+ const username = usernames[0];
86
+ const loaded = await loadIdentity(username, { storage });
87
+ if (!loaded) {
88
+ throw new Error("No identity found. Run 'agentcred init' first.");
89
+ }
90
+ const envelope = await sign(content, {
91
+ privateKey: loaded.privateKey,
92
+ github: username
93
+ }, { agent: values.agent });
94
+ console.log(JSON.stringify(envelope, null, 2));
95
+ }
96
+
97
+ // src/commands/verify.ts
98
+ import { parseArgs as parseArgs3 } from "util";
99
+ import * as fs2 from "fs/promises";
100
+ import { verify, verifyOffline } from "@agentcred-ai/sdk";
101
+ import { importJWK } from "jose";
102
+ var HELP3 = `agentcred verify \u2014 Verify an AgentCred envelope
103
+
104
+ Usage: agentcred verify [file] [options]
105
+ cat envelope.json | agentcred verify
106
+
107
+ Options:
108
+ --offline Verify offline using a local public key
109
+ --key <path> Path to public key JWK file (used with --offline)
110
+ --help, -h Show this help message
111
+
112
+ If no file is given, reads from stdin.`;
113
+ async function readStdin2() {
114
+ const chunks = [];
115
+ for await (const chunk of process.stdin) {
116
+ chunks.push(chunk);
117
+ }
118
+ return Buffer.concat(chunks).toString("utf-8");
119
+ }
120
+ async function verifyCommand(args) {
121
+ if (args.includes("--help") || args.includes("-h")) {
122
+ console.log(HELP3);
123
+ return;
124
+ }
125
+ const { values, positionals } = parseArgs3({
126
+ args,
127
+ options: {
128
+ offline: { type: "boolean", default: false },
129
+ key: { type: "string" }
130
+ },
131
+ allowPositionals: true,
132
+ strict: false
133
+ });
134
+ const filePath = positionals[0];
135
+ let input;
136
+ if (filePath) {
137
+ input = await fs2.readFile(filePath, "utf-8");
138
+ } else if (!process.stdin.isTTY) {
139
+ input = await readStdin2();
140
+ } else {
141
+ throw new Error("No input provided. Pass a file argument or pipe content via stdin.");
142
+ }
143
+ let envelope;
144
+ try {
145
+ envelope = JSON.parse(input);
146
+ } catch {
147
+ throw new Error("Invalid JSON input. Expected an AgentCred envelope.");
148
+ }
149
+ if (!envelope.agentcred?.jws) {
150
+ throw new Error("Invalid envelope: missing agentcred.jws field.");
151
+ }
152
+ if (values.offline) {
153
+ if (!values.key) {
154
+ throw new Error("--key <path> is required when using --offline");
155
+ }
156
+ if (typeof values.key !== "string") {
157
+ throw new Error("Invalid key: --key flag must be provided with a file path");
158
+ }
159
+ const keyData = await fs2.readFile(values.key, "utf-8");
160
+ const publicJWK = JSON.parse(keyData);
161
+ const publicKey = await importJWK(publicJWK, "EdDSA");
162
+ const result = await verifyOffline(envelope, publicKey);
163
+ if (result.verified) {
164
+ console.log(`\u2713 Verified: @${result.github?.username} (${result.agent}) at ${result.signedAt}`);
165
+ } else {
166
+ console.error(`\u2717 Verification failed: ${result.error}`);
167
+ process.exit(1);
168
+ }
169
+ } else {
170
+ const result = await verify(envelope);
171
+ if (result.verified) {
172
+ console.log(`\u2713 Verified: @${result.github?.username} (${result.agent}) at ${result.signedAt}`);
173
+ } else {
174
+ console.error(`\u2717 Verification failed: ${result.error}`);
175
+ process.exit(1);
176
+ }
177
+ }
178
+ }
179
+
180
+ // src/commands/whoami.ts
181
+ import { FileSystemKeyStorage as FileSystemKeyStorage3 } from "@agentcred-ai/sdk";
182
+ import { createHash } from "crypto";
183
+ import * as fs3 from "fs/promises";
184
+ import * as path from "path";
185
+ import * as os from "os";
186
+ var HELP4 = `agentcred whoami \u2014 Show current identity
187
+
188
+ Usage: agentcred whoami
189
+
190
+ Options:
191
+ --help, -h Show this help message`;
192
+ async function whoamiCommand(args) {
193
+ if (args.includes("--help") || args.includes("-h")) {
194
+ console.log(HELP4);
195
+ return;
196
+ }
197
+ const storage = new FileSystemKeyStorage3();
198
+ const usernames = await storage.list();
199
+ if (usernames.length === 0) {
200
+ throw new Error("No identity configured. Run 'agentcred init' first.");
201
+ }
202
+ const username = usernames[0];
203
+ const keyDir = path.join(os.homedir(), ".agentcred", "keys");
204
+ const keyPath = path.join(keyDir, `${username}.jwk`);
205
+ try {
206
+ const keyData = await fs3.readFile(keyPath, "utf-8");
207
+ const privateJWK = JSON.parse(keyData);
208
+ const { d: _d, ...publicPortion } = privateJWK;
209
+ const fingerprint = createHash("sha256").update(JSON.stringify(publicPortion)).digest("hex").slice(0, 16);
210
+ console.log(`You are @${username} (fingerprint: ${fingerprint})`);
211
+ } catch {
212
+ throw new Error("No identity configured. Run 'agentcred init' first.");
213
+ }
214
+ }
215
+
216
+ // src/index.ts
217
+ var version = "0.0.1";
218
+ var HELP5 = `agentcred v${version} \u2014 Human accountability badge for AI agents
219
+
220
+ Usage: agentcred <command> [options]
221
+
222
+ Commands:
223
+ init Initialize identity with GitHub token
224
+ sign Sign content (file or stdin)
225
+ verify Verify an AgentCred envelope (file or stdin)
226
+ whoami Show current identity
227
+
228
+ Options:
229
+ --help, -h Show this help message
230
+ --version, -v Show version
231
+
232
+ Run 'agentcred <command> --help' for command-specific help.`;
233
+ var commands = {
234
+ init: initCommand,
235
+ sign: signCommand,
236
+ verify: verifyCommand,
237
+ whoami: whoamiCommand
238
+ };
239
+ async function main() {
240
+ const args = process.argv.slice(2);
241
+ if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
242
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
243
+ console.log(HELP5);
244
+ process.exit(0);
245
+ }
246
+ }
247
+ if (args.includes("--version") || args.includes("-v")) {
248
+ console.log(version);
249
+ process.exit(0);
250
+ }
251
+ const commandName = args[0];
252
+ const commandArgs = args.slice(1);
253
+ const command = commands[commandName];
254
+ if (!command) {
255
+ console.error(`Unknown command: ${commandName}`);
256
+ console.error(`Run 'agentcred --help' for available commands.`);
257
+ process.exit(1);
258
+ }
259
+ try {
260
+ await command(commandArgs);
261
+ } catch (error) {
262
+ const message = error instanceof Error ? error.message : String(error);
263
+ console.error(`\u2717 ${message}`);
264
+ process.exit(1);
265
+ }
266
+ }
267
+ if (!process.env["VITEST"]) {
268
+ main();
269
+ }
270
+ export {
271
+ main,
272
+ version
273
+ };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@agentcred-ai/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI tool for AgentCred developer workflows",
5
+ "type": "module",
6
+ "bin": {
7
+ "agentcred": "./dist/index.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "dependencies": {
21
+ "jose": "^6.1.3",
22
+ "@agentcred-ai/sdk": "0.1.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^25.1.0",
26
+ "tsup": "^8.0.0",
27
+ "typescript": "^5.8.0",
28
+ "vitest": "^3.0.0"
29
+ },
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/agentcred-ai/agentcred",
34
+ "directory": "packages/cli"
35
+ },
36
+ "homepage": "https://agentcred.dev",
37
+ "bugs": {
38
+ "url": "https://github.com/agentcred-ai/agentcred/issues"
39
+ },
40
+ "keywords": [
41
+ "agentcred",
42
+ "ai-agent",
43
+ "mcp",
44
+ "cryptography",
45
+ "ed25519",
46
+ "identity",
47
+ "signature"
48
+ ],
49
+ "author": "AgentCred Contributors",
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "test": "vitest run",
53
+ "typecheck": "tsc --noEmit"
54
+ }
55
+ }