spb/metrika Public
Stata-class statistics, GPU-accelerated by Apple Silicon. Native Swift — no Electron, no Python runtime, no compromises.
Swift 92.4%
HTML 3.3%
R 3%
Shell 1.3%
1//2// MetrikaCLI.swift3// Metrika4//5// Author: Simon-Pierre Boucher6// Contact: contact@spboucher.ai7// Copyright © 2026 Simon-Pierre Boucher. All rights reserved.8//910import ArgumentParser11import Foundation12import ZQEngine1314/// Companion command-line tool: runs ZQL commands or `.zyq` do-files15/// against a headless session (default subcommand), and generates the16/// documentation site (`docs`).17@main18struct MetrikaCLI: AsyncParsableCommand {19 static let configuration = CommandConfiguration(20 commandName: "metrika-cli",21 abstract: "Metrika statistical engine — command-line interface.",22 subcommands: [RunCommand.self, DocsCommand.self],23 defaultSubcommand: RunCommand.self24 )25}2627/// Default behavior: execute commands, run a do-file, or start a REPL.28struct RunCommand: AsyncParsableCommand {29 static let configuration = CommandConfiguration(30 commandName: "run",31 abstract: "Execute ZQL commands or a do-file (default)."32 )3334 @Option(35 name: [.short, .customLong("execute")],36 help: "Execute a ZQL command (repeatable, runs in order)."37 )38 var execute: [String] = []3940 @Argument(help: "A .zyq do-file to run.")41 var doFile: String?4243 mutating func run() async throws {44 let session = try ZQSession()4546 if let doFile {47 let url = URL(fileURLWithPath: (doFile as NSString).expandingTildeInPath)48 let text = try String(contentsOf: url, encoding: .utf8)49 let result = try await session.executeScript(text)50 print(result.text)51 return52 }5354 if !execute.isEmpty {55 for command in execute {56 let result = try await session.execute(command)57 if !result.text.isEmpty { print(result.text) }58 }59 return60 }6162 // REPL63 print("Metrika — type ZQL commands, 'exit' to quit.")64 while true {65 print(". ", terminator: "")66 guard let line = readLine() else { break }67 if line == "exit" || line == "quit" { break }68 do {69 let result = try await session.execute(line)70 if !result.text.isEmpty { print(result.text) }71 } catch {72 print("error: \(error)")73 }74 }75 }76}77