Encode intent/decision/plan workflow for Snowflake platform delivery so engagements share a durable recipe instead of one-off LLM chats. Co-authored-by: Cursor <cursoragent@cursor.com>
45 lines
1.6 KiB
Python
45 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import typer
|
|
from rich.console import Console
|
|
|
|
from skylattice.core.decisions import explain_path
|
|
from skylattice.core.intent import load_intent
|
|
from skylattice.core.paths import find_customer_root, get_by_path
|
|
|
|
console = Console()
|
|
|
|
|
|
def run(
|
|
path_key: str = typer.Option(..., "--path", help="Intent path, e.g. domains.finance"),
|
|
project: Path | None = typer.Option(None, "--project", help="Customer project directory"),
|
|
) -> None:
|
|
"""Explain why a path looks the way it does (intent value + decisions)."""
|
|
customer_root = project.resolve() if project else find_customer_root()
|
|
intent = load_intent(customer_root)
|
|
|
|
parts = path_key.split(".")
|
|
value = get_by_path(intent, path_key)
|
|
if value is None and parts and parts[0] == "domains" and len(parts) >= 2:
|
|
for d in intent.get("domains") or []:
|
|
if d.get("name") == parts[1]:
|
|
value = d if len(parts) == 2 else d.get(parts[2])
|
|
break
|
|
|
|
console.print(f"[bold]{path_key}[/bold] = {value!r}")
|
|
|
|
if parts and parts[0] == "domains" and len(parts) >= 2:
|
|
for d in intent.get("domains") or []:
|
|
if d.get("name") == parts[1]:
|
|
console.print(f"domain record: {d}")
|
|
|
|
matches = explain_path(customer_root, path_key)
|
|
if not matches:
|
|
console.print("[dim]No linked decisions.[/dim]")
|
|
return
|
|
for d in matches:
|
|
console.print(f"[green]decision[/green] {d.get('id')} [{d.get('status')}] expires={d.get('expires_on')}")
|
|
console.print(f" {d.get('rationale')}")
|