vana-cli 1.0.1 → 1.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 +6 -1
- package/dist/cli.js +103 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,11 +31,16 @@ npx vana-cli --help
|
|
|
31
31
|
vana config init
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
2. **
|
|
34
|
+
2. **Configure your wallet private key**:
|
|
35
35
|
```bash
|
|
36
36
|
vana config set wallet_private_key 63...
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
3. **Configure the targeted Query Engine endpoint**:
|
|
40
|
+
```bash
|
|
41
|
+
vana config set query_engine_endpoint https://...
|
|
42
|
+
```
|
|
43
|
+
|
|
39
44
|
3. **Get refiner statistics**:
|
|
40
45
|
```bash
|
|
41
46
|
vana stats refiner --id 45
|
package/dist/cli.js
CHANGED
|
@@ -1,71 +1,128 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Cli as
|
|
3
|
-
`);for(let
|
|
2
|
+
import{Cli as ge,Builtins as ie}from"clipanion";import{Command as z,Option as k}from"clipanion";import{ethers as re}from"ethers";var $=class{constructor(e){this.baseUrl=e;this.baseUrl=e}async getRefinerIngestionStats(e,t){try{let n=t.startsWith("0x")?t:`0x${t}`,r=new re.Wallet(n),o=e.toString(),s=await r.signMessage(o),u=`${this.baseUrl}/stats/refiner/${e}`,c=await fetch(u,{method:"GET",headers:{"X-Refiner-Signature":s,"Content-Type":"application/json"}});if(!c.ok){let h=await c.text(),l=`HTTP ${c.status}: ${c.statusText}`;try{let S=JSON.parse(h);l=S.detail||S.message||l}catch{l=h||l}throw new Error(l)}return await c.json()}catch(n){throw n instanceof Error?n:new Error(`Failed to get refiner ingestion stats: ${String(n)}`)}}};import{ethers as oe}from"ethers";var I=class{constructor(e){this.baseUrl=e;this.baseUrl=e}async getRefinerExecutionStats(e,t){try{let n=t.startsWith("0x")?t:`0x${t}`,r=new oe.Wallet(n),o=e.toString(),s=await r.signMessage(o),u=`${this.baseUrl}/stats/refiner/${e}`,c=await fetch(u,{method:"GET",headers:{"X-Refiner-Signature":s,"Content-Type":"application/json"}});if(!c.ok){let h=await c.text(),l=`HTTP ${c.status}: ${c.statusText}`;try{let S=JSON.parse(h);l=S.detail||S.message||l}catch{l=h||l}throw new Error(l)}return await c.json()}catch(n){throw n instanceof Error?n:new Error(`Failed to get refiner execution stats: ${String(n)}`)}}};import{promises as b}from"fs";import{join as V,dirname as se}from"path";import{homedir as ae}from"os";import F from"keytar";var P={network:"moksha",rpc_endpoint:"https://rpc.moksha.vana.org",query_engine_endpoint:"https://54531900daaa8493797db8d07d6bfbfc77f75b4b-8000.dstack-prod5.phala.network",refinement_service_endpoint:"https://a7df0ae43df690b889c1201546d7058ceb04d21b-8000.dstack-prod5.phala.network"},L="vana",D=V(ae(),".vana"),E=V(D,"cli.config.toml"),y=class i{static instance;unprotectedConfig=null;constructor(){}static getInstance(){return i.instance||(i.instance=new i),i.instance}async initialize(){try{await b.mkdir(D,{recursive:!0});try{await b.access(E)}catch{await this.writeUnprotectedConfig(P)}}catch(e){throw new Error(`Failed to initialize config: ${e instanceof Error?e.message:String(e)}`)}}async getConfig(){let e=await this.getUnprotectedConfig(),t=await this.getProtectedConfig();return{...e,...t}}async getUnprotectedConfig(){if(this.unprotectedConfig)return this.unprotectedConfig;try{let e=await b.readFile(E,"utf-8");return this.unprotectedConfig=this.parseToml(e),this.unprotectedConfig}catch{return this.unprotectedConfig={...P},this.unprotectedConfig}}async getProtectedConfig(){try{return{wallet_private_key:await F.getPassword(L,"wallet_private_key")||void 0}}catch{return{}}}async setConfig(e,t){this.isProtectedKey(e)?await this.setProtectedConfig(e,t):await this.setUnprotectedConfig(e,t)}async getConfigValue(e){return(await this.getConfig())[e]}async setUnprotectedConfig(e,t){let n=await this.getUnprotectedConfig();if(e==="network"&&!["vana","moksha"].includes(t))throw new Error(`Invalid network value: ${t}. Must be 'vana' or 'moksha'`);n[e]=t,await this.writeUnprotectedConfig(n),this.unprotectedConfig=n}async setProtectedConfig(e,t){try{await F.setPassword(L,e,t)}catch(n){throw new Error(`Failed to store ${e} in keyring: ${n instanceof Error?n.message:String(n)}`)}}async writeUnprotectedConfig(e){let t=this.generateToml(e);try{await b.mkdir(se(E),{recursive:!0}),await b.writeFile(E,t,"utf-8")}catch(n){throw new Error(`Failed to write config file: ${n instanceof Error?n.message:String(n)}`)}}isProtectedKey(e){return e==="wallet_private_key"}parseToml(e){let t={},n=e.split(`
|
|
3
|
+
`);for(let r of n){let o=r.trim();if(o&&!o.startsWith("#")){let[s,...u]=o.split("=");if(s&&u.length>0){let c=s.trim(),h=u.join("=").trim().replace(/['"]/g,"");(c==="network"||c==="rpc_endpoint"||c==="query_engine_endpoint")&&(t[c]=h)}}}return{...P,...t}}generateToml(e){return`# Vana CLI Configuration
|
|
4
4
|
# This file stores unprotected configuration values
|
|
5
5
|
# Secrets like private keys are stored securely in the OS keyring
|
|
6
6
|
|
|
7
7
|
network = "${e.network}"
|
|
8
8
|
rpc_endpoint = "${e.rpc_endpoint}"
|
|
9
9
|
query_engine_endpoint = "${e.query_engine_endpoint}"
|
|
10
|
-
`}getConfigKeys(){return{unprotected:["network","rpc_endpoint","query_engine_endpoint"],protected:["wallet_private_key"]}}async reset(){await this.writeUnprotectedConfig(
|
|
11
|
-
${
|
|
12
|
-
`+"\u2500".repeat(Math.min(
|
|
13
|
-
`;for(let[c
|
|
14
|
-
`);return s},examples(
|
|
15
|
-
`;for(let n of e)t+=
|
|
16
|
-
`;return t},nextSteps(
|
|
17
|
-
`;for(let t of
|
|
18
|
-
`;return e},troubleshooting(
|
|
19
|
-
`;for(let n of e)t+=
|
|
20
|
-
`;return t}};var
|
|
21
|
-
`)}error(e){this.context.stderr.write(
|
|
22
|
-
`)}warning(e){this.context.stderr.write(
|
|
23
|
-
`)}info(e){this.context.stdout.write(
|
|
10
|
+
`}getConfigKeys(){return{unprotected:["network","rpc_endpoint","query_engine_endpoint"],protected:["wallet_private_key"]}}async reset(){await this.writeUnprotectedConfig(P),this.unprotectedConfig=null;try{await F.deletePassword(L,"wallet_private_key")}catch{}}getConfigPath(){return E}};import p from"chalk";function m(i,e){return i==="wallet_private_key"&&e?e.length>10?e.substring(0,6)+"..."+e.substring(e.length-4):e.substring(0,4)+"..."+e.substring(e.length-2):e}function R(i){return["wallet_private_key","private_key","secret","password","token"].some(t=>i.toLowerCase().includes(t))}function a(i,e,t={}){let{maskSensitive:n=!1,indent:r=2}=t,o=" ".repeat(r);if(e===void 0)return`${o}${p.cyan(i)}: ${p.gray("(not set)")}`;let s=n&&R(i)?m(i,e):e;return`${o}${p.cyan(i)}: ${s}`}function M(i,e){let t=p.blue.bold(`
|
|
11
|
+
${i}:`);return e&&(t+=p.gray(` (${e})`)),t}function f(i){return p.bold(i)+`
|
|
12
|
+
`+"\u2500".repeat(Math.min(i.length,50))}function J(i){return p.green(`\u2713 ${i}`)}function K(i){return p.red(`\u2717 ${i}`)}function Q(i){return p.yellow(`\u26A0 ${i}`)}function B(i){return p.blue(`\u2139 ${i}`)}function H(i){return p.gray(i)}function ce(i){return p.gray(` $ ${i}`)}var g={configSection(i,e,t,n={}){let{maskSensitive:r=!1,showEmpty:o=!0}=n,s=M(i,e)+`
|
|
13
|
+
`;for(let[u,c]of Object.entries(t))(c!==void 0||o)&&(s+=a(u,c,{maskSensitive:r})+`
|
|
14
|
+
`);return s},examples(i,e){let t=M(i)+`
|
|
15
|
+
`;for(let n of e)t+=ce(n)+`
|
|
16
|
+
`;return t},nextSteps(i){let e=M("Next steps")+`
|
|
17
|
+
`;for(let t of i)e+=H(` \u2022 ${t}`)+`
|
|
18
|
+
`;return e},troubleshooting(i,e){let t=M(i)+`
|
|
19
|
+
`;for(let n of e)t+=H(` \u2022 ${n}`)+`
|
|
20
|
+
`;return t}};var N=class{constructor(e){this.context=e}success(e){this.context.stdout.write(J(e)+`
|
|
21
|
+
`)}error(e){this.context.stderr.write(K(e)+`
|
|
22
|
+
`)}warning(e){this.context.stderr.write(Q(e)+`
|
|
23
|
+
`)}info(e){this.context.stdout.write(B(e)+`
|
|
24
24
|
`)}log(e){this.context.stdout.write(e+`
|
|
25
|
-
`)}write(e){this.context.stdout.write(e)}},
|
|
26
|
-
Retrieves comprehensive
|
|
25
|
+
`)}write(e){this.context.stdout.write(e)}},d={configNotFound:i=>`Configuration key '${i}' not found`,invalidValue:(i,e,t)=>`Invalid value '${e}' for '${i}'${t?`. Expected: ${t}`:""}`,missingRequired:i=>`Missing required field: ${i}`,keyringAccess:i=>`Failed to ${i} keyring. Ensure your system keyring is accessible`,fileAccess:(i,e)=>`Failed to ${e} file: ${i}`,networkError:i=>`Network error connecting to: ${i}`,authenticationFailed:i=>`Authentication failed${i?`: ${i}`:""}`,permissionDenied:i=>`Permission denied accessing: ${i}`,unexpectedError:i=>`Unexpected error: ${i instanceof Error?i.message:String(i)}`},_={configSet:(i,e)=>`Set ${i} in ${e}`,configInitialized:()=>"Configuration initialized",configReset:()=>"Configuration reset to defaults",operationComplete:i=>`${i} completed successfully`},G={secretsCleared:()=>"Protected values (like private keys) have been cleared",keyringUnavailable:()=>"OS keyring unavailable, secrets cannot be stored securely",deprecatedOption:(i,e)=>`Option '${i}' is deprecated, use '${e}' instead`,experimentalFeature:i=>`${i} is experimental and may change in future versions`},w={configLocation:i=>`Config file: ${i}`,useSecretsFlag:()=>"Use --secrets to view protected values",interactiveMode:()=>"Interactive mode requires a prompt library like inquirer",nextSteps:{setPrivateKey:()=>"Set your wallet private key: vana config set wallet_private_key 63...",viewConfig:()=>"View all settings: vana config get",viewSecrets:()=>"View with secrets: vana config get --secrets"}};function v(i){return new N({stdout:i.stdout,stderr:i.stderr})}import W from"ora";var fe=["Verify the refiner ID exists","Check your private key is correct","Ensure the API URLs are accessible","Verify you have permission to view this refiner's stats"],U=class extends z{static paths=[["stats","refiner"]];static usage=z.Usage({category:"Stats",description:"Get comprehensive statistics for a specific refiner",details:`
|
|
26
|
+
Retrieves comprehensive statistics for a refiner from both services:
|
|
27
|
+
|
|
28
|
+
Query Engine Stats:
|
|
27
29
|
\u2022 File contributions and data rows
|
|
28
30
|
\u2022 Query execution metrics
|
|
29
31
|
\u2022 Error breakdowns by type
|
|
30
32
|
\u2022 Table-specific row counts
|
|
31
33
|
\u2022 Contributor and timing information
|
|
32
34
|
|
|
35
|
+
Refinement Service Stats:
|
|
36
|
+
\u2022 Job processing metrics
|
|
37
|
+
\u2022 Success/failure rates
|
|
38
|
+
\u2022 Processing times
|
|
39
|
+
\u2022 Error analysis
|
|
40
|
+
\u2022 Recent activity
|
|
41
|
+
|
|
33
42
|
Requires cryptographic authentication using your wallet private key.
|
|
34
|
-
`,examples:[["Get stats for refiner ID 45","vana stats refiner --id 45"],["Get stats with custom
|
|
43
|
+
`,examples:[["Get stats for refiner ID 45","vana stats refiner --id 45"],["Get stats with custom endpoints","vana stats refiner --id 45 --query-endpoint https://query-engine.api.com --refine-endpoint https://refine.api.com"],["Get stats with private key override","vana stats refiner --id 45 --private-key 63..."],["Get stats in JSON format","vana stats refiner --id 45 --json"],["Get verbose stats with raw response","vana stats refiner --id 45 --verbose --include-raw"]]});refinerId=k.String("--id,-i",{description:"Refiner ID to get statistics for",required:!0});privateKey=k.String("--private-key,-pk",{description:"Private key for authentication (overrides config)"});queryEndpoint=k.String("--query-endpoint,-qe",{description:"Query Engine API URL (optional if configured via config)"});refineEndpoint=k.String("--refine-endpoint,-re",{description:"Refinement Service API URL (optional if configured via config)"});json=k.Boolean("--json,-j",!1,{description:"Output in JSON format"});verbose=k.Boolean("--verbose,-v",!1,{description:"Show verbose output with additional details"});includeRaw=k.Boolean("--include-raw",!1,{description:"Include raw API responses in output"});async execute(){let e=v(this.context);try{let t=this.validateRefinerId(e);if(t===null)return 1;let{privateKey:n,queryApiUrl:r,refineApiUrl:o}=await this.getConfiguration(e);if(!n)return 1;this.verbose&&this.displayVerboseInfo(e,t,n,r,o);let s=await this.fetchCombinedStats(e,t,n,r,o);return!s.ingestion_stats&&!s.execution_stats?(e.warning("No data found for this refiner in either service"),this.displayNoDataMessage(e,t,s),0):(this.displayResults(e,s),e.success(_.operationComplete("Refiner stats retrieved")),this.verbose&&e.warning("\u26A0\uFE0F Alpha software: Verify all data independently before making decisions"),0)}catch(t){return e.error(d.unexpectedError(t)),e.write(g.troubleshooting("Troubleshooting",fe)),1}}validateRefinerId(e){let t=parseInt(this.refinerId);return isNaN(t)||t<0?(e.error("Invalid refiner ID. Must be a non-negative number."),null):t}async getConfiguration(e){let t=y.getInstance();await t.initialize();let n=this.privateKey;if(!n)try{n=await t.getConfigValue("wallet_private_key")}catch{}if(!n)return e.error("No private key provided."),e.write(g.examples("Set private key with",["vana config set wallet_private_key 63...","or use --private-key option"])),{privateKey:void 0,queryApiUrl:void 0,refineApiUrl:void 0};let r=this.queryEndpoint;if(!r)try{r=await t.getConfigValue("query_engine_endpoint")}catch{}let o=this.refineEndpoint;if(!o)try{o=await t.getConfigValue("refinement_service_endpoint")}catch{}return!r&&!o?(e.error("At least one API endpoint is required (Query Engine or Refinement Service)."),e.write(g.examples("Set API endpoints with",["vana config set query_engine_endpoint https://query-engine.api.com","vana config set refinement_service_endpoint https://refine.api.com","or use --query-endpoint and --refine-endpoint options"])),{privateKey:void 0,queryApiUrl:void 0,refineApiUrl:void 0}):{privateKey:n,queryApiUrl:r,refineApiUrl:o}}displayVerboseInfo(e,t,n,r,o){e.write(f("\u{1F50D} Comprehensive Refiner Statistics")+`
|
|
35
44
|
`),e.write(a("Refiner ID",t.toString())+`
|
|
36
|
-
`),e.write(a("API
|
|
37
|
-
`),e.write(a("
|
|
45
|
+
`),e.write(a("Query Engine API",r||"Not configured")+`
|
|
46
|
+
`),e.write(a("Refinement Service API",o||"Not configured")+`
|
|
47
|
+
`),e.write(a("Private Key",m("wallet_private_key",n))+`
|
|
48
|
+
`),e.write(`
|
|
49
|
+
`)}async fetchCombinedStats(e,t,n,r,o){let s={refiner_id:t,ingestion_stats:void 0,execution_stats:void 0};if(r){let u=W("Fetching ingestion stats from query engine...").start();try{let c=new $(r);s.ingestion_stats=await c.getRefinerIngestionStats(t,n),u.succeed("Ingestion stats retrieved")}catch(c){u.fail("Failed to fetch ingestion stats"),s.ingestion_error=c instanceof Error?c.message:String(c),e.warning(`Query Engine: ${s.ingestion_error}`)}}if(o){let u=W("Fetching execution stats from refinement service...").start();try{let c=new I(o);s.execution_stats=await c.getRefinerExecutionStats(t,n),u.succeed("Execution stats retrieved")}catch(c){u.fail("Failed to fetch execution stats"),s.execution_error=c instanceof Error?c.message:String(c),e.warning(`Refinement Service: ${s.execution_error}`)}}return s}displayNoDataMessage(e,t,n){e.write(f(`\u{1F4CA} Refiner ${t} - No Data Found`)+`
|
|
50
|
+
|
|
51
|
+
`),e.write(`\u{1F50D} Data Availability:
|
|
52
|
+
`),n.ingestion_error?e.write(` Query Engine: \u274C ${n.ingestion_error}
|
|
53
|
+
`):n.ingestion_stats?e.write(` Query Engine: \u2705 Connected (no data ingested)
|
|
54
|
+
`):e.write(` Query Engine: \u26AA Not configured
|
|
55
|
+
`),n.execution_error?e.write(` Refinement Service: \u274C ${n.execution_error}
|
|
56
|
+
`):n.execution_stats?e.write(` Refinement Service: \u2705 Connected (no jobs processed)
|
|
57
|
+
`):e.write(` Refinement Service: \u26AA Not configured
|
|
38
58
|
`),e.write(`
|
|
39
|
-
|
|
59
|
+
\u{1F4A1} This could mean:
|
|
60
|
+
`),e.write(` \u2022 The refiner ID doesn't exist
|
|
61
|
+
`),e.write(` \u2022 The refiner hasn't processed any data or jobs yet
|
|
62
|
+
`),e.write(` \u2022 You don't have permission to view this refiner's stats
|
|
63
|
+
`),e.write(` \u2022 One or both services are not configured
|
|
64
|
+
`)}displayResults(e,t){this.json?e.write(JSON.stringify(t,null,2)+`
|
|
40
65
|
`):this.displayFormattedStats(e,t),this.includeRaw&&!this.json&&(e.write(`
|
|
41
|
-
`+f("\u{1F4C4} Raw API
|
|
66
|
+
`+f("\u{1F4C4} Raw API Responses")+`
|
|
42
67
|
`),e.write(JSON.stringify(t,null,2)+`
|
|
43
|
-
`))}displayFormattedStats(e,t){e.write(f(`\u{1F4CA} Refiner ${t.refiner_id} -
|
|
68
|
+
`))}displayFormattedStats(e,t){e.write(f(`\u{1F4CA} Refiner ${t.refiner_id} - Comprehensive Statistics`)+`
|
|
44
69
|
|
|
45
|
-
`),
|
|
46
|
-
|
|
70
|
+
`),t.execution_stats?this.displayJobExecutionStats(e,t.execution_stats):(e.write(`
|
|
71
|
+
`+f("\u2699\uFE0F Refiner Execution (Refinement Service)")+`
|
|
72
|
+
`),e.write(`\u26AA No execution data available
|
|
73
|
+
`),t.execution_error&&e.write(`\u274C Error: ${t.execution_error}
|
|
74
|
+
`)),t.ingestion_stats?this.displayDataIngestionStats(e,t.ingestion_stats):(e.write(f("\u{1F4C1} Data Ingestion")+`
|
|
75
|
+
`),e.write(`\u26AA No ingestion data available
|
|
76
|
+
`),t.ingestion_error&&e.write(`\u274C Error: ${t.ingestion_error}
|
|
77
|
+
`)),t.ingestion_stats&&this.displayQueryExecutionStats(e,t.ingestion_stats),this.displayCombinedErrorAnalysis(e,t),this.verbose&&this.displayTechnicalDetails(e,t)}displayDataIngestionStats(e,t){if(e.write(f("\u{1F4C1} Data Ingestion")+`
|
|
78
|
+
`),t.total_file_contributions===0){e.write(`\u26AA No data has been ingested yet
|
|
79
|
+
`);return}e.write(a("File Contributions",t.total_file_contributions.toLocaleString())+`
|
|
47
80
|
`),e.write(a("Total Data Rows",t.total_data_rows.toLocaleString())+`
|
|
48
81
|
`),e.write(a("Unique Contributors",t.unique_contributors.toLocaleString())+`
|
|
49
82
|
`),t.first_ingestion_at&&e.write(a("First Ingestion",new Date(t.first_ingestion_at).toLocaleString())+`
|
|
50
83
|
`),t.last_ingestion_at&&e.write(a("Last Ingestion",new Date(t.last_ingestion_at).toLocaleString())+`
|
|
51
84
|
`),t.ingestion_period_days&&e.write(a("Ingestion Period",`${t.ingestion_period_days.toFixed(1)} days`)+`
|
|
52
85
|
`),e.write(a("Avg Rate/Hour",t.average_ingestion_rate_per_hour.toFixed(2))+`
|
|
53
|
-
`)
|
|
86
|
+
`),Object.keys(t.rows_per_table).length>0&&(e.write(`
|
|
87
|
+
`+f("\u{1F4CB} Rows per Table")+`
|
|
88
|
+
`),Object.entries(t.rows_per_table).sort(([,n],[,r])=>r-n).forEach(([n,r])=>{e.write(a(n,r.toLocaleString())+`
|
|
89
|
+
`)}))}displayJobExecutionStats(e,t){if(e.write(f("\u2699\uFE0F Refiner Execution (Refinement Service)")+`
|
|
90
|
+
`),t.total_jobs===0){e.write(`\u26AA No jobs have been processed yet
|
|
91
|
+
`);return}if(e.write(a("Total Jobs",t.total_jobs.toLocaleString())+`
|
|
92
|
+
`),e.write(a("Successful",t.successful_jobs.toLocaleString())+`
|
|
93
|
+
`),e.write(a("Failed",t.failed_jobs.toLocaleString())+`
|
|
94
|
+
`),e.write(a("Currently Processing",t.processing_jobs.toLocaleString())+`
|
|
95
|
+
`),e.write(a("In Queue",t.submitted_jobs.toLocaleString())+`
|
|
96
|
+
`),t.total_jobs>0){let n=(t.success_rate*100).toFixed(1);e.write(a("Success Rate",`${n}%`)+`
|
|
97
|
+
`)}t.average_processing_time_seconds>0&&e.write(a("Avg Processing Time",`${t.average_processing_time_seconds.toFixed(1)}s`)+`
|
|
98
|
+
`),t.jobs_per_hour>0&&e.write(a("Jobs per Hour",t.jobs_per_hour.toFixed(2))+`
|
|
99
|
+
`),t.first_job_at&&e.write(a("First Job",new Date(t.first_job_at).toLocaleString())+`
|
|
100
|
+
`),t.last_job_at&&e.write(a("Last Job",new Date(t.last_job_at).toLocaleString())+`
|
|
101
|
+
`),t.processing_period_days&&e.write(a("Processing Period",`${t.processing_period_days.toFixed(1)} days`)+`
|
|
102
|
+
`),e.write(`
|
|
103
|
+
`)}displayQueryExecutionStats(e,t){if(t.total_queries_executed!==0&&(e.write(`
|
|
54
104
|
`+f("\u{1F50D} Query Execution")+`
|
|
55
105
|
`),e.write(a("Total Queries",t.total_queries_executed.toLocaleString())+`
|
|
56
106
|
`),e.write(a("Successful",t.successful_queries.toLocaleString())+`
|
|
57
107
|
`),e.write(a("Failed",t.failed_queries.toLocaleString())+`
|
|
58
|
-
`),t.total_queries_executed>0){let n=(t.successful_queries/t.total_queries_executed*100).toFixed(1);e.write(a("Success Rate",`${n}%`)+`
|
|
59
|
-
`)}}
|
|
60
|
-
`+f("\u274C
|
|
61
|
-
`),
|
|
62
|
-
`)
|
|
63
|
-
|
|
64
|
-
`),Object.entries(t.
|
|
65
|
-
`)}))
|
|
108
|
+
`),t.total_queries_executed>0)){let n=(t.successful_queries/t.total_queries_executed*100).toFixed(1);e.write(a("Success Rate",`${n}%`)+`
|
|
109
|
+
`)}}displayCombinedErrorAnalysis(e,t){let n=t.ingestion_stats&&Object.keys(t.ingestion_stats.query_errors_by_type).length>0,r=t.execution_stats&&Object.keys(t.execution_stats.error_types).length>0;!n&&!r||(e.write(`
|
|
110
|
+
`+f("\u274C Error Analysis")+`
|
|
111
|
+
`),n&&(e.write(`Query Errors:
|
|
112
|
+
`),Object.entries(t.ingestion_stats.query_errors_by_type).sort(([,o],[,s])=>s-o).forEach(([o,s])=>{e.write(` ${a(o,s.toLocaleString())}
|
|
113
|
+
`)})),r&&(e.write(`Execution Errors:
|
|
114
|
+
`),Object.entries(t.execution_stats.error_types).sort(([,o],[,s])=>s-o).forEach(([o,s])=>{e.write(` ${a(o,s.toLocaleString())}
|
|
115
|
+
`)})),t.execution_stats&&t.execution_stats.recent_errors.length>0&&(e.write(`
|
|
116
|
+
Recent Execution Errors:
|
|
117
|
+
`),t.execution_stats.recent_errors.slice(0,3).forEach((o,s)=>{e.write(` ${s+1}. ${o.error}
|
|
118
|
+
`),e.write(` ${new Date(o.timestamp).toLocaleString()}
|
|
119
|
+
`),o.job_id&&e.write(` Job ID: ${o.job_id}
|
|
120
|
+
`)})))}displayTechnicalDetails(e,t){e.write(`
|
|
66
121
|
`+f("\u{1F527} Technical Details")+`
|
|
67
|
-
`),t.last_processed_block&&e.write(a("Last Processed Block",t.last_processed_block.toLocaleString())+`
|
|
68
|
-
`)
|
|
122
|
+
`),t.ingestion_stats?.last_processed_block&&e.write(a("Last Processed Block",t.ingestion_stats.last_processed_block.toLocaleString())+`
|
|
123
|
+
`),t.execution_stats&&e.write(a("Service Status","Connected")+`
|
|
124
|
+
`),t.ingestion_stats&&e.write(a("Query Engine Status","Connected")+`
|
|
125
|
+
`)}};import{Command as X,Option as A}from"clipanion";var T=class extends X{static paths=[["config","get"]];static usage=X.Usage({category:"Configuration",description:"Get configuration values",details:`
|
|
69
126
|
Get configuration values from the Vana CLI config.
|
|
70
127
|
|
|
71
128
|
By default, only unprotected values are shown.
|
|
@@ -76,10 +133,10 @@ ${r}:`);return e&&(t+=l.gray(` (${e})`)),t}function f(r){return l.bold(r)+`
|
|
|
76
133
|
$ vana config get network # Show specific key
|
|
77
134
|
$ vana config get --secrets # Show all config including secrets
|
|
78
135
|
$ vana config get --json # Output as JSON
|
|
79
|
-
`});key=
|
|
80
|
-
`)}else{let
|
|
81
|
-
`)}else this.displayConfig(n,e,t)}return 0}catch(t){return e.error(
|
|
82
|
-
`);let
|
|
136
|
+
`});key=A.String({required:!1});secrets=A.Boolean("--secrets",!1,{description:"Include protected values from keyring"});json=A.Boolean("--json",!1,{description:"Output as JSON"});async execute(){let e=v(this.context);try{let t=y.getInstance();if(await t.initialize(),this.key){let n=await t.getConfigValue(this.key);if(n===void 0)return e.error(d.configNotFound(this.key)),1;if(this.json){let r=!this.secrets&&R(this.key)?m(this.key,n):n;e.write(JSON.stringify({[this.key]:r},null,2)+`
|
|
137
|
+
`)}else{let r=!this.secrets&&R(this.key)?m(this.key,n):n;e.log(`${this.key}: ${r}`)}}else{let n;if(this.secrets?n=await t.getConfig():n=await t.getUnprotectedConfig(),this.json){let r={...n};if(!this.secrets)for(let[o,s]of Object.entries(r))typeof s=="string"&&R(o)&&(r[o]=m(o,s));e.write(JSON.stringify(r,null,2)+`
|
|
138
|
+
`)}else this.displayConfig(n,e,t)}return 0}catch(t){return e.error(d.unexpectedError(t)),1}}displayConfig(e,t,n){t.write(f("Vana CLI Configuration")+`
|
|
139
|
+
`);let r=n.getConfigKeys(),o={};for(let s of r.unprotected)o[s]=e[s];if(t.write(g.configSection("Unprotected","stored in ~/.vana/cli.config.toml",o,{maskSensitive:!1,showEmpty:!1})),this.secrets){let s={};for(let u of r.protected)s[u]=e[u];t.write(g.configSection("Protected","stored in OS keyring",s,{maskSensitive:!0,showEmpty:!0}))}else t.info(w.useSecretsFlag());t.info(w.configLocation(n.getConfigPath()))}};import{Command as Y,Option as O}from"clipanion";import ue from"ora";var q=class extends Y{static paths=[["config","set"]];static usage=Y.Usage({category:"Configuration",description:"Set configuration values",details:`
|
|
83
140
|
Set configuration values for the Vana CLI.
|
|
84
141
|
|
|
85
142
|
Unprotected values are stored in ~/.vana/cli.config.toml
|
|
@@ -95,9 +152,9 @@ ${r}:`);return e&&(t+=l.gray(` (${e})`)),t}function f(r){return l.bold(r)+`
|
|
|
95
152
|
$ vana config set rpc_endpoint https://rpc.moksha.vana.org
|
|
96
153
|
$ vana config set wallet_private_key 0x1234...
|
|
97
154
|
$ vana config set --interactive
|
|
98
|
-
`});key=
|
|
155
|
+
`});key=O.String({required:!1});value=O.String({required:!1});interactive=O.Boolean("--interactive",!1,{description:"Interactive configuration setup"});quiet=O.Boolean("--quiet",!1,{description:"Suppress output messages"});async execute(){let e=v(this.context);try{let t=y.getInstance();if(await t.initialize(),this.interactive)return await this.runInteractiveSetup(t,e);if(!this.key||!this.value)return e.error(d.missingRequired("key and value")),e.info("Usage: vana config set <key> <value>"),e.info("Or use: vana config set --interactive"),1;let n=ue("Setting configuration...").start();try{if(await t.setConfig(this.key,this.value),n.succeed(),!this.quiet){let o=this.isProtectedKey(this.key)?"OS keyring":"~/.vana/cli.config.toml";e.success(_.configSet(this.key,o))}return 0}catch(r){throw n.fail(),r}}catch(t){return e.error(d.unexpectedError(t)),1}}async runInteractiveSetup(e,t){t.write(f("\u{1F527} Vana CLI Interactive Configuration")+`
|
|
99
156
|
|
|
100
|
-
`);try{let n=await e.getConfig(),
|
|
157
|
+
`);try{let n=await e.getConfig(),r={network:n.network,rpc_endpoint:n.rpc_endpoint},o={wallet_private_key:n.wallet_private_key};return t.write(g.configSection("Current Configuration","unprotected values",r,{maskSensitive:!1,showEmpty:!0})),t.write(g.configSection("Protected Configuration","stored in keyring",o,{maskSensitive:!0,showEmpty:!0})),t.warning(w.interactiveMode()),t.info("Use: vana config set <key> <value> to set individual values"),t.write(g.examples("Example commands",["vana config set network moksha","vana config set rpc_endpoint https://rpc.moksha.vana.org","vana config set wallet_private_key 63..."])),0}catch(n){return t.error(d.unexpectedError(n)),1}}isProtectedKey(e){return e==="wallet_private_key"}};import{Command as Z,Option as ee}from"clipanion";import te from"ora";var j=class extends Z{static paths=[["config","init"]];static usage=Z.Usage({category:"Configuration",description:"Initialize configuration with defaults",details:`
|
|
101
158
|
Initialize the Vana CLI configuration with default values.
|
|
102
159
|
|
|
103
160
|
Default configuration:
|
|
@@ -110,7 +167,7 @@ ${r}:`);return e&&(t+=l.gray(` (${e})`)),t}function f(r){return l.bold(r)+`
|
|
|
110
167
|
Examples:
|
|
111
168
|
$ vana config init # Initialize with defaults
|
|
112
169
|
$ vana config init --reset # Reset existing config to defaults
|
|
113
|
-
`});reset=
|
|
170
|
+
`});reset=ee.Boolean("--reset",!1,{description:"Reset existing configuration to defaults"});quiet=ee.Boolean("--quiet",!1,{description:"Suppress output messages"});async execute(){let e=v(this.context);try{let t=y.getInstance();if(this.reset){let n=te("Resetting configuration to defaults...").start();try{await t.reset(),n.succeed(),this.quiet||(e.success(_.configReset()),e.warning(G.secretsCleared()))}catch(r){throw n.fail(),r}}else{let n=te("Initializing configuration...").start();try{await t.initialize(),n.succeed(),this.quiet||(e.success(_.configInitialized()),e.warning("\u26A0\uFE0F This is alpha software - only use for testing/development"))}catch(r){throw n.fail(),r}}if(!this.quiet){let n=await t.getUnprotectedConfig();e.write(`
|
|
114
171
|
`+f("Current Configuration")+`
|
|
115
|
-
`);let
|
|
116
|
-
`)));var
|
|
172
|
+
`);let r={network:n.network,rpc_endpoint:n.rpc_endpoint};e.write(g.configSection("Configuration","unprotected values",r,{maskSensitive:!1,showEmpty:!0})),e.info(w.configLocation(t.getConfigPath())),e.write(g.nextSteps([w.nextSteps.setPrivateKey(),w.nextSteps.viewConfig(),w.nextSteps.viewSecrets()]))}return 0}catch(t){return e.error(d.unexpectedError(t)),1}}};import ne from"chalk";import{readFileSync as pe}from"fs";import{fileURLToPath as le}from"url";import{dirname as de,join as ye}from"path";var we=le(import.meta.url),ve=de(we),he=JSON.parse(pe(ye(ve,"../package.json"),"utf-8")),[lt,dt,...x]=process.argv;x.length>0&&!x.includes("--help")&&!x.includes("-h")&&!x.includes("--version")&&!x.includes("-v")&&(console.error(ne.yellow("\u26A0\uFE0F ALPHA SOFTWARE - Use only for testing/development")),console.error(ne.gray(` Not suitable for production use. Features may change without notice.
|
|
173
|
+
`)));var C=new ge({binaryLabel:"Vana CLI (Alpha)",binaryName:"vana",binaryVersion:he.version});C.register(ie.HelpCommand);C.register(ie.VersionCommand);C.register(T);C.register(q);C.register(j);C.register(U);await C.runExit(x,{stdin:process.stdin,stdout:process.stdout});
|