@uvrn/cli 1.0.1 → 1.0.3

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/src/cli.ts DELETED
@@ -1,294 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Loosechain Delta Engine CLI
5
- * Command-line interface for running delta engine operations
6
- */
7
-
8
- import { Command } from 'commander';
9
- import * as fs from 'fs';
10
- import * as path from 'path';
11
- import { runDeltaEngine, validateBundle, verifyReceipt } from '@uvrn/core';
12
- import type { DeltaBundle, DeltaReceipt } from '@uvrn/core';
13
-
14
- const packageJson = require('../package.json');
15
-
16
- // Exit codes
17
- const EXIT_SUCCESS = 0;
18
- const EXIT_INVALID_BUNDLE = 1;
19
- const EXIT_ENGINE_ERROR = 2;
20
- const EXIT_IO_ERROR = 3;
21
-
22
- interface CliOptions {
23
- output?: string;
24
- quiet?: boolean;
25
- pretty?: boolean;
26
- }
27
-
28
- /**
29
- * Read input from file, stdin, or URL
30
- */
31
- async function readInput(input?: string): Promise<string> {
32
- try {
33
- // If no input specified, read from stdin
34
- if (!input || input === '-') {
35
- return await readStdin();
36
- }
37
-
38
- // Check if it's a URL
39
- if (input.startsWith('http://') || input.startsWith('https://')) {
40
- return await fetchUrl(input);
41
- }
42
-
43
- // Otherwise, treat as file path
44
- const resolvedPath = path.resolve(process.cwd(), input);
45
- return fs.readFileSync(resolvedPath, 'utf-8');
46
- } catch (error) {
47
- throw new Error(`Failed to read input: ${(error as Error).message}`);
48
- }
49
- }
50
-
51
- /**
52
- * Read from stdin
53
- */
54
- async function readStdin(): Promise<string> {
55
- return new Promise((resolve, reject) => {
56
- let data = '';
57
- process.stdin.setEncoding('utf-8');
58
-
59
- process.stdin.on('data', chunk => {
60
- data += chunk;
61
- });
62
-
63
- process.stdin.on('end', () => {
64
- resolve(data);
65
- });
66
-
67
- process.stdin.on('error', error => {
68
- reject(error);
69
- });
70
- });
71
- }
72
-
73
- /**
74
- * Fetch from URL
75
- */
76
- async function fetchUrl(url: string): Promise<string> {
77
- const https = url.startsWith('https://') ? require('https') : require('http');
78
-
79
- return new Promise((resolve, reject) => {
80
- https.get(url, (res: any) => {
81
- let data = '';
82
-
83
- res.on('data', (chunk: string) => {
84
- data += chunk;
85
- });
86
-
87
- res.on('end', () => {
88
- if (res.statusCode >= 200 && res.statusCode < 300) {
89
- resolve(data);
90
- } else {
91
- reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`));
92
- }
93
- });
94
- }).on('error', (error: Error) => {
95
- reject(error);
96
- });
97
- });
98
- }
99
-
100
- /**
101
- * Parse JSON safely
102
- */
103
- function parseJson<T>(jsonString: string, type: string): T {
104
- try {
105
- return JSON.parse(jsonString);
106
- } catch (error) {
107
- throw new Error(`Invalid JSON for ${type}: ${(error as Error).message}`);
108
- }
109
- }
110
-
111
- /**
112
- * Write output to file or stdout
113
- */
114
- function writeOutput(data: any, options: CliOptions): void {
115
- const output = options.pretty
116
- ? JSON.stringify(data, null, 2)
117
- : JSON.stringify(data);
118
-
119
- if (options.output) {
120
- try {
121
- const resolvedPath = path.resolve(process.cwd(), options.output);
122
- fs.writeFileSync(resolvedPath, output, 'utf-8');
123
- if (!options.quiet) {
124
- console.error(`Output written to: ${options.output}`);
125
- }
126
- } catch (error) {
127
- console.error(`Failed to write output file: ${(error as Error).message}`);
128
- process.exit(EXIT_IO_ERROR);
129
- }
130
- } else {
131
- console.log(output);
132
- }
133
- }
134
-
135
- /**
136
- * Command: run
137
- * Execute the delta engine on a bundle
138
- */
139
- async function runCommand(input: string | undefined, options: CliOptions): Promise<void> {
140
- try {
141
- // Read and parse bundle
142
- const bundleJson = await readInput(input);
143
- const bundle = parseJson<DeltaBundle>(bundleJson, 'bundle');
144
-
145
- // Run engine
146
- const receipt = runDeltaEngine(bundle);
147
-
148
- // Output receipt
149
- writeOutput(receipt, options);
150
- process.exit(EXIT_SUCCESS);
151
- } catch (error) {
152
- const errorMessage = (error as Error).message;
153
-
154
- if (!options.quiet) {
155
- console.error('Error:', errorMessage);
156
- }
157
-
158
- if (errorMessage.includes('Invalid DeltaBundle')) {
159
- process.exit(EXIT_INVALID_BUNDLE);
160
- } else if (errorMessage.includes('Failed to read input')) {
161
- process.exit(EXIT_IO_ERROR);
162
- } else {
163
- process.exit(EXIT_ENGINE_ERROR);
164
- }
165
- }
166
- }
167
-
168
- /**
169
- * Command: validate
170
- * Validate bundle structure without running engine
171
- */
172
- async function validateCommand(input: string | undefined, options: CliOptions): Promise<void> {
173
- try {
174
- // Read and parse bundle
175
- const bundleJson = await readInput(input);
176
- const bundle = parseJson<DeltaBundle>(bundleJson, 'bundle');
177
-
178
- // Validate
179
- const result = validateBundle(bundle);
180
-
181
- if (result.valid) {
182
- if (!options.quiet) {
183
- console.log('✓ Bundle is valid');
184
- }
185
- writeOutput({ valid: true }, options);
186
- process.exit(EXIT_SUCCESS);
187
- } else {
188
- if (!options.quiet) {
189
- console.error('✗ Bundle is invalid:', result.error);
190
- }
191
- writeOutput({ valid: false, error: result.error }, options);
192
- process.exit(EXIT_INVALID_BUNDLE);
193
- }
194
- } catch (error) {
195
- if (!options.quiet) {
196
- console.error('Error:', (error as Error).message);
197
- }
198
- process.exit(EXIT_IO_ERROR);
199
- }
200
- }
201
-
202
- /**
203
- * Command: verify
204
- * Verify receipt integrity by replaying hash computation
205
- */
206
- async function verifyCommand(input: string | undefined, options: CliOptions): Promise<void> {
207
- try {
208
- // Read and parse receipt
209
- const receiptJson = await readInput(input);
210
- const receipt = parseJson<DeltaReceipt>(receiptJson, 'receipt');
211
-
212
- // Verify
213
- const result = verifyReceipt(receipt);
214
-
215
- if (result.verified) {
216
- if (!options.quiet) {
217
- console.log('✓ Receipt is valid');
218
- console.log(' Hash:', receipt.hash);
219
- }
220
- writeOutput({ verified: true, hash: receipt.hash }, options);
221
- process.exit(EXIT_SUCCESS);
222
- } else {
223
- if (!options.quiet) {
224
- console.error('✗ Receipt verification failed:', result.error);
225
- if (result.recomputedHash) {
226
- console.error(' Expected:', receipt.hash);
227
- console.error(' Computed:', result.recomputedHash);
228
- }
229
- }
230
- writeOutput({
231
- verified: false,
232
- error: result.error,
233
- providedHash: receipt.hash,
234
- recomputedHash: result.recomputedHash
235
- }, options);
236
- process.exit(EXIT_ENGINE_ERROR);
237
- }
238
- } catch (error) {
239
- if (!options.quiet) {
240
- console.error('Error:', (error as Error).message);
241
- }
242
- process.exit(EXIT_IO_ERROR);
243
- }
244
- }
245
-
246
- /**
247
- * Main CLI setup
248
- */
249
- function main(): void {
250
- const program = new Command();
251
-
252
- program
253
- .name('delta-engine')
254
- .description('CLI for Loosechain Delta Engine - Bundle → Receipt')
255
- .version(packageJson.version);
256
-
257
- program
258
- .command('run [bundle]')
259
- .description('Execute delta engine on a bundle (file path, URL, or stdin)')
260
- .option('-o, --output <file>', 'Write output to file instead of stdout')
261
- .option('-q, --quiet', 'Suppress informational messages')
262
- .option('-p, --pretty', 'Pretty-print JSON output')
263
- .action(runCommand);
264
-
265
- program
266
- .command('validate [bundle]')
267
- .description('Validate bundle structure without running engine')
268
- .option('-o, --output <file>', 'Write output to file instead of stdout')
269
- .option('-q, --quiet', 'Suppress informational messages')
270
- .option('-p, --pretty', 'Pretty-print JSON output')
271
- .action(validateCommand);
272
-
273
- program
274
- .command('verify [receipt]')
275
- .description('Verify receipt integrity by replaying hash computation')
276
- .option('-o, --output <file>', 'Write output to file instead of stdout')
277
- .option('-q, --quiet', 'Suppress informational messages')
278
- .option('-p, --pretty', 'Pretty-print JSON output')
279
- .action(verifyCommand);
280
-
281
- program.parse(process.argv);
282
-
283
- // Show help if no command provided
284
- if (!process.argv.slice(2).length) {
285
- program.outputHelp();
286
- }
287
- }
288
-
289
- // Run CLI
290
- if (require.main === module) {
291
- main();
292
- }
293
-
294
- export { main };
package/src/index.ts DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * Loosechain Delta Engine CLI
3
- * Public exports
4
- */
5
-
6
- export { main } from './cli';
package/test-bundle.json DELETED
@@ -1,25 +0,0 @@
1
- {
2
- "bundleId": "cli-test-001",
3
- "claim": "Test bundle for CLI verification",
4
- "thresholdPct": 0.05,
5
- "dataSpecs": [
6
- {
7
- "id": "source-a",
8
- "label": "Source A",
9
- "sourceKind": "metric",
10
- "originDocIds": ["doc-a"],
11
- "metrics": [
12
- { "key": "value", "value": 100, "unit": "count" }
13
- ]
14
- },
15
- {
16
- "id": "source-b",
17
- "label": "Source B",
18
- "sourceKind": "metric",
19
- "originDocIds": ["doc-b"],
20
- "metrics": [
21
- { "key": "value", "value": 102, "unit": "count" }
22
- ]
23
- }
24
- ]
25
- }
package/test-receipt.json DELETED
@@ -1 +0,0 @@
1
- {"bundleId":"cli-test-001","deltaFinal":0.01980198,"sources":["Source A","Source B"],"rounds":[{"round":1,"deltasByMetric":{"value":0.01980198},"withinThreshold":true,"witnessRequired":false}],"suggestedFixes":[],"outcome":"consensus","hash":"36247244c63f58e0b2908d2fad115f60677f29b59b67665579b9b6e8db727791"}