feat: add vapora-doc-lifecycle adapter for documentation management
- Create VAPORA adapter for doc-lifecycle-core integration - DocLifecyclePlugin: Main plugin interface for orchestration - DocumenterIntegration: Integrates with Documenter agent - Configuration for VAPORA-specific settings Features: - Event-driven documentation processing (NATS) - Automatic classification and consolidation - RAG index generation with SurrealDB - mdBook site generation - Root files management (README, CHANGELOG, ROADMAP) Dependency structure: - Development: local path to doc-lifecycle-core - Production: will use crates.io version This enables gradual adoption: 1. Use standalone tool in any Rust project 2. Integrate into VAPORA for automatic processing 3. Share core library between both deployments
This commit is contained in:
parent
ca3fa91d5d
commit
5ea9e3f4de
23
crates/vapora-doc-lifecycle/Cargo.toml
Normal file
23
crates/vapora-doc-lifecycle/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[package]
|
||||||
|
name = "vapora-doc-lifecycle"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
authors = ["Jesus Perez <jesus@jesusperez.pro>"]
|
||||||
|
license = "MIT"
|
||||||
|
description = "VAPORA adapter for documentation lifecycle management"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
doc-lifecycle-core = { path = "../../../Tools/doc-lifecycle-manager/crates/doc-lifecycle-core" }
|
||||||
|
tokio = { version = "1.35", features = ["full"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
tracing = "0.1"
|
||||||
|
anyhow = "1.0"
|
||||||
|
thiserror = "1.0"
|
||||||
|
|
||||||
|
# VAPORA dependencies (will be added later)
|
||||||
|
# vapora-shared = { path = "../vapora-shared" }
|
||||||
|
# vapora-agents = { path = "../vapora-agents" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tempfile = "3.8"
|
||||||
55
crates/vapora-doc-lifecycle/src/config.rs
Normal file
55
crates/vapora-doc-lifecycle/src/config.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//! Configuration for doc-lifecycle VAPORA adapter
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// Plugin configuration
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PluginConfig {
|
||||||
|
/// Enable doc-lifecycle plugin
|
||||||
|
pub enabled: bool,
|
||||||
|
|
||||||
|
/// Root directory for documentation
|
||||||
|
pub docs_root: PathBuf,
|
||||||
|
|
||||||
|
/// Mode: minimal, standard, or full
|
||||||
|
pub mode: String,
|
||||||
|
|
||||||
|
/// Classify on task completion
|
||||||
|
pub auto_classify: bool,
|
||||||
|
|
||||||
|
/// Consolidate duplicates automatically
|
||||||
|
pub auto_consolidate: bool,
|
||||||
|
|
||||||
|
/// Generate RAG index
|
||||||
|
pub generate_rag_index: bool,
|
||||||
|
|
||||||
|
/// Generate mdBook site
|
||||||
|
pub generate_mdbook: bool,
|
||||||
|
|
||||||
|
/// Language for documentation
|
||||||
|
pub language: String,
|
||||||
|
|
||||||
|
/// NATS subject for task events
|
||||||
|
pub nats_subject: String,
|
||||||
|
|
||||||
|
/// SurrealDB connection string
|
||||||
|
pub surreal_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PluginConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: true,
|
||||||
|
docs_root: PathBuf::from("docs"),
|
||||||
|
mode: "standard".to_string(),
|
||||||
|
auto_classify: true,
|
||||||
|
auto_consolidate: true,
|
||||||
|
generate_rag_index: true,
|
||||||
|
generate_mdbook: true,
|
||||||
|
language: "en".to_string(),
|
||||||
|
nats_subject: "vapora.tasks.completed".to_string(),
|
||||||
|
surreal_url: "surreal://localhost:8000".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
crates/vapora-doc-lifecycle/src/documenter.rs
Normal file
56
crates/vapora-doc-lifecycle/src/documenter.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//! Documenter agent integration with doc-lifecycle
|
||||||
|
|
||||||
|
use crate::config::PluginConfig;
|
||||||
|
use crate::plugin::DocLifecyclePlugin;
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
|
/// Documenter agent integration
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DocumenterIntegration {
|
||||||
|
plugin: DocLifecyclePlugin,
|
||||||
|
config: PluginConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DocumenterIntegration {
|
||||||
|
/// Create a new documenter integration
|
||||||
|
pub fn new(config: PluginConfig) -> Result<Self> {
|
||||||
|
let plugin = DocLifecyclePlugin::new(config.clone())?;
|
||||||
|
|
||||||
|
Ok(Self { plugin, config })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle task completion event
|
||||||
|
pub async fn on_task_completed(&mut self, task_id: &str) -> Result<()> {
|
||||||
|
tracing::info!(
|
||||||
|
"Documenter: Processing task completion for task {}",
|
||||||
|
task_id
|
||||||
|
);
|
||||||
|
|
||||||
|
// 1. Process documentation
|
||||||
|
self.plugin.process_task_docs(task_id).await?;
|
||||||
|
|
||||||
|
// 2. Update root files (README, CHANGELOG, ROADMAP)
|
||||||
|
self.update_root_files(task_id).await?;
|
||||||
|
|
||||||
|
// 3. Publish event for other agents
|
||||||
|
self.publish_docs_updated_event(task_id).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_root_files(&self, _task_id: &str) -> Result<()> {
|
||||||
|
// TODO: Update README, CHANGELOG, ROADMAP
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn publish_docs_updated_event(&self, _task_id: &str) -> Result<()> {
|
||||||
|
// TODO: Publish to NATS
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get current configuration
|
||||||
|
#[must_use]
|
||||||
|
pub fn config(&self) -> &PluginConfig {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
|
}
|
||||||
41
crates/vapora-doc-lifecycle/src/error.rs
Normal file
41
crates/vapora-doc-lifecycle/src/error.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//! Error types for VAPORA doc-lifecycle adapter
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
/// Result type for adapter operations
|
||||||
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// Error type for adapter operations
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Core library error
|
||||||
|
Core(doc_lifecycle_core::Error),
|
||||||
|
/// Configuration error
|
||||||
|
Config(String),
|
||||||
|
/// NATS error
|
||||||
|
NatsError(String),
|
||||||
|
/// Database error
|
||||||
|
DatabaseError(String),
|
||||||
|
/// Other errors
|
||||||
|
Other(Box<dyn std::error::Error + Send + Sync>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Core(e) => write!(f, "Core error: {}", e),
|
||||||
|
Self::Config(msg) => write!(f, "Config error: {}", msg),
|
||||||
|
Self::NatsError(msg) => write!(f, "NATS error: {}", msg),
|
||||||
|
Self::DatabaseError(msg) => write!(f, "Database error: {}", msg),
|
||||||
|
Self::Other(e) => write!(f, "{}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
impl From<doc_lifecycle_core::Error> for Error {
|
||||||
|
fn from(err: doc_lifecycle_core::Error) -> Self {
|
||||||
|
Self::Core(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
28
crates/vapora-doc-lifecycle/src/lib.rs
Normal file
28
crates/vapora-doc-lifecycle/src/lib.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//! VAPORA Documentation Lifecycle Management Adapter
|
||||||
|
//!
|
||||||
|
//! This crate provides integration between VAPORA's agent orchestration
|
||||||
|
//! and the doc-lifecycle-core library.
|
||||||
|
//!
|
||||||
|
//! Features:
|
||||||
|
//! - Event-driven documentation processing
|
||||||
|
//! - NATS JetStream integration for task events
|
||||||
|
//! - SurrealDB vector store for RAG indexing
|
||||||
|
//! - Automatic triggering on task completion
|
||||||
|
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
#![warn(missing_debug_implementations)]
|
||||||
|
|
||||||
|
pub mod plugin;
|
||||||
|
pub mod documenter;
|
||||||
|
pub mod config;
|
||||||
|
pub mod error;
|
||||||
|
|
||||||
|
pub use error::{Error, Result};
|
||||||
|
|
||||||
|
/// Re-export commonly used types
|
||||||
|
pub mod prelude {
|
||||||
|
pub use crate::plugin::DocLifecyclePlugin;
|
||||||
|
pub use crate::documenter::DocumenterIntegration;
|
||||||
|
pub use crate::config::PluginConfig;
|
||||||
|
pub use crate::{Error, Result};
|
||||||
|
}
|
||||||
88
crates/vapora-doc-lifecycle/src/plugin.rs
Normal file
88
crates/vapora-doc-lifecycle/src/plugin.rs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
//! Doc-lifecycle plugin for VAPORA
|
||||||
|
|
||||||
|
use crate::config::PluginConfig;
|
||||||
|
use crate::Result;
|
||||||
|
use doc_lifecycle_core::prelude::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// Main plugin interface for doc-lifecycle integration
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DocLifecyclePlugin {
|
||||||
|
config: PluginConfig,
|
||||||
|
classifier: Classifier,
|
||||||
|
consolidator: Consolidator,
|
||||||
|
rag_indexer: RagIndexer,
|
||||||
|
mdbook_generator: Option<MdBookGenerator>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DocLifecyclePlugin {
|
||||||
|
/// Create a new doc-lifecycle plugin
|
||||||
|
pub fn new(config: PluginConfig) -> Result<Self> {
|
||||||
|
let mdbook_generator = if config.generate_mdbook {
|
||||||
|
let mdbook_config = doc_lifecycle_core::mdbook_generator::MdBookConfig::new(
|
||||||
|
PathBuf::from("book"),
|
||||||
|
"VAPORA Project".to_string(),
|
||||||
|
);
|
||||||
|
Some(MdBookGenerator::new(mdbook_config))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
config,
|
||||||
|
classifier: Classifier::new(),
|
||||||
|
consolidator: Consolidator::new(),
|
||||||
|
rag_indexer: RagIndexer::new(),
|
||||||
|
mdbook_generator,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Process documentation for a completed task
|
||||||
|
pub async fn process_task_docs(&mut self, task_id: &str) -> Result<()> {
|
||||||
|
tracing::info!("Processing task docs for task {}", task_id);
|
||||||
|
|
||||||
|
// 1. Classify documents
|
||||||
|
if self.config.auto_classify {
|
||||||
|
self.classify_session_docs(task_id).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Consolidate duplicates
|
||||||
|
if self.config.auto_consolidate {
|
||||||
|
self.consolidate_docs().await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Generate RAG index
|
||||||
|
if self.config.generate_rag_index {
|
||||||
|
self.update_rag_index().await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Generate mdBook
|
||||||
|
if self.config.generate_mdbook {
|
||||||
|
self.generate_mdbook().await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn classify_session_docs(&self, _task_id: &str) -> Result<()> {
|
||||||
|
// TODO: Implement session doc classification
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn consolidate_docs(&self) -> Result<()> {
|
||||||
|
// TODO: Implement consolidation
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_rag_index(&self) -> Result<()> {
|
||||||
|
// TODO: Implement RAG index update
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn generate_mdbook(&self) -> Result<()> {
|
||||||
|
if let Some(generator) = &self.mdbook_generator {
|
||||||
|
generator.generate()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user