ADR-0012: Mix tasks for developer experience

View Source

Status

Proposed

Context

Conjure currently provides only programmatic APIs. Common developer workflows require writing boilerplate code:

# To validate a skill
{:ok, skills} = Conjure.load("/path/to/skills")
Enum.each(skills, fn skill ->
  case Conjure.Loader.validate(skill) do
    :ok -> IO.puts("#{skill.name}: valid")
    {:error, errors} -> IO.puts("#{skill.name}: #{inspect(errors)}")
  end
end)

# To list available skills
{:ok, skills} = Conjure.load("/path/to/skills")
Enum.each(skills, &IO.puts(&1.name))

# To build Docker image
# Must manually construct docker build command...

Mix tasks are the standard Elixir mechanism for CLI tooling, providing:

  • Consistent interface (mix conjure.xxx)
  • Argument parsing via OptionParser
  • Integration with Mix project context
  • Discoverability via mix help

The lib/conjure/mix/tasks/ directory exists but is empty, indicating this was planned but not implemented.

Decision

We will implement the following Mix tasks:

mix conjure.validate

Validates skill structure and metadata.

# Validate skills in default paths
$ mix conjure.validate

# Validate specific directory
$ mix conjure.validate --path /path/to/skills

# Validate single skill
$ mix conjure.validate --path /path/to/skills/pdf

# Strict mode (warnings as errors)
$ mix conjure.validate --strict

Output:

Validating skills...
 pdf - valid
 docx - valid
 broken-skill - missing required field: description

Found 3 skills: 2 valid, 1 invalid

mix conjure.list

Lists available skills with metadata.

# List all skills
$ mix conjure.list

# JSON output for scripting
$ mix conjure.list --format json

# Show full details
$ mix conjure.list --verbose

Output:

Available Skills:
  pdf          Comprehensive PDF manipulation toolkit...
  docx         Document creation and editing...

2 skills found

mix conjure.docker.build

Builds the sandbox Docker image.

# Build default image
$ mix conjure.docker.build

# Custom tag
$ mix conjure.docker.build --tag myorg/conjure-sandbox:v1

# No cache
$ mix conjure.docker.build --no-cache

mix conjure.info

Shows information about a specific skill.

$ mix conjure.info pdf

Name: pdf
Description: Comprehensive PDF manipulation toolkit...
License: MIT
Location: /path/to/skills/pdf
Resources:
  - scripts/pdf_utils.py
  - references/api.md
Allowed Tools: bash_tool, view, create_file

Implementation Structure

lib/conjure/mix/tasks/
 conjure.validate.ex
 conjure.list.ex
 conjure.info.ex
 conjure.docker.build.ex

Each task follows the standard Mix.Task pattern:

defmodule Mix.Tasks.Conjure.Validate do
  @shortdoc "Validates skill structure and metadata"
  @moduledoc """
  Validates skills in the specified path.

  ## Usage

      $ mix conjure.validate [--path PATH] [--strict]

  ## Options

    * `--path` - Path to skills directory (default: configured paths)
    * `--strict` - Treat warnings as errors

  """

  use Mix.Task

  @impl Mix.Task
  def run(args) do
    {opts, _, _} = OptionParser.parse(args,
      strict: [path: :string, strict: :boolean]
    )

    # Implementation...
  end
end

Consequences

Positive

  • Standard Elixir developer experience
  • Discoverable via mix help conjure
  • Scriptable for CI/CD pipelines
  • Reduces boilerplate for common operations
  • Consistent with ecosystem conventions

Negative

  • Additional code to maintain
  • Must handle edge cases in CLI context (no supervision tree, etc.)
  • Mix tasks are not available in releases (escript alternative needed)

Neutral

  • Tasks depend on Conjure being compiled
  • Output formatting may need iteration based on user feedback
  • JSON output enables integration with other tools

Alternatives Considered

Escript Binary

A standalone conjure binary would work in releases. Rejected for initial implementation because:

  • Mix tasks are simpler to implement
  • Most users interact during development, not production
  • Can add escript later if needed

IEx Helpers

Could provide Conjure.CLI module for IEx usage. Rejected because:

  • Non-standard interface
  • Mix tasks are more discoverable
  • Can still use the module functions in IEx

References