Module: Logi::Output

Defined in:
lib/logi/output.rb

Overview

Centralized output for human / JSON modes.

Why: When an LLM (Claude, ChatGPT) drives the CLI, it can pass ‘–json` (or set `LOGI_OUTPUT=json`) to receive a stable, parseable shape on stdout. Human messages still go to stderr so they don’t pollute pipes.

Pattern: GitHub ‘gh –json fields`, Stripe CLI default JSON, Vercel `–output json`.

Class Method Summary collapse

Class Method Details

.chatter(text, options = {}) ⇒ Object

Pretty-print to stderr only when human (no-op in JSON mode). Use for progress chatter (“Opening your browser…” etc).



53
54
55
56
# File 'lib/logi/output.rb', line 53

def chatter(text, options = {})
  return if json?(options)
  $stderr.puts text
end

.failure(code:, message:, status: nil, options: {}, &human_block) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/logi/output.rb', line 38

def failure(code:, message:, status: nil, options: {}, &human_block)
  payload = { success: false, error: { code: code, message: message } }
  payload[:error][:status] = status if status

  if json?(options)
    $stdout.puts JSON.generate(payload)
  elsif human_block
    human_block.call
  else
    warn message
  end
end

.json?(options = {}) ⇒ Boolean

Returns:

  • (Boolean)


27
# File 'lib/logi/output.rb', line 27

def json?(options = {}); mode(options) == "json"; end

.mode(options = {}) ⇒ Object

Resolve mode from (in order):

1. ENV `LOGI_OUTPUT=json` or `=human`
2. options[:json] true → json
3. tty/pipe heuristic — pipe defaults to json (LLM-friendly)
4. fallback: human


21
22
23
24
25
# File 'lib/logi/output.rb', line 21

def mode(options = {})
  return ENV["LOGI_OUTPUT"] if %w[json human].include?(ENV["LOGI_OUTPUT"])
  return "json" if options[:json]
  "human"
end

.success(data, options = {}, &human_block) ⇒ Object

Emit a structured success result. In human mode, runs the block instead.



30
31
32
33
34
35
36
# File 'lib/logi/output.rb', line 30

def success(data, options = {}, &human_block)
  if json?(options)
    $stdout.puts JSON.generate(success: true, data: data)
  elsif human_block
    human_block.call
  end
end