Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/shelfai/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
bundle Export the shelf as a portable .shelf bundle
import Import a portable .shelf bundle
inspect Inspect a .shelf bundle manifest
compile Compile one or more chunks into optimized context
prune Clean up stale memory entries
chunk-scan Scan agents directory for chunking candidates
chunk Run heuristic pre-filter on a monolithic agent file
Expand Down Expand Up @@ -1098,6 +1099,55 @@ def export_context(
console_err.print(f"[dim]Exported (~{estimate_tokens(result):,} tokens)[/dim]")


# ──────────────────────────────────────────────
# shelfai compile
# ──────────────────────────────────────────────


@app.command("compile")
def compile_cmd(
chunks: list[str] = typer.Argument(None, help="Chunk IDs to compile"),
task: Optional[str] = typer.Option(None, "--task", help="Auto-select chunks for a task type"),
all_chunks: bool = typer.Option(False, "--all", help="Compile every chunk in the shelf"),
max_tokens: Optional[int] = typer.Option(None, "--max-tokens", help="Token budget"),
order: str = typer.Option("priority", "--order", help="Chunk order: priority, alphabetical, dependency, custom"),
output: Optional[str] = typer.Option(None, "--output", "-o", help="Write compiled context to a file"),
shelf_path: str = typer.Option("./shelf", "--shelf", "-s", help="Path to shelf directory"),
):
"""Compile one or more chunks into an optimized context string."""
from shelfai.core.compiler import ChunkCompiler, CompileConfig

shelf_root = _resolve_shelf_root(shelf_path)
if shelf_root is None:
console.print(f"[red]No shelf found at {shelf_path}. Run `shelfai init` first.[/red]")
raise typer.Exit(1)

compiler = ChunkCompiler(str(shelf_root))
config = CompileConfig(max_tokens=max_tokens, order=order)

if task:
compiled = compiler.compile_for_task(task, config=config)
elif all_chunks:
compiled = compiler.compile(compiler.list_chunks(), config=config)
elif chunks:
compiled = compiler.compile(list(chunks), config=config)
else:
console.print("[red]Provide chunk IDs, --task, or --all.[/red]")
raise typer.Exit(1)

if output:
output_path = Path(output).expanduser().resolve()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(compiled.content, encoding="utf-8")
console.print(f"[green]Wrote compiled context to {output_path}[/green]")
else:
print(compiled.content)

if compiled.warnings:
for warning in compiled.warnings:
console_err.print(f"[yellow]{warning}[/yellow]")


# ──────────────────────────────────────────────
# shelfai templates
# ──────────────────────────────────────────────
Expand Down
4 changes: 4 additions & 0 deletions src/shelfai/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""ShelfAI core modules."""

from shelfai.core.annotations import AnnotationManager, ChunkAnnotation
from shelfai.core.compiler import ChunkCompiler, CompileConfig, CompiledContext
from shelfai.core.conditions import ConditionalLoader, LoadCondition, LoadContext
from shelfai.core.diff_report import ChunkDiff, ShelfDiffReport, compare_before_after, compare_shelves
from shelfai.core.migrate import MigrationPlan, MigrationStep, ShelfMigrator
Expand All @@ -9,6 +10,9 @@
__all__ = [
"AnnotationManager",
"ChunkAnnotation",
"ChunkCompiler",
"CompileConfig",
"CompiledContext",
"ChunkDiff",
"ChunkPriority",
"ConditionalLoader",
Expand Down
Loading
Loading