Skip to content

feat: CLI agent-readiness optimizations #268

@bussyjd

Description

@bussyjd

Context

The obol CLI is/will increasingly consumed by AI agents — Claude Code during development, OpenClaw agents in-cluster, and soon MCP clients. Today the CLI is human-optimized: colored output, spinners, interactive prompts, and hand-formatted tables. Agents need structured output, non-interactive paths, input hardening, and runtime introspection.

Current strengths: internal/ui/ abstraction with TTY detection, --verbose/--quiet global flags, internal/schemas/ with JSON-tagged Go types, --force pattern for non-interactive destructive ops, 23 SKILL.md files shipped, two commands already have --json (update, sell info).

Key gaps: No global structured output, ~100+ raw fmt.Printf calls in cmd/obol/ bypassing the UI layer, no input validation, no schema introspection, no --dry-run, no field filtering, no raw JSON input path, no CONTEXT.md for agent consumption, interactive flows with no headless bypass (openclaw onboard hardwired Interactive: true), no MCP surface.

Plan

Phase 1: Global --output json + Raw JSON Input

  • Extend *ui.UI with OutputMode (human|json), add IsJSON(), JSON(v) method
  • Add global --output / -o flag (env OBOL_OUTPUT)
  • Refactor commands to return typed results first, then format for human or JSON (reusable for MCP later)
  • Migrate all list/status commands: sell list/status, network list, model status/list, version, openclaw list, tunnel status
  • Wire existing sell info --json and update --json to global flag, deprecate local flags
  • Add --from-json flag to resource-creating commands (sell http, sell inference, sell pricing, network add) — accepts schemas.ServiceOfferSpec / schemas.PaymentTerms directly, bypasses 15+ flag translation

Phase 2: Input Validation + Headless Paths

  • New internal/validate/ package: Name, Namespace, WalletAddress, ChainName, Path, Price, URL, NoControlChars
  • Reject path traversals (../, %2e%2e), control characters, invalid formats
  • Wire validation into all action handlers (sell, network, model, openclaw)
  • Headless paths: when IsJSON() || !IsTTY(), prompts return defaults or error with required flag hints
  • Fix openclaw onboard (Interactive: true hardwired) — add non-interactive path when all flags provided
  • Fix model setup interactive selection, model pull stdin reader, sell delete raw fmt.Scanln

Phase 3: Schema Introspection (obol describe)

  • New cmd/obol/describe.go: walks urfave/cli command tree, emits flags + schemas as JSON
  • New internal/schemas/registry.go: JSON Schema generation from Go struct tags
  • Command metadata annotations linking mutating commands to their schemas

Phase 4: --fields Support

  • New internal/ui/fields.go: FilterFields(data, fields) via reflect on JSON tags
  • Global --fields flag (requires --output json)

Phase 5: --dry-run for Mutating Commands

  • Global --dry-run flag
  • Priority: sell http (already builds manifest before apply), sell pricing, network add, sell delete
  • Returns DryRunResult{Command, Valid, WouldCreate, Manifest} as JSON

Phase 6: Agent Context & Skills

  • Ship CONTEXT.md encoding agent invariants (always use --output json, --force, --fields, --dry-run)
  • Update 23 SKILL.md files to reference new agent-friendly flags

Phase 7: MCP Surface (obol mcp)

  • New internal/mcp/ package using github.com/mark3labs/mcp-go
  • Tool handlers call refactored typed-result functions directly (not shell out with --output json)
  • Exposes high-value tools: sell, network, model, openclaw, version, update, tunnel status
  • Excludes: kubectl/helm/k9s passthroughs, interactive-only, dangerous ops

Key Files

File Changes
internal/ui/ui.go OutputMode, IsJSON(), NewWithAllOptions()
internal/ui/output.go JSON() method, stderr redirect in JSON mode
internal/ui/prompt.go Non-interactive behavior when JSON/non-TTY
cmd/obol/main.go --output, --dry-run, --fields global flags
cmd/obol/sell.go JSON output, typed results, validation, dry-run, --from-json
cmd/obol/network.go JSON output, typed results, validation
cmd/obol/model.go JSON output, typed results, validation, headless paths
cmd/obol/openclaw.go JSON output, typed results, validation, headless onboard
cmd/obol/describe.go New — schema introspection command
cmd/obol/mcp.go New — obol mcp command
internal/validate/validate.go New — input validation
internal/schemas/registry.go New — JSON Schema generation
internal/mcp/ New — MCP server, tools, handlers
CONTEXT.md New — agent-facing context file

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions