Skip to content

feat(extract): add --format markdown output for skill injection use case #23

@WesleyMFrederick

Description

@WesleyMFrederick

Problem

jact extract header outputs JSON by default, which includes metadata (links report, stats, content IDs) alongside the extracted content. When used inside Claude Code skills via the !command`` dynamic injection syntax, the agent receives JSON it must parse to find the actual markdown content. The extracted content is buried in .extractedContentBlocks.<id>.content.

Reproduction Steps

  1. Create a Claude Code skill with dynamic injection:
    ## Injected Rules
    !`jact extract header /path/to/file.md "Section Name" --scope /path/to/repo`
  2. Invoke the skill via /test-inject
  3. Observe: agent receives full JSON output including outgoingLinksReport, stats, processedLinks metadata
  4. The actual markdown content is nested at .extractedContentBlocks.<hash>.content

Root Cause

jact extract header was designed for programmatic consumption (validation pipelines, CI). The Claude Code skill injection use case (!command``) needs raw extracted content only, with no wrapper metadata.

Expected Behavior

A --format markdown (or --format text) flag that outputs only the extracted markdown content, no JSON wrapper:

# Current (default, becomes --verbose or --format json)
jact extract header file.md "Section" --scope /repo
# → full JSON with metadata

# New
jact extract header file.md "Section" --scope /repo --format markdown
# → raw markdown content only, ready for skill injection

Related

Note

Current JSON output works (model parses the .content field), but it wastes tokens on metadata the model does not need. For a single header extraction, the JSON wrapper is ~350 chars of overhead per extraction. In skills with multiple !jact extract`` calls, this compounds.

Proposed migration:

  • --format markdown (new default candidate): raw content only
  • --format json (current behavior): full metadata, links report, stats
  • --verbose flag: could be an alias for the full JSON output

Not proposing changing the current default in this issue. Start with adding --format markdown as an opt-in flag. Default change can be a separate discussion.


Acceptance Criteria

  • jact extract header <file> <heading> --format markdown outputs only the extracted markdown content
  • No JSON wrapper, no stats, no links report in markdown format output
  • Multiple content blocks concatenated in extraction order with --- separator
  • --format json preserves current behavior exactly
  • Default format unchanged (JSON) to avoid breaking existing consumers

Definition of Done

  • Failing tests written (RED phase)
  • Implementation complete (GREEN phase)
  • All tests pass
  • Build succeeds
  • Committed with conventional commit

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions