Kora CLI: Roadmap & Implementation
1. Roadmap
1.1. Phase 1: Foundation (April - May 2026)
-
Initialize Go module (
github.com/EvanusModestus/kora) -
Cobra + Viper scaffolding with root command
-
Auth provider interface (keyring, env, interactive)
-
HTTP client with retry, TLS, auth injection
-
Output formatters (table via Lipgloss, JSON, CSV)
-
First vendor: Cisco ISE (port from netapi — most mature)
-
Second vendor: GitHub (broad appeal, easy to demo)
-
kora login <vendor>credential management -
kora <vendor> ?discovery system -
README, LICENSE (Apache-2.0), CONTRIBUTING.md
1.2. Phase 2: Core Vendors (June - August 2026)
-
5 more vendors: Cloudflare, Vault, Wazuh, Synology, Keycloak
-
kora configfor persistent settings -
Shell completions (bash, zsh, fish, PowerShell)
-
GoReleaser + Cosign release pipeline
-
Homebrew tap, AUR package, Scoop manifest
-
Demo video (3 min, shows ? discovery)
-
Launch: Hacker News, r/devops, r/golang, Awesome Go
1.3. Phase 3: Community & Plugin System (September - November 2026)
-
Plugin interface:
kora plugin install stripe -
Community vendor contributions
-
kora pipe— chain commands (query → filter → format → output) -
Man page generation from Cobra
-
Comprehensive test suite
1.4. Phase 4: Revenue (December 2026+)
-
Kora Pro: scheduled queries, report templates, workflow automation
-
Kora Enterprise: audit logging, SSO, on-prem deployment
-
GitHub Sponsors + Open Collective
-
Documentation site (Antora — domus-kora-docs spoke)
2. Phase 1 Implementation
Detailed step-by-step guide for building the Kora CLI foundation. Each step is separated for individual execution and verification.
2.1. Step 1: Create GitHub Repository
Create the public repository with Apache-2.0 license.
gh repo create kora --public --license apache-2.0 --description "One CLI. Every API." --clone
cd kora
gh repo view --json name,description,licenseInfo
2.3. Step 3: Install Core Dependencies
Each dependency serves a specific role in the architecture.
go get github.com/spf13/cobra@latest
go get github.com/spf13/viper@latest
go get github.com/charmbracelet/lipgloss@latest
go get github.com/charmbracelet/bubbletea@latest
go get github.com/go-resty/resty/v2@latest
go get github.com/zalando/go-keyring@latest
go get filippo.io/age@latest
go mod tidy
cat go.sum | wc -l
2.4. Step 4: Create Project Structure
Create the directory tree that mirrors the Atomic Design architecture from netapi.
mkdir -p cmd
mkdir -p internal/client
mkdir -p internal/auth
mkdir -p internal/output
mkdir -p internal/config
mkdir -p pkg/kora
find . -type d | grep -v '.git' | sort
The resulting structure:
kora/
+-- cmd/
| +-- root.go # Root command with ? discovery
+-- internal/
| +-- client/
| | +-- http.go # HTTP client with retry, TLS, auth
| +-- auth/
| | +-- provider.go # Auth provider interface
| +-- output/
| | +-- formatter.go # Table, JSON, CSV formatters
| +-- config/
| +-- config.go # Viper config management
+-- pkg/
| +-- kora/
| +-- types.go # Public types
+-- main.go # Entry point
+-- go.mod
+-- go.sum
+-- Makefile
+-- .goreleaser.yml
+-- .gitignore
+-- LICENSE
+-- README.md
2.5. Step 5: Scaffold main.go
The entry point is intentionally minimal. All logic lives in cmd/ and internal/.
package main
import (
"os"
"github.com/EvanusModestus/kora/cmd"
)
func main() {
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
}
2.6. Step 6: Scaffold cmd/root.go
The root command defines the CLI identity, version, and ? discovery behavior. Cobra handles flag parsing, help generation, and shell completion out of the box.
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// Version is set at build time via ldflags
var Version = "dev"
var rootCmd = &cobra.Command{
Use: "kora",
Short: "One CLI. Every API.",
Long: `Kora — Universal API CLI
One tool to authenticate, discover, query, and format responses
from any API. Named after the West African 21-stringed instrument:
one instrument, many strings, one musician makes them all sing.
Use '?' after any command to discover available subcommands:
kora ? List all vendors
kora ise ? List ISE resources
kora ise endpoints? List endpoint actions`,
Version: Version,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// Check for ? as last argument for discovery mode
if len(args) > 0 && args[len(args)-1] == "?" {
cmd.Help()
os.Exit(0)
}
},
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
}
},
}
func Execute() error {
return rootCmd.Execute()
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().String("format", "table", "Output format: table, json, csv, yaml")
rootCmd.PersistentFlags().Bool("insecure", false, "Skip TLS verification (use with caution)")
rootCmd.PersistentFlags().Bool("debug", false, "Enable debug output")
viper.BindPFlag("format", rootCmd.PersistentFlags().Lookup("format"))
viper.BindPFlag("insecure", rootCmd.PersistentFlags().Lookup("insecure"))
viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug"))
}
func initConfig() {
viper.SetConfigName(".kora")
viper.SetConfigType("yaml")
viper.AddConfigPath("$HOME")
viper.AddConfigPath(".")
viper.SetEnvPrefix("KORA")
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err == nil {
if viper.GetBool("debug") {
fmt.Fprintln(os.Stderr, "Using config:", viper.ConfigFileUsed())
}
}
}
2.7. Step 7: First Build and Run
Build the binary and verify it works.
go build -o kora .
./kora --help
Kora — Universal API CLI
One tool to authenticate, discover, query, and format responses
from any API. Named after the West African 21-stringed instrument:
one instrument, many strings, one musician makes them all sing.
Use '?' after any command to discover available subcommands:
kora ? List all vendors
kora ise ? List ISE resources
kora ise endpoints? List endpoint actions
Usage:
kora [flags]
Flags:
--debug Enable debug output
--format Output format: table, json, csv, yaml (default "table")
-h, --help help for kora
--insecure Skip TLS verification (use with caution)
-v, --version version for kora
./kora --version
go build -ldflags "-X github.com/EvanusModestus/kora/cmd.Version=0.1.0" -o kora .
./kora --version
2.8. Step 8: Install Locally
Add kora to PATH so it is available system-wide.
go install .
which kora
kora --version
Alternatively, install to a specific location:
go build -o kora . && sudo mv kora /usr/local/bin/
2.9. Next Steps
After completing Phase 1 foundation:
-
Implement
internal/client/http.gowith Resty wrapper, retry logic, TLS config -
Implement
internal/auth/provider.gowith keyring and environment variable backends -
Implement
internal/output/formatter.gowith Lipgloss table rendering -
Add first vendor command:
cmd/ise.goported from netapi -
Add second vendor command:
cmd/github.gofor broad appeal -
Write
Makefilewith build, test, lint, and release targets -
Configure
.goreleaser.ymlfor cross-platform distribution
3. Dependencies
3.1. Blocked By
-
Go proficiency (intermediate level needed — user is beginner)
-
Domain availability check (kora.dev or alternative)
-
Time allocation decision (how many hours/week dedicated)
3.2. Blocks
-
Ollama API service productization (Kora could integrate local AI for API discovery)
-
domus-kora-docs (Antora spoke — documentation site)
-
Revenue timeline for personal financial goals