use std::path::PathBuf;
use anyhow::{Context, Result};
use clap::Parser;
use khive_mcp::serve::{resolve_runtime_config, RuntimeConfigInputs};
use khive_pack_git::ingest::{run_ingest, IngestOptions};
use khive_runtime::{KhiveRuntime, Namespace, PackRegistry, VerbRegistryBuilder};
#[derive(Parser, Debug)]
pub struct GitIngestArgs {
#[arg(long)]
pub repo: PathBuf,
#[arg(long)]
pub project: String,
#[arg(long, env = "KHIVE_DB")]
pub db: Option<String>,
#[arg(long, default_value = "local")]
pub namespace: String,
#[arg(long)]
pub human: bool,
}
pub async fn run_git_ingest(args: GitIngestArgs) -> Result<()> {
let ns = Namespace::parse(&args.namespace).map_err(|e| anyhow::anyhow!("{e}"))?;
let cfg = resolve_runtime_config(RuntimeConfigInputs {
db: args.db.as_deref(),
config: None,
namespace: ns,
namespace_explicit: true,
actor_explicit: false,
no_embed: false,
packs: None,
brain_profile: None,
})?;
let runtime = KhiveRuntime::new(cfg).map_err(|e| anyhow::anyhow!("{e}"))?;
let resolved_ns = runtime.config().default_namespace.clone();
let token = runtime
.authorize(resolved_ns)
.map_err(|e| anyhow::anyhow!("{e}"))
.context("failed to authorize namespace")?;
let mut builder = VerbRegistryBuilder::new();
builder.with_gate(runtime.config().gate.clone());
builder.with_default_namespace(runtime.config().default_namespace.as_str());
builder.with_visible_namespaces(runtime.config().visible_namespaces.clone());
builder.with_actor_id(runtime.config().actor_id.clone());
PackRegistry::register_packs(
&runtime.config().packs.clone(),
runtime.clone(),
&mut builder,
)
.map_err(|e| anyhow::anyhow!("pack registration failed: {e:?}"))?;
let registry = builder.build().map_err(|e| anyhow::anyhow!("{e}"))?;
runtime.install_edge_rules(registry.all_edge_rules());
let report = run_ingest(
&runtime,
&token,
®istry,
IngestOptions::unbounded(args.repo, args.project),
)
.await?;
if args.human {
println!(
"commits: {} ingested, {} skipped\nissues: {} ingested, {} skipped\nprs: {} ingested, {} skipped\ngh_available: {}",
report.commits_ingested,
report.commits_skipped_existing,
report.issues_ingested,
report.issues_skipped_existing,
report.prs_ingested,
report.prs_skipped_existing,
report.gh_available,
);
for w in &report.warnings {
eprintln!("warning: {w}");
}
} else {
println!("{}", serde_json::to_string_pretty(&report)?);
}
Ok(())
}