@ch4p/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.
@@ -0,0 +1,215 @@
1
+ import {
2
+ loadConfig
3
+ } from "./chunk-NRFRTZVP.js";
4
+ import {
5
+ BOLD,
6
+ DIM,
7
+ GREEN,
8
+ RED,
9
+ RESET,
10
+ TEAL,
11
+ YELLOW,
12
+ separator
13
+ } from "./chunk-NMGPBPNU.js";
14
+
15
+ // src/commands/identity.ts
16
+ var CHAIN_NAMES = {
17
+ 1: "Ethereum Mainnet",
18
+ 8453: "Base",
19
+ 42161: "Arbitrum One",
20
+ 10: "Optimism",
21
+ 11155111: "Sepolia",
22
+ 84532: "Base Sepolia"
23
+ };
24
+ async function identity(args) {
25
+ const subcommand = args[0] ?? "status";
26
+ switch (subcommand) {
27
+ case "status":
28
+ await identityStatus();
29
+ break;
30
+ case "register":
31
+ await identityRegister();
32
+ break;
33
+ default:
34
+ console.error(`
35
+ ${RED}Unknown identity subcommand:${RESET} ${subcommand}`);
36
+ console.error(` ${DIM}Available: status, register${RESET}
37
+ `);
38
+ process.exitCode = 1;
39
+ break;
40
+ }
41
+ }
42
+ async function identityStatus() {
43
+ console.log(`
44
+ ${TEAL}${BOLD}ch4p Identity${RESET}`);
45
+ console.log(separator());
46
+ console.log("");
47
+ let config;
48
+ try {
49
+ config = loadConfig();
50
+ } catch (err) {
51
+ const message = err instanceof Error ? err.message : String(err);
52
+ console.error(` ${RED}Failed to load config:${RESET} ${message}`);
53
+ console.error(` ${DIM}Run ${TEAL}ch4p onboard${DIM} to set up ch4p.${RESET}
54
+ `);
55
+ process.exitCode = 1;
56
+ return;
57
+ }
58
+ const idConfig = config.identity;
59
+ if (!idConfig?.enabled) {
60
+ console.log(` ${BOLD}Status${RESET} ${DIM}disabled${RESET}`);
61
+ console.log("");
62
+ console.log(` ${DIM}To enable on-chain identity, add to ~/.ch4p/config.json:${RESET}`);
63
+ console.log(` ${DIM}{${RESET}`);
64
+ console.log(` ${DIM} "identity": {${RESET}`);
65
+ console.log(` ${DIM} "enabled": true,${RESET}`);
66
+ console.log(` ${DIM} "provider": "erc8004",${RESET}`);
67
+ console.log(` ${DIM} "rpcUrl": "https://mainnet.base.org"${RESET}`);
68
+ console.log(` ${DIM} }${RESET}`);
69
+ console.log(` ${DIM}}${RESET}
70
+ `);
71
+ return;
72
+ }
73
+ const chainId = idConfig.chainId ?? 8453;
74
+ const chainName = CHAIN_NAMES[chainId] ?? `Chain ${chainId}`;
75
+ const hasKey = !!(idConfig.privateKey && !idConfig.privateKey.includes("${"));
76
+ const hasRpc = !!idConfig.rpcUrl;
77
+ console.log(` ${BOLD}Status${RESET} ${GREEN}enabled${RESET}`);
78
+ console.log(` ${BOLD}Provider${RESET} ${idConfig.provider}`);
79
+ console.log(` ${BOLD}Chain${RESET} ${chainName} (${chainId})`);
80
+ console.log(` ${BOLD}RPC URL${RESET} ${hasRpc ? idConfig.rpcUrl : `${YELLOW}not configured${RESET}`}`);
81
+ console.log(` ${BOLD}Private Key${RESET} ${hasKey ? `${GREEN}configured${RESET}` : `${DIM}not set (read-only)${RESET}`}`);
82
+ console.log(` ${BOLD}Agent ID${RESET} ${idConfig.agentId ?? `${DIM}not registered${RESET}`}`);
83
+ const feedbackMode = idConfig.feedbackMode ?? "off";
84
+ console.log(` ${BOLD}Feedback${RESET} ${feedbackMode}${feedbackMode === "threshold" ? ` (>= ${idConfig.feedbackThreshold ?? 0.7})` : ""}`);
85
+ const trust = idConfig.trust;
86
+ if (trust) {
87
+ console.log("");
88
+ console.log(` ${BOLD}Trust Configuration${RESET}`);
89
+ console.log(` ${BOLD} Min Reputation${RESET} ${trust.minReputation ?? 0}`);
90
+ console.log(` ${BOLD} Min Validation${RESET} ${trust.minValidation ?? 0}`);
91
+ console.log(
92
+ ` ${BOLD} Trusted Clients${RESET} ${trust.trustedClients?.length ?? 0} configured`
93
+ );
94
+ console.log(
95
+ ` ${BOLD} Trusted Validators${RESET} ${trust.trustedValidators?.length ?? 0} configured`
96
+ );
97
+ }
98
+ if (idConfig.agentId && hasRpc) {
99
+ console.log("");
100
+ try {
101
+ const { EthIdentityProvider } = await import("@ch4p/plugin-erc8004");
102
+ const provider = new EthIdentityProvider({
103
+ enabled: true,
104
+ chainId,
105
+ rpcUrl: idConfig.rpcUrl,
106
+ contracts: idConfig.contracts ?? {}
107
+ });
108
+ const onChainIdentity = await provider.getIdentity(idConfig.agentId);
109
+ if (onChainIdentity) {
110
+ console.log(` ${BOLD}On-Chain Identity${RESET}`);
111
+ console.log(` ${BOLD} Global ID${RESET} ${onChainIdentity.globalId}`);
112
+ console.log(` ${BOLD} Owner${RESET} ${onChainIdentity.ownerAddress}`);
113
+ if (onChainIdentity.agentWallet) {
114
+ console.log(` ${BOLD} Agent Wallet${RESET} ${onChainIdentity.agentWallet}`);
115
+ }
116
+ if (onChainIdentity.uri) {
117
+ console.log(` ${BOLD} URI${RESET} ${onChainIdentity.uri}`);
118
+ }
119
+ } else {
120
+ console.log(` ${YELLOW}Agent ID ${idConfig.agentId} not found on-chain.${RESET}`);
121
+ }
122
+ } catch {
123
+ console.log(` ${DIM}On-chain lookup unavailable (plugin not installed or RPC error).${RESET}`);
124
+ }
125
+ }
126
+ console.log("");
127
+ }
128
+ async function identityRegister() {
129
+ console.log(`
130
+ ${TEAL}${BOLD}ch4p Identity \u2014 Register${RESET}`);
131
+ console.log(separator());
132
+ console.log("");
133
+ let config;
134
+ try {
135
+ config = loadConfig();
136
+ } catch (err) {
137
+ const message = err instanceof Error ? err.message : String(err);
138
+ console.error(` ${RED}Failed to load config:${RESET} ${message}`);
139
+ process.exitCode = 1;
140
+ return;
141
+ }
142
+ const idConfig = config.identity;
143
+ if (!idConfig?.enabled) {
144
+ console.error(` ${RED}Identity is not enabled.${RESET}`);
145
+ console.error(` ${DIM}Enable it in ~/.ch4p/config.json first.${RESET}
146
+ `);
147
+ process.exitCode = 1;
148
+ return;
149
+ }
150
+ if (!idConfig.rpcUrl) {
151
+ console.error(` ${RED}No RPC URL configured.${RESET}`);
152
+ console.error(` ${DIM}Set identity.rpcUrl in ~/.ch4p/config.json.${RESET}
153
+ `);
154
+ process.exitCode = 1;
155
+ return;
156
+ }
157
+ if (!idConfig.privateKey || idConfig.privateKey.includes("${")) {
158
+ console.error(` ${RED}No private key configured.${RESET}`);
159
+ console.error(` ${DIM}Registration requires a private key for signing transactions.${RESET}`);
160
+ console.error(` ${DIM}Set identity.privateKey in ~/.ch4p/config.json.${RESET}
161
+ `);
162
+ process.exitCode = 1;
163
+ return;
164
+ }
165
+ if (idConfig.agentId) {
166
+ console.log(` ${YELLOW}Agent already registered with ID: ${idConfig.agentId}${RESET}`);
167
+ console.log(` ${DIM}Run ${TEAL}ch4p identity status${DIM} to see details.${RESET}
168
+ `);
169
+ return;
170
+ }
171
+ const chainId = idConfig.chainId ?? 8453;
172
+ const chainName = CHAIN_NAMES[chainId] ?? `Chain ${chainId}`;
173
+ console.log(` ${BOLD}Chain${RESET} ${chainName} (${chainId})`);
174
+ console.log(` ${BOLD}RPC${RESET} ${idConfig.rpcUrl}`);
175
+ console.log("");
176
+ console.log(` ${DIM}Registering agent on-chain...${RESET}`);
177
+ try {
178
+ const { EthIdentityProvider } = await import("@ch4p/plugin-erc8004");
179
+ const provider = new EthIdentityProvider({
180
+ enabled: true,
181
+ chainId,
182
+ rpcUrl: idConfig.rpcUrl,
183
+ contracts: idConfig.contracts ?? {},
184
+ privateKey: idConfig.privateKey
185
+ });
186
+ const identity2 = await provider.register();
187
+ console.log("");
188
+ console.log(` ${GREEN}${BOLD}Agent registered successfully!${RESET}`);
189
+ console.log("");
190
+ console.log(` ${BOLD}Agent ID${RESET} ${identity2.agentId}`);
191
+ console.log(` ${BOLD}Global ID${RESET} ${identity2.globalId}`);
192
+ console.log(` ${BOLD}Owner${RESET} ${identity2.ownerAddress}`);
193
+ if (identity2.uri) {
194
+ console.log(` ${BOLD}URI${RESET} ${identity2.uri}`);
195
+ }
196
+ console.log("");
197
+ console.log(` ${DIM}Next steps:${RESET}`);
198
+ console.log(` ${DIM} 1. Add ${TEAL}"agentId": "${identity2.agentId}"${DIM} to identity config${RESET}`);
199
+ console.log(` ${DIM} 2. Run ${TEAL}ch4p gateway${DIM} to serve /.well-known/agent.json${RESET}`);
200
+ console.log(` ${DIM} 3. Run ${TEAL}ch4p identity status${DIM} to verify${RESET}`);
201
+ console.log("");
202
+ } catch (err) {
203
+ const message = err instanceof Error ? err.message : String(err);
204
+ console.error(`
205
+ ${RED}Registration failed:${RESET} ${message}`);
206
+ if (message.includes("insufficient funds")) {
207
+ console.error(` ${DIM}The wallet needs ETH/gas tokens on ${chainName} to pay for the transaction.${RESET}`);
208
+ }
209
+ console.error("");
210
+ process.exitCode = 1;
211
+ }
212
+ }
213
+ export {
214
+ identity
215
+ };
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ BOLD,
4
+ DIM,
5
+ GREEN,
6
+ RED,
7
+ RESET,
8
+ TEAL
9
+ } from "./chunk-NMGPBPNU.js";
10
+
11
+ // src/index.ts
12
+ import { readFileSync } from "fs";
13
+ import { resolve, dirname } from "path";
14
+ import { fileURLToPath } from "url";
15
+ function getVersion() {
16
+ try {
17
+ if (typeof CH4P_VERSION === "string") return CH4P_VERSION;
18
+ } catch {
19
+ }
20
+ try {
21
+ const __dirname = dirname(fileURLToPath(import.meta.url));
22
+ const paths = [
23
+ resolve(__dirname, "..", "package.json"),
24
+ resolve(__dirname, "..", "..", "package.json")
25
+ ];
26
+ for (const p of paths) {
27
+ try {
28
+ const raw = readFileSync(p, "utf8");
29
+ const pkg = JSON.parse(raw);
30
+ if (pkg.version) return pkg.version;
31
+ } catch {
32
+ }
33
+ }
34
+ } catch {
35
+ }
36
+ return "0.1.0";
37
+ }
38
+ function printHelp() {
39
+ const version = getVersion();
40
+ console.log(`
41
+ ${TEAL}${BOLD}ch4p${RESET} ${DIM}v${version}${RESET} -- Personal AI Assistant
42
+
43
+ ${BOLD}Usage${RESET}
44
+ ${GREEN}ch4p${RESET} Interactive agent mode (REPL)
45
+ ${GREEN}ch4p agent${RESET} Interactive agent mode (REPL)
46
+ ${GREEN}ch4p agent -m "message"${RESET} Single message mode
47
+ ${GREEN}ch4p${RESET} ${DIM}<command> [options]${RESET}
48
+
49
+ ${BOLD}Commands${RESET}
50
+ ${GREEN}agent${RESET} Start the agent (interactive or single message)
51
+ ${GREEN}gateway${RESET} Start the gateway server
52
+ ${GREEN}onboard${RESET} Run the setup wizard
53
+ ${GREEN}audit${RESET} Run a security audit
54
+ ${GREEN}doctor${RESET} Run health checks
55
+ ${GREEN}status${RESET} Show system status
56
+ ${GREEN}tools${RESET} List available tools
57
+ ${GREEN}pairing${RESET} Manage gateway pairing
58
+ ${GREEN}message${RESET} Send a message via a channel
59
+ ${GREEN}skills${RESET} Manage agent skills
60
+ ${GREEN}canvas${RESET} Start the interactive canvas workspace
61
+ ${GREEN}identity${RESET} Manage on-chain agent identity (ERC-8004)
62
+ ${GREEN}install${RESET} Install gateway as a system daemon (systemd / launchd)
63
+
64
+ ${BOLD}Agent Options${RESET}
65
+ ${GREEN}-m, --message${RESET} "text" Run a single message and exit
66
+
67
+ ${BOLD}Message Options${RESET}
68
+ ${GREEN}-c, --channel${RESET} name Target channel (telegram, discord, etc.)
69
+ ${GREEN}-t, --thread${RESET} id Thread ID for threaded replies
70
+
71
+ ${BOLD}Global Options${RESET}
72
+ ${GREEN}--help, -h${RESET} Show this help
73
+ ${GREEN}--version, -V${RESET} Show version
74
+
75
+ ${BOLD}Examples${RESET}
76
+ ${DIM}$${RESET} ch4p ${DIM}# Start interactive mode${RESET}
77
+ ${DIM}$${RESET} ch4p agent -m "Summarize README.md" ${DIM}# Single message${RESET}
78
+ ${DIM}$${RESET} ch4p onboard ${DIM}# First-time setup${RESET}
79
+ ${DIM}$${RESET} ch4p audit ${DIM}# Security audit${RESET}
80
+ ${DIM}$${RESET} ch4p doctor ${DIM}# Health checks${RESET}
81
+ ${DIM}$${RESET} ch4p status ${DIM}# System status${RESET}
82
+ ${DIM}$${RESET} ch4p tools ${DIM}# List tools${RESET}
83
+ ${DIM}$${RESET} ch4p canvas ${DIM}# Start canvas workspace${RESET}
84
+ ${DIM}$${RESET} ch4p message -c telegram "Hello!" ${DIM}# Send via channel${RESET}
85
+ ${DIM}$${RESET} ch4p install ${DIM}# Install gateway daemon${RESET}
86
+
87
+ ${DIM}Run ${TEAL}ch4p onboard${DIM} to get started.${RESET}
88
+ `);
89
+ }
90
+ function parseArgs(argv) {
91
+ const args = argv.slice(2);
92
+ if (args.includes("--help") || args.includes("-h")) {
93
+ return { command: "help", rest: [] };
94
+ }
95
+ if (args.includes("--version") || args.includes("-v") || args.includes("-V")) {
96
+ return { command: "version", rest: [] };
97
+ }
98
+ if (args.length === 0) {
99
+ return { command: "agent", rest: [] };
100
+ }
101
+ const command = args[0] ?? "agent";
102
+ const rest = args.slice(1);
103
+ return { command, rest };
104
+ }
105
+ async function main() {
106
+ const { command, rest } = parseArgs(process.argv);
107
+ switch (command) {
108
+ case "agent": {
109
+ const { agent } = await import("./agent-LRE3CXL3.js");
110
+ await agent(rest);
111
+ break;
112
+ }
113
+ case "gateway": {
114
+ const { gateway } = await import("./gateway-KZYTXCIQ.js");
115
+ await gateway(rest);
116
+ break;
117
+ }
118
+ case "onboard": {
119
+ const { onboard } = await import("./onboard-ZVZLMMZP.js");
120
+ await onboard();
121
+ break;
122
+ }
123
+ case "audit": {
124
+ const { audit } = await import("./audit-BIGXGJSQ.js");
125
+ await audit();
126
+ break;
127
+ }
128
+ case "doctor": {
129
+ const { doctor } = await import("./doctor-D6CEAUAC.js");
130
+ await doctor();
131
+ break;
132
+ }
133
+ case "status": {
134
+ const { status } = await import("./status-6HMA7CDS.js");
135
+ await status();
136
+ break;
137
+ }
138
+ case "tools": {
139
+ const { tools } = await import("./tools-2X5MBDEX.js");
140
+ await tools();
141
+ break;
142
+ }
143
+ case "pairing": {
144
+ const { pairing } = await import("./pairing-UOUSOB7K.js");
145
+ await pairing(rest);
146
+ break;
147
+ }
148
+ case "message": {
149
+ const { message } = await import("./message-JHZX6JBD.js");
150
+ await message(rest);
151
+ break;
152
+ }
153
+ case "skills": {
154
+ const { skills } = await import("./skills-UPJVALNY.js");
155
+ await skills(rest);
156
+ break;
157
+ }
158
+ case "canvas": {
159
+ const { canvas } = await import("./canvas-OIXBPYUL.js");
160
+ await canvas(rest);
161
+ break;
162
+ }
163
+ case "identity": {
164
+ const { identity } = await import("./identity-S45KJKEO.js");
165
+ await identity(rest);
166
+ break;
167
+ }
168
+ case "install": {
169
+ const { install } = await import("./install-WROGJA5J.js");
170
+ await install(rest);
171
+ break;
172
+ }
173
+ case "version": {
174
+ console.log(`ch4p v${getVersion()}`);
175
+ break;
176
+ }
177
+ case "help": {
178
+ printHelp();
179
+ break;
180
+ }
181
+ default: {
182
+ console.error(`
183
+ ${RED}Unknown command:${RESET} ${command}`);
184
+ console.error(` ${DIM}Run ${TEAL}ch4p --help${DIM} for available commands.${RESET}
185
+ `);
186
+ process.exitCode = 1;
187
+ break;
188
+ }
189
+ }
190
+ }
191
+ main().catch((err) => {
192
+ const message = err instanceof Error ? err.message : String(err);
193
+ console.error(`
194
+ ${RED}${BOLD}Fatal error:${RESET} ${message}`);
195
+ if (err instanceof Error && err.stack) {
196
+ const stackLines = err.stack.split("\n").slice(1).map((l) => ` ${l.trim()}`).join("\n");
197
+ console.error(`${DIM}${stackLines}${RESET}`);
198
+ }
199
+ process.exitCode = 1;
200
+ });