hashproof 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/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # hashproof
2
+
3
+ Command line interface for the Hashproof Content Provenance API. Verify, store, resolve, and fingerprint digital assets from the terminal.
4
+
5
+ ## Install
6
+
7
+ Run it without installing, using npx:
8
+
9
+ ```bash
10
+ npx hashproof status
11
+ ```
12
+
13
+ Or install it globally:
14
+
15
+ ```bash
16
+ npm install -g hashproof
17
+ ```
18
+
19
+ ## Authentication
20
+
21
+ The `verify`, `store`, `resolve`, and `fingerprint` commands require an API key. Keys start with `hpsk_`. Save one with:
22
+
23
+ ```bash
24
+ hashproof config set-key hpsk_your_key
25
+ ```
26
+
27
+ You can also provide the key through the environment, which takes precedence over the saved key:
28
+
29
+ ```bash
30
+ export HASHPROOF_API_KEY=hpsk_your_key
31
+ ```
32
+
33
+ The `status` command does not require a key.
34
+
35
+ ## Commands
36
+
37
+ ```bash
38
+ hashproof verify <file> # Check a file's content provenance
39
+ hashproof store <file> # Store a C2PA manifest for a file
40
+ hashproof resolve <file> # Resolve provenance by soft binding
41
+ hashproof fingerprint <file> # Compute a perceptual fingerprint
42
+ hashproof status # Report API service status
43
+ hashproof config set-key <key> # Save your API key
44
+ hashproof config set-url <url> # Set a custom API base URL
45
+ hashproof config show # Show the current configuration
46
+ ```
47
+
48
+ `store` accepts `--title` (`-t`) to set an asset title. `fingerprint` accepts `--algorithm` (`-a`), which defaults to `phash-dct-64`.
49
+
50
+ ## Configuration
51
+
52
+ Configuration is stored at `~/.hashproof/config.json`. Two environment variables override the saved values:
53
+
54
+ - `HASHPROOF_API_KEY` overrides the saved API key.
55
+ - `HASHPROOF_BASE_URL` overrides the API base URL. The default is `https://api.hashproof.ai`.
56
+
57
+ ## License
58
+
59
+ MIT
@@ -0,0 +1,27 @@
1
+ export interface CliConfig {
2
+ apiKey?: string;
3
+ baseUrl?: string;
4
+ }
5
+ /**
6
+ * Load the CLI configuration from disk.
7
+ * Returns an empty config if the file does not exist.
8
+ */
9
+ export declare function loadConfig(): CliConfig;
10
+ /**
11
+ * Save the CLI configuration to disk.
12
+ */
13
+ export declare function saveConfig(config: CliConfig): void;
14
+ /**
15
+ * Get the API key from config or HASHPROOF_API_KEY environment variable.
16
+ * Environment variable takes precedence.
17
+ */
18
+ export declare function getApiKey(): string | undefined;
19
+ /**
20
+ * Get the base URL from config or HASHPROOF_BASE_URL environment variable.
21
+ */
22
+ export declare function getBaseUrl(): string | undefined;
23
+ /**
24
+ * Get the path to the config file for display purposes.
25
+ */
26
+ export declare function getConfigPath(): string;
27
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAcD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,SAAS,CAOtC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGlD;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAE/C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
package/dist/config.js ADDED
@@ -0,0 +1,57 @@
1
+ // ============================================================
2
+ // @hashproof/cli — Config file management
3
+ // Stores config at ~/.hashproof/config.json
4
+ // ============================================================
5
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { homedir } from 'node:os';
8
+ const CONFIG_DIR = join(homedir(), '.hashproof');
9
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
10
+ /**
11
+ * Ensure the config directory exists.
12
+ */
13
+ function ensureConfigDir() {
14
+ if (!existsSync(CONFIG_DIR)) {
15
+ mkdirSync(CONFIG_DIR, { recursive: true });
16
+ }
17
+ }
18
+ /**
19
+ * Load the CLI configuration from disk.
20
+ * Returns an empty config if the file does not exist.
21
+ */
22
+ export function loadConfig() {
23
+ try {
24
+ const raw = readFileSync(CONFIG_FILE, 'utf-8');
25
+ return JSON.parse(raw);
26
+ }
27
+ catch {
28
+ return {};
29
+ }
30
+ }
31
+ /**
32
+ * Save the CLI configuration to disk.
33
+ */
34
+ export function saveConfig(config) {
35
+ ensureConfigDir();
36
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + '\n', 'utf-8');
37
+ }
38
+ /**
39
+ * Get the API key from config or HASHPROOF_API_KEY environment variable.
40
+ * Environment variable takes precedence.
41
+ */
42
+ export function getApiKey() {
43
+ return process.env['HASHPROOF_API_KEY'] || loadConfig().apiKey;
44
+ }
45
+ /**
46
+ * Get the base URL from config or HASHPROOF_BASE_URL environment variable.
47
+ */
48
+ export function getBaseUrl() {
49
+ return process.env['HASHPROOF_BASE_URL'] || loadConfig().baseUrl;
50
+ }
51
+ /**
52
+ * Get the path to the config file for display purposes.
53
+ */
54
+ export function getConfigPath() {
55
+ return CONFIG_FILE;
56
+ }
57
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,0CAA0C;AAC1C,4CAA4C;AAC5C,+DAA+D;AAE/D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAOlC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACjD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD;;GAEG;AACH,SAAS,eAAe;IACtB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,eAAe,EAAE,CAAC;IAClB,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,UAAU,EAAE,CAAC,MAAM,CAAC;AACjE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,UAAU,EAAE,CAAC,OAAO,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,62 @@
1
+ import type { ManifestData, VerifyResult, ResolveResult, FingerprintResult } from '@hashproof/sdk';
2
+ /**
3
+ * Local, CLI-only mirror of the GET /v1/status response shape. Declared HERE
4
+ * (not imported from @hashproof/shared or @hashproof/api) so the CLI carries no
5
+ * private-workspace coupling; the API's ServiceHealth is the contract this
6
+ * conforms TO. Fields are optional/loose because the wire payload is untrusted.
7
+ */
8
+ export interface ServiceHealth {
9
+ status?: string;
10
+ services?: Record<string, string>;
11
+ }
12
+ /**
13
+ * Print a labeled key-value pair.
14
+ */
15
+ export declare function kv(label: string, value: string | number | boolean | null | undefined): void;
16
+ /**
17
+ * Print a section header.
18
+ */
19
+ export declare function header(text: string): void;
20
+ /**
21
+ * Print a success message.
22
+ */
23
+ export declare function success(message: string): void;
24
+ /**
25
+ * Print a warning message.
26
+ */
27
+ export declare function warn(message: string): void;
28
+ /**
29
+ * Print an error message.
30
+ */
31
+ export declare function error(message: string): void;
32
+ /**
33
+ * Display a verification result in a human-readable format.
34
+ */
35
+ export declare function displayVerifyResult(result: VerifyResult): void;
36
+ /**
37
+ * Display manifest summary.
38
+ */
39
+ export declare function displayManifestSummary(manifest: ManifestData): void;
40
+ /**
41
+ * Display a resolve result with matches.
42
+ */
43
+ export declare function displayResolveResult(result: ResolveResult): void;
44
+ /**
45
+ * Display a store result.
46
+ */
47
+ export declare function displayStoreResult(result: {
48
+ manifestId: string;
49
+ manifest: ManifestData;
50
+ softBindings: unknown[];
51
+ }): void;
52
+ /**
53
+ * Display a fingerprint result.
54
+ */
55
+ export declare function displayFingerprintResult(result: FingerprintResult): void;
56
+ /**
57
+ * Display API status: the overall status plus a per-service breakdown from the
58
+ * GET /v1/status response. Defensive against a missing or malformed payload so
59
+ * the command never crashes on an unexpected shape.
60
+ */
61
+ export declare function displayStatus(health: unknown): void;
62
+ //# sourceMappingURL=display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnG;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAID;;GAEG;AACH,wBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAG3F;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGzC;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAyC9D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAgCnE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CA6BhE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,OAAO,EAAE,CAAA;CAAE,GAAG,IAAI,CAOxH;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAMxE;AAmBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAoBnD"}
@@ -0,0 +1,246 @@
1
+ // ============================================================
2
+ // @hashproof/cli — Terminal output formatting
3
+ // ============================================================
4
+ import chalk from 'chalk';
5
+ // --- Generic utilities ---
6
+ /**
7
+ * Print a labeled key-value pair.
8
+ */
9
+ export function kv(label, value) {
10
+ const displayValue = value === null || value === undefined ? chalk.dim('(none)') : String(value);
11
+ console.log(` ${chalk.bold(padRight(label, 22))} ${displayValue}`);
12
+ }
13
+ /**
14
+ * Print a section header.
15
+ */
16
+ export function header(text) {
17
+ console.log();
18
+ console.log(chalk.cyan.bold(`--- ${text} ---`));
19
+ }
20
+ /**
21
+ * Print a success message.
22
+ */
23
+ export function success(message) {
24
+ console.log(chalk.green.bold('\u2713') + ' ' + message);
25
+ }
26
+ /**
27
+ * Print a warning message.
28
+ */
29
+ export function warn(message) {
30
+ console.log(chalk.yellow.bold('!') + ' ' + message);
31
+ }
32
+ /**
33
+ * Print an error message.
34
+ */
35
+ export function error(message) {
36
+ console.log(chalk.red.bold('Error:') + ' ' + message);
37
+ }
38
+ // --- Domain-specific formatters ---
39
+ /**
40
+ * Display a verification result in a human-readable format.
41
+ */
42
+ export function displayVerifyResult(result) {
43
+ header('Verification Result');
44
+ if (result.hasProvenance) {
45
+ success('Provenance found');
46
+ }
47
+ else {
48
+ warn('No provenance found');
49
+ }
50
+ kv('Source', colorSource(result.source));
51
+ kv('Trust Status', colorTrust(result.trustStatus));
52
+ if (result.resolvedVia) {
53
+ kv('Resolved Via', result.resolvedVia);
54
+ }
55
+ if (result.manifest) {
56
+ displayManifestSummary(result.manifest);
57
+ }
58
+ if (result.validation) {
59
+ header('Validation');
60
+ kv('Status', colorValidation(result.validation.status));
61
+ kv('Trust Chain Valid', result.validation.trustChainValid);
62
+ kv('Signer Trusted', result.validation.signerTrusted);
63
+ if (result.validation.errors.length > 0) {
64
+ console.log(chalk.red(` Errors (${result.validation.errors.length}):`));
65
+ for (const err of result.validation.errors) {
66
+ console.log(` - [${err.code}] ${err.message}`);
67
+ }
68
+ }
69
+ if (result.validation.warnings.length > 0) {
70
+ console.log(chalk.yellow(` Warnings (${result.validation.warnings.length}):`));
71
+ for (const w of result.validation.warnings) {
72
+ console.log(` - ${w}`);
73
+ }
74
+ }
75
+ }
76
+ console.log();
77
+ }
78
+ /**
79
+ * Display manifest summary.
80
+ */
81
+ export function displayManifestSummary(manifest) {
82
+ header('Manifest');
83
+ kv('ID', manifest.id);
84
+ kv('Title', manifest.title);
85
+ kv('Format', manifest.format);
86
+ kv('Validation', colorValidation(manifest.validationStatus));
87
+ kv('Claim Generator', manifest.claimGenerator);
88
+ kv('Created', manifest.createdAt);
89
+ kv('Size', formatBytes(manifest.rawSize));
90
+ if (manifest.signatureInfo) {
91
+ kv('Signer', manifest.signatureInfo.subject);
92
+ kv('Issuer', manifest.signatureInfo.issuer);
93
+ kv('Algorithm', manifest.signatureInfo.algorithm);
94
+ kv('Signed At', manifest.signatureInfo.signedAt);
95
+ }
96
+ if (manifest.assertions.length > 0) {
97
+ console.log(` ${chalk.bold(padRight('Assertions', 22))} ${manifest.assertions.length}`);
98
+ for (const a of manifest.assertions) {
99
+ console.log(` - ${a.label} (${a.kind})`);
100
+ }
101
+ }
102
+ if (manifest.ingredients.length > 0) {
103
+ console.log(` ${chalk.bold(padRight('Ingredients', 22))} ${manifest.ingredients.length}`);
104
+ for (const i of manifest.ingredients) {
105
+ console.log(` - ${i.title} [${i.relationship}]`);
106
+ }
107
+ }
108
+ kv('Hard Binding', `${manifest.hardBinding.algorithm}: ${truncate(manifest.hardBinding.hash, 32)}`);
109
+ }
110
+ /**
111
+ * Display a resolve result with matches.
112
+ */
113
+ export function displayResolveResult(result) {
114
+ header('Resolution Result');
115
+ kv('Fingerprint', result.query.fingerprint);
116
+ kv('Algorithm', result.query.algorithm);
117
+ kv('Search Time', `${result.searchTimeMs}ms`);
118
+ kv('Matches', result.matches.length);
119
+ if (result.matches.length === 0) {
120
+ warn('No matching manifests found.');
121
+ }
122
+ else {
123
+ console.log();
124
+ console.log(chalk.bold(' # Similarity Distance Manifest ID Title'));
125
+ console.log(' ' + '-'.repeat(90));
126
+ for (let i = 0; i < result.matches.length; i++) {
127
+ const m = result.matches[i];
128
+ const sim = `${(m.similarity * 100).toFixed(1)}%`;
129
+ const idx = padRight(String(i + 1), 4);
130
+ const simStr = padRight(colorSimilarity(sim, m.similarity), 23); // account for ANSI codes
131
+ const dist = padRight(String(m.distance), 11);
132
+ const id = padRight(m.manifestId, 39);
133
+ const title = m.manifest.title || chalk.dim('Untitled');
134
+ console.log(` ${idx}${simStr}${dist}${id}${title}`);
135
+ }
136
+ }
137
+ console.log();
138
+ }
139
+ /**
140
+ * Display a store result.
141
+ */
142
+ export function displayStoreResult(result) {
143
+ success(`Manifest stored successfully`);
144
+ header('Stored Manifest');
145
+ kv('Manifest ID', result.manifestId);
146
+ kv('Soft Bindings', result.softBindings.length);
147
+ displayManifestSummary(result.manifest);
148
+ console.log();
149
+ }
150
+ /**
151
+ * Display a fingerprint result.
152
+ */
153
+ export function displayFingerprintResult(result) {
154
+ header('Fingerprint');
155
+ kv('Fingerprint', result.fingerprint);
156
+ kv('Algorithm', result.algorithm);
157
+ kv('Bit Length', result.bitLength);
158
+ console.log();
159
+ }
160
+ /**
161
+ * Color a /v1/status value with the 3-valued scheme: operational=green,
162
+ * degraded=yellow, outage/unknown=red.
163
+ */
164
+ function colorServiceStatus(value) {
165
+ switch (value) {
166
+ case 'operational':
167
+ return chalk.green(value);
168
+ case 'degraded':
169
+ return chalk.yellow(value);
170
+ case 'outage':
171
+ return chalk.red(value);
172
+ default:
173
+ return chalk.red(value); // unknown -> red (fail visible)
174
+ }
175
+ }
176
+ /**
177
+ * Display API status: the overall status plus a per-service breakdown from the
178
+ * GET /v1/status response. Defensive against a missing or malformed payload so
179
+ * the command never crashes on an unexpected shape.
180
+ */
181
+ export function displayStatus(health) {
182
+ header('Hashproof API Status');
183
+ const h = health && typeof health === 'object' ? health : {};
184
+ const overall = typeof h.status === 'string' ? h.status : 'unknown';
185
+ kv('Overall', colorServiceStatus(overall));
186
+ const services = h.services;
187
+ if (services && typeof services === 'object') {
188
+ const entries = Object.entries(services);
189
+ if (entries.length > 0) {
190
+ console.log();
191
+ for (const [name, value] of entries) {
192
+ kv(capitalize(name), colorServiceStatus(String(value)));
193
+ }
194
+ }
195
+ }
196
+ console.log();
197
+ }
198
+ // --- Helpers ---
199
+ function colorTrust(trust) {
200
+ switch (trust) {
201
+ case 'trusted': return chalk.green.bold('TRUSTED');
202
+ case 'untrusted': return chalk.red.bold('UNTRUSTED');
203
+ default: return chalk.yellow('UNKNOWN');
204
+ }
205
+ }
206
+ function colorSource(source) {
207
+ switch (source) {
208
+ case 'embedded': return chalk.green('Embedded C2PA');
209
+ case 'resolved': return chalk.blue('Resolved (soft binding)');
210
+ default: return chalk.dim('None');
211
+ }
212
+ }
213
+ function colorValidation(status) {
214
+ switch (status) {
215
+ case 'trusted': return chalk.green.bold('TRUSTED');
216
+ case 'valid': return chalk.green('VALID');
217
+ case 'well_formed': return chalk.yellow('WELL FORMED');
218
+ default: return chalk.dim('UNKNOWN');
219
+ }
220
+ }
221
+ function colorSimilarity(text, value) {
222
+ if (value >= 0.95)
223
+ return chalk.green.bold(text);
224
+ if (value >= 0.8)
225
+ return chalk.green(text);
226
+ if (value >= 0.5)
227
+ return chalk.yellow(text);
228
+ return chalk.red(text);
229
+ }
230
+ function padRight(str, len) {
231
+ return str.length >= len ? str : str + ' '.repeat(len - str.length);
232
+ }
233
+ function truncate(str, len) {
234
+ return str.length <= len ? str : str.slice(0, len) + '...';
235
+ }
236
+ function formatBytes(bytes) {
237
+ if (bytes < 1024)
238
+ return `${bytes} B`;
239
+ if (bytes < 1024 * 1024)
240
+ return `${(bytes / 1024).toFixed(1)} KB`;
241
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
242
+ }
243
+ function capitalize(str) {
244
+ return str.charAt(0).toUpperCase() + str.slice(1);
245
+ }
246
+ //# sourceMappingURL=display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env node
2
+ // ============================================================
3
+ // @hashproof/cli — Hashproof Content Provenance CLI
4
+ // ============================================================
5
+ import { Command } from 'commander';
6
+ import { readFileSync } from 'node:fs';
7
+ import chalk from 'chalk';
8
+ import { HashproofClient, HashproofApiError } from '@hashproof/sdk';
9
+ import { loadConfig, saveConfig, getApiKey, getBaseUrl, getConfigPath } from './config.js';
10
+ import { displayVerifyResult, displayResolveResult, displayStoreResult, displayFingerprintResult, displayStatus, error as printError, success, header, kv, } from './display.js';
11
+ const VERSION = '0.1.0';
12
+ // ============================================================
13
+ // Client factory
14
+ // ============================================================
15
+ function createClient() {
16
+ const apiKey = getApiKey();
17
+ if (!apiKey) {
18
+ console.error(chalk.red.bold('Error:') + ' No API key configured.');
19
+ console.error('');
20
+ console.error('Set your API key with:');
21
+ console.error(chalk.cyan(' hashproof config set-key <your-api-key>'));
22
+ console.error('');
23
+ console.error('Or set the HASHPROOF_API_KEY environment variable:');
24
+ console.error(chalk.cyan(' export HASHPROOF_API_KEY=hpsk_...'));
25
+ process.exit(1);
26
+ }
27
+ return new HashproofClient({
28
+ apiKey,
29
+ baseUrl: getBaseUrl(),
30
+ });
31
+ }
32
+ /**
33
+ * Read a file from disk and return its contents as a Buffer.
34
+ */
35
+ function readFile(filePath) {
36
+ try {
37
+ return readFileSync(filePath);
38
+ }
39
+ catch (err) {
40
+ const message = err instanceof Error ? err.message : String(err);
41
+ console.error(chalk.red.bold('Error:') + ` Could not read file: ${filePath}`);
42
+ console.error(` ${message}`);
43
+ process.exit(1);
44
+ }
45
+ }
46
+ /**
47
+ * Wrap a command handler with standard error handling.
48
+ */
49
+ function handleErrors(fn) {
50
+ return async (...args) => {
51
+ try {
52
+ await fn(...args);
53
+ }
54
+ catch (err) {
55
+ if (err instanceof HashproofApiError) {
56
+ printError(`${err.message} (${err.code}, HTTP ${err.statusCode})`);
57
+ if (err.details) {
58
+ console.error(chalk.dim(JSON.stringify(err.details, null, 2)));
59
+ }
60
+ }
61
+ else if (err instanceof Error) {
62
+ printError(err.message);
63
+ }
64
+ else {
65
+ printError(String(err));
66
+ }
67
+ process.exit(1);
68
+ }
69
+ };
70
+ }
71
+ // ============================================================
72
+ // Program
73
+ // ============================================================
74
+ const program = new Command();
75
+ program
76
+ .name('hashproof')
77
+ .description('Hashproof Content Provenance CLI — verify, store, and resolve C2PA manifests')
78
+ .version(VERSION);
79
+ // --- verify ---
80
+ program
81
+ .command('verify <file>')
82
+ .description('Verify a file\'s content provenance')
83
+ .action(handleErrors(async (filePath) => {
84
+ const client = createClient();
85
+ const fileBuffer = readFile(filePath);
86
+ console.log(chalk.dim(`Verifying ${filePath}...`));
87
+ const result = await client.verify(fileBuffer);
88
+ displayVerifyResult(result);
89
+ }));
90
+ // --- store ---
91
+ program
92
+ .command('store <file>')
93
+ .description('Store a C2PA manifest from a digital asset')
94
+ .option('-t, --title <title>', 'Title for the asset')
95
+ .action(handleErrors(async (filePath, opts) => {
96
+ const client = createClient();
97
+ const fileBuffer = readFile(filePath);
98
+ const options = opts;
99
+ console.log(chalk.dim(`Storing manifest for ${filePath}...`));
100
+ const result = await client.store(fileBuffer, { title: options.title });
101
+ displayStoreResult(result);
102
+ }));
103
+ // --- resolve ---
104
+ program
105
+ .command('resolve <file>')
106
+ .description('Resolve provenance for a file via soft binding')
107
+ .option('-a, --algorithm <alg>', 'Soft binding algorithm', 'phash-dct-64')
108
+ .action(handleErrors(async (filePath, opts) => {
109
+ const client = createClient();
110
+ const fileBuffer = readFile(filePath);
111
+ const options = opts;
112
+ console.log(chalk.dim(`Resolving provenance for ${filePath}...`));
113
+ const result = await client.resolve(fileBuffer);
114
+ displayResolveResult(result);
115
+ }));
116
+ // --- fingerprint ---
117
+ program
118
+ .command('fingerprint <file>')
119
+ .description('Compute a perceptual fingerprint for a file')
120
+ .option('-a, --algorithm <alg>', 'Algorithm to use', 'phash-dct-64')
121
+ .action(handleErrors(async (filePath, opts) => {
122
+ const client = createClient();
123
+ const fileBuffer = readFile(filePath);
124
+ const options = opts;
125
+ console.log(chalk.dim(`Computing fingerprint for ${filePath}...`));
126
+ const result = await client.computeFingerprint(fileBuffer, options.algorithm);
127
+ displayFingerprintResult(result);
128
+ }));
129
+ // --- status ---
130
+ program
131
+ .command('status')
132
+ .description('Check the Hashproof API status')
133
+ .action(handleErrors(async () => {
134
+ const apiKey = getApiKey();
135
+ const baseUrl = (getBaseUrl() || 'https://api.hashproof.ai').replace(/\/+$/, '');
136
+ const response = await fetch(`${baseUrl}/v1/status`, {
137
+ headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
138
+ });
139
+ if (!response.ok) {
140
+ printError(`API returned HTTP ${response.status}`);
141
+ process.exit(1);
142
+ }
143
+ const status = await response.json();
144
+ displayStatus(status);
145
+ }));
146
+ // --- config ---
147
+ const configCmd = program
148
+ .command('config')
149
+ .description('Manage CLI configuration');
150
+ configCmd
151
+ .command('set-key <key>')
152
+ .description('Set your Hashproof API key')
153
+ .action(handleErrors(async (key) => {
154
+ const apiKey = key;
155
+ if (!apiKey.startsWith('hpsk_')) {
156
+ printError('Invalid API key format. Keys start with "hpsk_".');
157
+ process.exit(1);
158
+ }
159
+ const config = loadConfig();
160
+ config.apiKey = apiKey;
161
+ saveConfig(config);
162
+ success(`API key saved to ${getConfigPath()}`);
163
+ kv('Key Prefix', apiKey.substring(0, 12) + '...');
164
+ }));
165
+ configCmd
166
+ .command('set-url <url>')
167
+ .description('Set a custom API base URL')
168
+ .action(handleErrors(async (url) => {
169
+ const config = loadConfig();
170
+ config.baseUrl = url;
171
+ saveConfig(config);
172
+ success(`Base URL set to ${url}`);
173
+ }));
174
+ configCmd
175
+ .command('show')
176
+ .description('Show current CLI configuration')
177
+ .action(handleErrors(async () => {
178
+ const config = loadConfig();
179
+ const envKey = process.env['HASHPROOF_API_KEY'];
180
+ const envUrl = process.env['HASHPROOF_BASE_URL'];
181
+ header('Configuration');
182
+ kv('Config File', getConfigPath());
183
+ console.log();
184
+ if (envKey) {
185
+ kv('API Key (env)', envKey.substring(0, 12) + '...' + chalk.dim(' (HASHPROOF_API_KEY)'));
186
+ }
187
+ if (config.apiKey) {
188
+ kv('API Key (file)', config.apiKey.substring(0, 12) + '...');
189
+ }
190
+ if (!envKey && !config.apiKey) {
191
+ kv('API Key', chalk.red('Not set'));
192
+ }
193
+ const activeKey = envKey || config.apiKey;
194
+ if (activeKey) {
195
+ kv('Active Key', (envKey ? 'env' : 'file') + ` (${activeKey.substring(0, 12)}...)`);
196
+ }
197
+ kv('Base URL', envUrl || config.baseUrl || 'https://api.hashproof.ai (default)');
198
+ console.log();
199
+ }));
200
+ // --- Parse ---
201
+ program.parse();
202
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "hashproof",
3
+ "version": "0.1.0",
4
+ "description": "CLI for the Hashproof Content Provenance API",
5
+ "type": "module",
6
+ "bin": {
7
+ "hashproof": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "engines": {
14
+ "node": ">=18"
15
+ },
16
+ "dependencies": {
17
+ "commander": "^12.0.0",
18
+ "chalk": "^5.3.0",
19
+ "@hashproof/sdk": "0.2.1"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "^5.4.0",
23
+ "tsx": "^4.7.0",
24
+ "@types/node": "^20.11.0"
25
+ },
26
+ "keywords": [
27
+ "hashproof",
28
+ "c2pa",
29
+ "content-provenance",
30
+ "cli"
31
+ ],
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/hashproof/hashproof",
36
+ "directory": "packages/cli"
37
+ },
38
+ "scripts": {
39
+ "build": "tsc",
40
+ "dev": "tsx src/index.ts",
41
+ "typecheck": "tsc --noEmit",
42
+ "lint": "eslint src/"
43
+ }
44
+ }