@gns-foundation/hive-worker 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,87 @@
1
+ # GEIANT Hive Worker
2
+
3
+ **Turn your laptop into an AI compute node. Earn GNS tokens.**
4
+
5
+ ```bash
6
+ npx @gns-foundation/hive-worker join
7
+ ```
8
+
9
+ That's it. One command. Your device joins the GEIANT Hive swarm, contributes idle CPU/GPU cycles to AI inference jobs, and earns [GNS tokens](https://gcrumbs.com) automatically.
10
+
11
+ ---
12
+
13
+ ## What it does
14
+
15
+ - Generates a persistent Ed25519 identity (stored at `~/.hive/identity.json`)
16
+ - Detects your hardware: CPU, GPU, RAM, estimated TFLOPS
17
+ - Resolves your location to an [H3 geospatial cell](https://h3geo.org) (Res-6, ~36 km²)
18
+ - Registers you in the GEIANT Hive swarm registry
19
+ - Starts a `llama.cpp` RPC server if available (handles AI model shards)
20
+ - Sends a heartbeat every 30 seconds to stay active in the swarm
21
+ - Disconnects cleanly on Ctrl+C
22
+
23
+ ## Commands
24
+
25
+ ```bash
26
+ # Join the swarm (with optional GNS handle)
27
+ npx @gns-foundation/hive-worker join --handle @yourname
28
+
29
+ # Join without starting the RPC server (observer mode)
30
+ npx @gns-foundation/hive-worker join --no-rpc
31
+
32
+ # Check swarm status and your token balance
33
+ npx @gns-foundation/hive-worker status
34
+
35
+ # Show your identity
36
+ npx @gns-foundation/hive-worker whoami
37
+
38
+ # Disconnect gracefully
39
+ npx @gns-foundation/hive-worker leave
40
+ ```
41
+
42
+ ## Compute contribution
43
+
44
+ For full compute participation, install [llama.cpp](https://github.com/ggerganov/llama.cpp):
45
+
46
+ ```bash
47
+ # macOS (Apple Silicon)
48
+ brew install llama.cpp
49
+
50
+ # From source
51
+ git clone https://github.com/ggerganov/llama.cpp
52
+ cd llama.cpp && make rpc-server
53
+ ```
54
+
55
+ The worker detects the binary automatically and starts it on port `50052`. Without it, you join as an observer node (still registered in the swarm, no inference workloads routed to you).
56
+
57
+ ## Revenue split
58
+
59
+ Every inference job processed by the Hive distributes GNS tokens automatically:
60
+
61
+ | Slice | Recipient |
62
+ |-------|-----------|
63
+ | 60% | Community node operators (you) |
64
+ | 25% | GEIANT / ULISSY s.r.l. (orchestration) |
65
+ | 10% | Hydration & Resilience Fund |
66
+ | 5% | Sovereign Quorum coordinators |
67
+
68
+ Your share is weighted by trust tier (breadcrumb history) and thermal stability score.
69
+
70
+ ## Privacy
71
+
72
+ - Your Ed25519 private key **never leaves your machine** (`~/.hive/identity.json`, mode 600)
73
+ - Location is derived from IP geolocation (city-level, no GPS)
74
+ - Inference workloads are encrypted in transit (NaCl)
75
+ - You can `leave` and rejoin at any time — your identity and earnings persist
76
+
77
+ ## System requirements
78
+
79
+ - Node.js ≥ 18
80
+ - Any OS (macOS, Linux, Windows)
81
+ - Internet connection
82
+ - Optional: `llama.cpp` rpc-server for compute participation
83
+
84
+ ---
85
+
86
+ Built on [GNS Protocol](https://gcrumbs.com) · [GEIANT](https://geiant.com) · [Whitepaper](https://geiant.com/hive)
87
+ Contact: cayerbe@ulissy.app · USPTO #63/948,788
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,355 @@
1
+ #!/usr/bin/env node
2
+ // ============================================================
3
+ // HIVE WORKER CLI
4
+ // Usage:
5
+ // npx @gns-foundation/hive-worker join [--handle <@name>] [--rpc-port <port>]
6
+ // npx @gns-foundation/hive-worker status
7
+ // npx @gns-foundation/hive-worker leave
8
+ // npx @gns-foundation/hive-worker whoami
9
+ // npx @gns-foundation/hive-worker models list
10
+ // npx @gns-foundation/hive-worker models fetch <model-id>
11
+ // ============================================================
12
+ import { program } from 'commander';
13
+ import { loadOrCreateIdentity, shortPk, identityPath } from './identity.js';
14
+ import { detectHardware, detectGeo } from './hardware.js';
15
+ import { registerNode, heartbeat, deregisterNode, fetchSwarmStats, fetchTokenBalance } from './registry.js';
16
+ import { findRpcBinary, startRpcServer, stopRpcServer, DEFAULT_RPC_PORT } from './llama.js';
17
+ import { printBanner, printSuccess, printInfo, printWarn, printError, renderDashboard, clearDashboard, hideCursor, } from './dashboard.js';
18
+ import { startJobPoller } from './jobs.js';
19
+ import { executeJob, downloadModel, listCachedModels, resolveModelUrl, findLlamaCli } from './executor.js';
20
+ import { creditWorker, SPLIT } from './settlement.js';
21
+ const HEARTBEAT_INTERVAL_MS = 30_000;
22
+ const STATS_REFRESH_INTERVAL_MS = 60_000;
23
+ const DASHBOARD_REFRESH_MS = 3_000;
24
+ const JOB_POLL_INTERVAL_MS = 5_000; // poll for new jobs every 5s
25
+ // ─── JOIN command ─────────────────────────────────────────────
26
+ async function cmdJoin(opts) {
27
+ printBanner();
28
+ // 1. Identity
29
+ const { identity, isNew } = loadOrCreateIdentity();
30
+ if (isNew) {
31
+ printSuccess(`New identity generated: ${shortPk(identity.pk)}`);
32
+ printInfo(`Stored at ${identityPath()}`);
33
+ }
34
+ else {
35
+ printSuccess(`Identity loaded: ${shortPk(identity.pk)}`);
36
+ }
37
+ // 2. Handle
38
+ const handle = opts.handle?.replace(/^@/, '') ?? null;
39
+ if (handle)
40
+ printSuccess(`Handle: @${handle}`);
41
+ else
42
+ printInfo('No handle — use --handle @yourname to claim one.');
43
+ // 3. Hardware
44
+ printInfo('Detecting hardware...');
45
+ const hw = detectHardware();
46
+ printSuccess(`${hw.cpuCores}-core ${hw.arch} · ${hw.ramGb} GB RAM · ~${hw.estimatedTflops} TFLOPS`);
47
+ if (hw.gpuModel)
48
+ printSuccess(`GPU: ${hw.gpuModel}`);
49
+ // 4. Geo
50
+ printInfo('Detecting location...');
51
+ const geo = await detectGeo();
52
+ printSuccess(`Location: ${geo.city}, ${geo.country} · H3 cell ${geo.h3Cell.slice(0, 10)}…`);
53
+ // 5. llama-cli check (for job execution)
54
+ const llamaCliAvailable = !!findLlamaCli();
55
+ if (!opts.noJobs) {
56
+ if (llamaCliAvailable) {
57
+ printSuccess('llama-cli found — job execution enabled');
58
+ }
59
+ else {
60
+ printWarn('llama-cli not found — joining as observer (no inference jobs).');
61
+ printWarn('Install llama.cpp to earn GNS: https://github.com/ggerganov/llama.cpp');
62
+ }
63
+ }
64
+ // logs declared early so the rpc-server callback can reference it immediately
65
+ const logs = [`Joined at ${new Date().toISOString()}`];
66
+ // 6. RPC server (for pipeline/shard mode)
67
+ let rpcHandle = null;
68
+ const rpcBinary = findRpcBinary();
69
+ const rpcPort = opts.noRpc ? null : parseInt(opts.rpcPort ?? String(DEFAULT_RPC_PORT), 10);
70
+ if (opts.noRpc !== true && rpcBinary) {
71
+ printInfo(`Starting llama.cpp rpc-server on :${rpcPort}...`);
72
+ rpcHandle = startRpcServer(rpcPort, (line) => logs.push(line));
73
+ if (rpcHandle)
74
+ printSuccess(`RPC server PID ${rpcHandle.pid} on :${rpcPort}`);
75
+ }
76
+ else if (opts.noRpc !== true) {
77
+ printWarn('rpc-server not found — pipeline mode disabled.');
78
+ }
79
+ // 7. Register
80
+ printInfo('Registering with GEIANT Hive swarm...');
81
+ try {
82
+ await registerNode(identity, hw, geo, handle, rpcHandle?.port ?? null);
83
+ printSuccess('Registered in swarm registry');
84
+ }
85
+ catch (err) {
86
+ printError(`Registration failed: ${err instanceof Error ? err.message : String(err)}`);
87
+ printWarn('Continuing in offline mode — will retry on heartbeat');
88
+ }
89
+ // 8. Initial stats
90
+ let swarmStats = await fetchSwarmStats();
91
+ let tokensEarned = await fetchTokenBalance(identity.pk);
92
+ printSuccess(`Swarm: ${swarmStats.activeNodes} active nodes · ${swarmStats.totalTflops} TFLOPS`);
93
+ // Cached models
94
+ const cachedModels = listCachedModels();
95
+ if (cachedModels.length > 0) {
96
+ printSuccess(`Models cached: ${cachedModels.map(m => m.modelId).join(', ')}`);
97
+ }
98
+ else if (!opts.noJobs && llamaCliAvailable) {
99
+ printWarn('No models cached. Fetch one: hive-worker models fetch phi-3-mini');
100
+ }
101
+ console.log('');
102
+ printInfo('Entering live mode. Press Ctrl+C to disconnect.\n');
103
+ // ─── Live state ───────────────────────────────────────────────
104
+ hideCursor();
105
+ const startTime = Date.now();
106
+ let heartbeatCount = 0;
107
+ let lastHeartbeat = null;
108
+ let jobsCompleted = 0;
109
+ const addLog = (msg) => {
110
+ logs.push(`[${new Date().toLocaleTimeString()}] ${msg}`);
111
+ if (logs.length > 50)
112
+ logs.splice(0, logs.length - 50);
113
+ };
114
+ const state = {
115
+ pk: identity.pk,
116
+ handle,
117
+ status: 'idle',
118
+ hw,
119
+ geo,
120
+ rpcPort: rpcHandle?.port ?? null,
121
+ rpcAvailable: !!rpcBinary,
122
+ tokensEarned,
123
+ swarmStats,
124
+ uptimeSeconds: 0,
125
+ heartbeatCount: 0,
126
+ lastHeartbeat: null,
127
+ logs,
128
+ };
129
+ // ─── Heartbeat timer ─────────────────────────────────────────
130
+ const heartbeatTimer = setInterval(async () => {
131
+ try {
132
+ await heartbeat(identity.pk, state.status);
133
+ heartbeatCount++;
134
+ lastHeartbeat = new Date();
135
+ state.heartbeatCount = heartbeatCount;
136
+ state.lastHeartbeat = lastHeartbeat;
137
+ addLog(`Heartbeat #${heartbeatCount}`);
138
+ }
139
+ catch (err) {
140
+ addLog(`Heartbeat error: ${err instanceof Error ? err.message : String(err)}`);
141
+ }
142
+ }, HEARTBEAT_INTERVAL_MS);
143
+ // ─── Stats refresh timer ─────────────────────────────────────
144
+ const statsTimer = setInterval(async () => {
145
+ try {
146
+ swarmStats = await fetchSwarmStats();
147
+ tokensEarned = await fetchTokenBalance(identity.pk);
148
+ state.swarmStats = swarmStats;
149
+ state.tokensEarned = tokensEarned;
150
+ }
151
+ catch { /* non-fatal */ }
152
+ }, STATS_REFRESH_INTERVAL_MS);
153
+ // ─── Job polling loop ─────────────────────────────────────────
154
+ let jobPoller = null;
155
+ if (!opts.noJobs && (llamaCliAvailable || cachedModels.length > 0)) {
156
+ jobPoller = startJobPoller({
157
+ workerPk: identity.pk,
158
+ h3Cell: geo.h3Cell,
159
+ intervalMs: JOB_POLL_INTERVAL_MS,
160
+ onJobClaimed: (job) => {
161
+ state.status = 'computing';
162
+ addLog(`Job claimed: ${job.id.slice(0, 8)} · model=${job.model_id} · ${job.max_tokens} tokens`);
163
+ },
164
+ onJobCompleted: (job, result) => {
165
+ state.status = 'idle';
166
+ jobsCompleted++;
167
+ addLog(`Job ${job.id.slice(0, 8)} done · ${result.tokensPerSecond} tok/s · ` +
168
+ `earned ${(job.gns_reward * SPLIT.WORKER).toFixed(4)} GNS`);
169
+ // Optimistic local credit (server-side Stellar TX is async)
170
+ state.tokensEarned += job.gns_reward * SPLIT.WORKER;
171
+ // Kick off background settlement
172
+ creditWorker(identity.pk, job.id, job.gns_reward)
173
+ .then(rec => {
174
+ if (rec.stellarTxHash) {
175
+ addLog(`Settled · TX ${rec.stellarTxHash.slice(0, 12)}…`);
176
+ }
177
+ })
178
+ .catch(err => addLog(`Settlement error: ${err instanceof Error ? err.message : String(err)}`));
179
+ },
180
+ onJobFailed: (job, error) => {
181
+ state.status = 'idle';
182
+ addLog(`Job ${job.id.slice(0, 8)} failed: ${error.slice(0, 60)}`);
183
+ },
184
+ onLog: addLog,
185
+ executor: async (job) => {
186
+ return executeJob(job, {
187
+ onToken: (_tok) => { },
188
+ onLog: addLog,
189
+ });
190
+ },
191
+ });
192
+ addLog('Job poller started — polling every 5s');
193
+ }
194
+ else if (opts.noJobs) {
195
+ addLog('Job execution disabled (--no-jobs flag)');
196
+ }
197
+ else {
198
+ addLog('Observer mode — install llama.cpp + fetch a model to execute jobs');
199
+ }
200
+ // ─── Dashboard refresh ────────────────────────────────────────
201
+ const dashTimer = setInterval(() => {
202
+ state.uptimeSeconds = Math.floor((Date.now() - startTime) / 1000);
203
+ renderDashboard(state);
204
+ }, DASHBOARD_REFRESH_MS);
205
+ renderDashboard(state);
206
+ // ─── Graceful shutdown ────────────────────────────────────────
207
+ const shutdown = async (signal) => {
208
+ clearInterval(heartbeatTimer);
209
+ clearInterval(statsTimer);
210
+ clearInterval(dashTimer);
211
+ jobPoller?.stop();
212
+ clearDashboard();
213
+ console.log('\n');
214
+ printInfo(`Received ${signal}. Disconnecting gracefully...`);
215
+ try {
216
+ await deregisterNode(identity.pk);
217
+ printSuccess('Marked offline in swarm registry');
218
+ }
219
+ catch { /* best-effort */ }
220
+ if (rpcHandle) {
221
+ stopRpcServer(rpcHandle);
222
+ printSuccess('RPC server stopped');
223
+ }
224
+ const earned = await fetchTokenBalance(identity.pk).catch(() => state.tokensEarned);
225
+ printSuccess(`Session complete · ${jobsCompleted} jobs · ${earned.toFixed(4)} GNS earned`);
226
+ console.log('');
227
+ process.exit(0);
228
+ };
229
+ process.on('SIGINT', () => shutdown('SIGINT'));
230
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
231
+ }
232
+ // ─── STATUS command ───────────────────────────────────────────
233
+ async function cmdStatus() {
234
+ printBanner();
235
+ const { identity } = loadOrCreateIdentity();
236
+ printInfo(`Identity: ${shortPk(identity.pk)}`);
237
+ const stats = await fetchSwarmStats();
238
+ const tokens = await fetchTokenBalance(identity.pk);
239
+ printInfo(`Swarm: ${stats.activeNodes} active nodes · ${stats.totalTflops} TFLOPS`);
240
+ printInfo(`GNS earned: ${tokens.toFixed(4)}`);
241
+ const models = listCachedModels();
242
+ if (models.length > 0) {
243
+ printInfo(`Cached models: ${models.map(m => `${m.modelId} (${m.sizeMb} MB)`).join(', ')}`);
244
+ }
245
+ else {
246
+ printWarn('No models cached. Run: hive-worker models fetch phi-3-mini');
247
+ }
248
+ const llamaCli = findLlamaCli();
249
+ const rpcBin = findRpcBinary();
250
+ printInfo(`llama-cli: ${llamaCli ?? 'not found'}`);
251
+ printInfo(`rpc-server: ${rpcBin ?? 'not found'}`);
252
+ }
253
+ // ─── LEAVE command ────────────────────────────────────────────
254
+ async function cmdLeave() {
255
+ printBanner();
256
+ const { identity } = loadOrCreateIdentity();
257
+ printInfo(`Deregistering ${shortPk(identity.pk)} from swarm...`);
258
+ await deregisterNode(identity.pk);
259
+ printSuccess('Marked offline. Identity preserved at ' + identityPath());
260
+ printInfo('Run `hive-worker join` to rejoin.');
261
+ }
262
+ // ─── WHOAMI command ───────────────────────────────────────────
263
+ async function cmdWhoami() {
264
+ const { identity, isNew } = loadOrCreateIdentity();
265
+ if (isNew)
266
+ printWarn('No identity found — a new one was just generated.');
267
+ console.log('');
268
+ console.log(` pk: ${identity.pk}`);
269
+ console.log(` short: ${shortPk(identity.pk)}`);
270
+ console.log(` created: ${identity.createdAt}`);
271
+ console.log(` file: ${identityPath()}`);
272
+ console.log('');
273
+ }
274
+ // ─── MODELS LIST command ──────────────────────────────────────
275
+ async function cmdModelsList() {
276
+ const cached = listCachedModels();
277
+ console.log('');
278
+ if (cached.length === 0) {
279
+ printWarn('No models cached yet.');
280
+ printInfo('Fetch one: hive-worker models fetch phi-3-mini');
281
+ }
282
+ else {
283
+ printSuccess(`${cached.length} model(s) cached:`);
284
+ for (const m of cached) {
285
+ console.log(` ${m.modelId.padEnd(20)} ${m.sizeMb} MB`);
286
+ }
287
+ }
288
+ console.log('');
289
+ printInfo('Available models: phi-3-mini, gemma-2-2b, tinyllama');
290
+ console.log('');
291
+ }
292
+ // ─── MODELS FETCH command ─────────────────────────────────────
293
+ async function cmdModelsFetch(modelId) {
294
+ printBanner();
295
+ const job = {
296
+ model_id: modelId,
297
+ model_url: null,
298
+ };
299
+ const url = resolveModelUrl(job);
300
+ if (!url) {
301
+ printError(`Unknown model "${modelId}". Available: phi-3-mini, gemma-2-2b, tinyllama`);
302
+ process.exit(1);
303
+ }
304
+ printInfo(`Downloading ${modelId}...`);
305
+ printInfo(`Source: ${url}`);
306
+ console.log('');
307
+ let lastPct = -1;
308
+ const dest = await downloadModel(modelId, url, (pct, mbDone, mbTotal) => {
309
+ if (pct !== lastPct) {
310
+ process.stdout.write(`\r Downloading... ${pct}% (${mbDone} / ${mbTotal} MB) `);
311
+ lastPct = pct;
312
+ }
313
+ });
314
+ console.log('');
315
+ printSuccess(`Saved to ${dest}`);
316
+ printInfo('You can now run: hive-worker join');
317
+ }
318
+ // ─── CLI definition ───────────────────────────────────────────
319
+ program
320
+ .name('hive-worker')
321
+ .description('GEIANT Hive compute node — earn GNS tokens for idle compute')
322
+ .version('0.1.0');
323
+ program
324
+ .command('join')
325
+ .description('Join the GEIANT Hive swarm and start earning GNS')
326
+ .option('--handle <n>', 'Your GNS handle (e.g. @alice)')
327
+ .option('--rpc-port <port>', 'Port for llama.cpp rpc-server', String(DEFAULT_RPC_PORT))
328
+ .option('--no-rpc', 'Skip starting rpc-server')
329
+ .option('--no-jobs', 'Observer only — do not execute inference jobs')
330
+ .action(async (opts) => { await cmdJoin(opts); });
331
+ program
332
+ .command('status')
333
+ .description('Show swarm status and your token balance')
334
+ .action(async () => { await cmdStatus(); });
335
+ program
336
+ .command('leave')
337
+ .description('Gracefully disconnect from the swarm')
338
+ .action(async () => { await cmdLeave(); });
339
+ program
340
+ .command('whoami')
341
+ .description('Show your Hive identity')
342
+ .action(async () => { await cmdWhoami(); });
343
+ const models = program
344
+ .command('models')
345
+ .description('Manage locally cached inference models');
346
+ models
347
+ .command('list')
348
+ .description('List cached models')
349
+ .action(async () => { await cmdModelsList(); });
350
+ models
351
+ .command('fetch <model-id>')
352
+ .description('Download a model (phi-3-mini, gemma-2-2b, tinyllama)')
353
+ .action(async (modelId) => { await cmdModelsFetch(modelId); });
354
+ program.parse();
355
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { HardwareProfile, GeoProfile } from './hardware.js';
2
+ import type { RegistryStats, WorkerStatus } from './registry.js';
3
+ export interface DashboardState {
4
+ pk: string;
5
+ handle: string | null;
6
+ status: WorkerStatus;
7
+ hw: HardwareProfile;
8
+ geo: GeoProfile;
9
+ rpcPort: number | null;
10
+ rpcAvailable: boolean;
11
+ tokensEarned: number;
12
+ swarmStats: RegistryStats;
13
+ uptimeSeconds: number;
14
+ heartbeatCount: number;
15
+ lastHeartbeat: Date | null;
16
+ logs: string[];
17
+ }
18
+ export declare function renderDashboard(state: DashboardState): void;
19
+ export declare function clearDashboard(): void;
20
+ export declare function hideCursor(): void;
21
+ export declare function printBanner(): void;
22
+ export declare function printSuccess(msg: string): void;
23
+ export declare function printInfo(msg: string): void;
24
+ export declare function printWarn(msg: string): void;
25
+ export declare function printError(msg: string): void;
@@ -0,0 +1,97 @@
1
+ // ============================================================
2
+ // HIVE WORKER — TERMINAL DASHBOARD (simple logger mode)
3
+ // No ANSI cursor movement — just clean line-by-line output.
4
+ // Eliminates the flickering caused by cursor-up + clear redraws.
5
+ // ============================================================
6
+ const A = {
7
+ reset: '\x1b[0m',
8
+ bold: '\x1b[1m',
9
+ green: '\x1b[32m',
10
+ cyan: '\x1b[36m',
11
+ yellow: '\x1b[33m',
12
+ magenta: '\x1b[35m',
13
+ gray: '\x1b[90m',
14
+ white: '\x1b[37m',
15
+ };
16
+ const col = (c, s) => `${c}${s}${A.reset}`;
17
+ // Track what we last printed so we only reprint on change
18
+ let lastStatus = null;
19
+ let lastHeartbeat = 0;
20
+ let lastTokens = -1;
21
+ let lastSwarmNodes = -1;
22
+ let lastLogCount = 0;
23
+ let headerPrinted = false;
24
+ export function renderDashboard(state) {
25
+ // Print header once
26
+ if (!headerPrinted) {
27
+ console.log('');
28
+ console.log(col(A.cyan + A.bold, ' ◆ GEIANT HIVE WORKER v0.1.0'));
29
+ console.log(col(A.gray, ` ${state.hw.cpuCores}c ${state.hw.arch} · ${state.hw.ramGb} GB · ~${state.hw.estimatedTflops} TFLOPS · ${state.geo.city}`));
30
+ console.log(col(A.gray, ` Identity: ${col(A.cyan, state.pk.slice(0, 8))}${state.handle ? ' · @' + state.handle : ''}`));
31
+ console.log(col(A.gray, ' ─────────────────────────────────────'));
32
+ headerPrinted = true;
33
+ }
34
+ // Print status line only when status changes
35
+ if (state.status !== lastStatus) {
36
+ const icon = state.status === 'idle' ? col(A.green, '●')
37
+ : state.status === 'computing' ? col(A.yellow, '◉')
38
+ : col(A.gray, '○');
39
+ console.log(` ${icon} ${col(A.white, state.status.toUpperCase())} ${col(A.gray, new Date().toLocaleTimeString())}`);
40
+ lastStatus = state.status;
41
+ }
42
+ // Print heartbeat line only on new heartbeat
43
+ if (state.heartbeatCount > lastHeartbeat) {
44
+ console.log(col(A.gray, ` ♥ Heartbeat #${state.heartbeatCount} · uptime ${humanUptime(state.uptimeSeconds)}`));
45
+ lastHeartbeat = state.heartbeatCount;
46
+ }
47
+ // Print swarm update when node count changes
48
+ if (state.swarmStats.activeNodes !== lastSwarmNodes) {
49
+ console.log(col(A.gray, ` ⬡ Swarm: ${col(A.white, String(state.swarmStats.activeNodes))} nodes · ${col(A.yellow, state.swarmStats.totalTflops + ' TFLOPS')}`));
50
+ lastSwarmNodes = state.swarmStats.activeNodes;
51
+ }
52
+ // Print earnings update when tokens change
53
+ if (state.tokensEarned !== lastTokens) {
54
+ console.log(col(A.green, ` ✦ Earned: ${state.tokensEarned.toFixed(4)} GNS`));
55
+ lastTokens = state.tokensEarned;
56
+ }
57
+ // Print only new log lines
58
+ if (state.logs.length > lastLogCount) {
59
+ const newLines = state.logs.slice(lastLogCount);
60
+ for (const line of newLines) {
61
+ console.log(col(A.gray, ' › ') + col(A.white, line.slice(0, 72)));
62
+ }
63
+ lastLogCount = state.logs.length;
64
+ }
65
+ }
66
+ export function clearDashboard() {
67
+ // Nothing to clear in logger mode
68
+ }
69
+ export function hideCursor() {
70
+ // No cursor hiding in logger mode — not needed
71
+ }
72
+ function humanUptime(s) {
73
+ if (s < 60)
74
+ return `${s}s`;
75
+ if (s < 3600)
76
+ return `${Math.floor(s / 60)}m ${s % 60}s`;
77
+ return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`;
78
+ }
79
+ export function printBanner() {
80
+ console.log('');
81
+ console.log(col(A.cyan + A.bold, ' ◆ GEIANT HIVE WORKER'));
82
+ console.log(col(A.gray, ' geiant.com/hive · Powered by GNS Protocol'));
83
+ console.log('');
84
+ }
85
+ export function printSuccess(msg) {
86
+ console.log(` ${col(A.green, '✓')} ${msg}`);
87
+ }
88
+ export function printInfo(msg) {
89
+ console.log(` ${col(A.cyan, '›')} ${msg}`);
90
+ }
91
+ export function printWarn(msg) {
92
+ console.log(` ${col(A.yellow, '!')} ${msg}`);
93
+ }
94
+ export function printError(msg) {
95
+ console.log(` ${col(A.magenta, '✗')} ${msg}`);
96
+ }
97
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { HiveJob, JobResult } from './jobs.js';
2
+ export declare function findLlamaCli(): string | null;
3
+ export declare function ensureModelCacheDir(): void;
4
+ export declare function modelCachePath(modelId: string): string;
5
+ export declare function isModelCached(modelId: string): boolean;
6
+ export declare function resolveModelUrl(job: HiveJob): string | null;
7
+ export declare function downloadModel(modelId: string, url: string, onProgress: (pct: number, mbDone: number, mbTotal: number) => void): Promise<string>;
8
+ export interface ExecutorOptions {
9
+ onToken?: (token: string) => void;
10
+ onLog?: (line: string) => void;
11
+ }
12
+ export declare function executeJob(job: HiveJob, opts?: ExecutorOptions): Promise<JobResult>;
13
+ export declare function listCachedModels(): Array<{
14
+ modelId: string;
15
+ sizeMb: number;
16
+ }>;