@plures/runebook 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ANALYSIS_LADDER.md +231 -0
- package/CHANGELOG.md +124 -0
- package/INTEGRATIONS.md +242 -0
- package/LICENSE +21 -0
- package/MEMORY.md +253 -0
- package/NIXOS.md +357 -0
- package/QUICKSTART.md +157 -0
- package/README.md +295 -0
- package/RELEASE.md +190 -0
- package/ValidationChecklist.md +598 -0
- package/docs/demo.md +338 -0
- package/docs/llm-integration.md +300 -0
- package/docs/parallel-execution-plan.md +160 -0
- package/flake.nix +228 -0
- package/integrations/README.md +242 -0
- package/integrations/demo-steps.sh +64 -0
- package/integrations/nvim-runebook.lua +140 -0
- package/integrations/tmux-status.sh +51 -0
- package/integrations/vim-runebook.vim +77 -0
- package/integrations/wezterm-status-simple.lua +48 -0
- package/integrations/wezterm-status.lua +76 -0
- package/nixos-module.nix +156 -0
- package/package.json +76 -0
- package/packages/design-dojo/index.js +4 -0
- package/packages/design-dojo/package.json +20 -0
- package/packages/design-dojo/tokens.css +69 -0
- package/playwright.config.ts +16 -0
- package/scripts/check-versions.cjs +62 -0
- package/scripts/demo.sh +220 -0
- package/shell.nix +31 -0
- package/src/app.html +13 -0
- package/src/cli/index.ts +1050 -0
- package/src/lib/agent/analysis-pipeline.ts +347 -0
- package/src/lib/agent/analysis-service.ts +171 -0
- package/src/lib/agent/analysis.ts +159 -0
- package/src/lib/agent/analyzers/heuristic.ts +289 -0
- package/src/lib/agent/analyzers/index.ts +7 -0
- package/src/lib/agent/analyzers/llm.ts +204 -0
- package/src/lib/agent/analyzers/local-search.ts +215 -0
- package/src/lib/agent/capture.ts +123 -0
- package/src/lib/agent/index.ts +244 -0
- package/src/lib/agent/integration.ts +81 -0
- package/src/lib/agent/llm/providers/base.ts +99 -0
- package/src/lib/agent/llm/providers/index.ts +60 -0
- package/src/lib/agent/llm/providers/mock.ts +67 -0
- package/src/lib/agent/llm/providers/ollama.ts +151 -0
- package/src/lib/agent/llm/providers/openai.ts +153 -0
- package/src/lib/agent/llm/sanitizer.ts +170 -0
- package/src/lib/agent/llm/types.ts +118 -0
- package/src/lib/agent/memory.ts +363 -0
- package/src/lib/agent/node-status.ts +56 -0
- package/src/lib/agent/node-suggestions.ts +64 -0
- package/src/lib/agent/status.ts +80 -0
- package/src/lib/agent/suggestions.ts +169 -0
- package/src/lib/components/Canvas.svelte +124 -0
- package/src/lib/components/ConnectionLine.svelte +46 -0
- package/src/lib/components/DisplayNode.svelte +167 -0
- package/src/lib/components/InputNode.svelte +158 -0
- package/src/lib/components/TerminalNode.svelte +237 -0
- package/src/lib/components/Toolbar.svelte +359 -0
- package/src/lib/components/TransformNode.svelte +327 -0
- package/src/lib/core/index.ts +31 -0
- package/src/lib/core/observer.ts +278 -0
- package/src/lib/core/redaction.ts +158 -0
- package/src/lib/core/shell-adapters/base.ts +325 -0
- package/src/lib/core/shell-adapters/bash.ts +110 -0
- package/src/lib/core/shell-adapters/index.ts +62 -0
- package/src/lib/core/shell-adapters/zsh.ts +105 -0
- package/src/lib/core/storage.ts +360 -0
- package/src/lib/core/types.ts +176 -0
- package/src/lib/design-dojo/Box.svelte +47 -0
- package/src/lib/design-dojo/Button.svelte +75 -0
- package/src/lib/design-dojo/Input.svelte +65 -0
- package/src/lib/design-dojo/List.svelte +38 -0
- package/src/lib/design-dojo/Select.svelte +48 -0
- package/src/lib/design-dojo/SplitPane.svelte +43 -0
- package/src/lib/design-dojo/StatusBar.svelte +61 -0
- package/src/lib/design-dojo/Table.svelte +47 -0
- package/src/lib/design-dojo/Text.svelte +36 -0
- package/src/lib/design-dojo/Toggle.svelte +48 -0
- package/src/lib/design-dojo/index.ts +10 -0
- package/src/lib/stores/canvas-praxis.ts +268 -0
- package/src/lib/stores/canvas.ts +58 -0
- package/src/lib/types/agent.ts +78 -0
- package/src/lib/types/canvas.ts +71 -0
- package/src/lib/utils/storage.ts +326 -0
- package/src/lib/utils/yaml-loader.ts +52 -0
- package/src/routes/+layout.svelte +5 -0
- package/src/routes/+layout.ts +5 -0
- package/src/routes/+page.svelte +32 -0
- package/src-tauri/Cargo.lock +5735 -0
- package/src-tauri/Cargo.toml +38 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/capabilities/default.json +10 -0
- package/src-tauri/icons/128x128.png +0 -0
- package/src-tauri/icons/128x128@2x.png +0 -0
- package/src-tauri/icons/32x32.png +0 -0
- package/src-tauri/icons/Square107x107Logo.png +0 -0
- package/src-tauri/icons/Square142x142Logo.png +0 -0
- package/src-tauri/icons/Square150x150Logo.png +0 -0
- package/src-tauri/icons/Square284x284Logo.png +0 -0
- package/src-tauri/icons/Square30x30Logo.png +0 -0
- package/src-tauri/icons/Square310x310Logo.png +0 -0
- package/src-tauri/icons/Square44x44Logo.png +0 -0
- package/src-tauri/icons/Square71x71Logo.png +0 -0
- package/src-tauri/icons/Square89x89Logo.png +0 -0
- package/src-tauri/icons/StoreLogo.png +0 -0
- package/src-tauri/icons/icon.icns +0 -0
- package/src-tauri/icons/icon.ico +0 -0
- package/src-tauri/icons/icon.png +0 -0
- package/src-tauri/src/agents/agent1.rs +66 -0
- package/src-tauri/src/agents/agent2.rs +80 -0
- package/src-tauri/src/agents/agent3.rs +73 -0
- package/src-tauri/src/agents/agent4.rs +66 -0
- package/src-tauri/src/agents/agent5.rs +68 -0
- package/src-tauri/src/agents/agent6.rs +75 -0
- package/src-tauri/src/agents/base.rs +52 -0
- package/src-tauri/src/agents/mod.rs +17 -0
- package/src-tauri/src/core/coordination.rs +117 -0
- package/src-tauri/src/core/mod.rs +12 -0
- package/src-tauri/src/core/ownership.rs +61 -0
- package/src-tauri/src/core/types.rs +132 -0
- package/src-tauri/src/execution/mod.rs +5 -0
- package/src-tauri/src/execution/runner.rs +143 -0
- package/src-tauri/src/lib.rs +161 -0
- package/src-tauri/src/main.rs +6 -0
- package/src-tauri/src/memory/api.rs +422 -0
- package/src-tauri/src/memory/client.rs +156 -0
- package/src-tauri/src/memory/encryption.rs +79 -0
- package/src-tauri/src/memory/migration.rs +110 -0
- package/src-tauri/src/memory/mod.rs +28 -0
- package/src-tauri/src/memory/schema.rs +275 -0
- package/src-tauri/src/memory/tests.rs +192 -0
- package/src-tauri/src/orchestrator/coordinator.rs +232 -0
- package/src-tauri/src/orchestrator/mod.rs +13 -0
- package/src-tauri/src/orchestrator/planner.rs +304 -0
- package/src-tauri/tauri.conf.json +35 -0
- package/static/examples/date-time-example.yaml +147 -0
- package/static/examples/hello-world.yaml +74 -0
- package/static/examples/transform-example.yaml +157 -0
- package/static/favicon.png +0 -0
- package/static/svelte.svg +1 -0
- package/static/tauri.svg +6 -0
- package/static/vite.svg +1 -0
- package/svelte.config.js +18 -0
- package/tsconfig.json +19 -0
- package/vite.config.js +45 -0
- package/vitest.config.ts +21 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "runebook"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "RuneBook - A reactive, canvas-native computing environment"
|
|
5
|
+
authors = ["RuneBook Contributors"]
|
|
6
|
+
edition = "2021"
|
|
7
|
+
|
|
8
|
+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
9
|
+
|
|
10
|
+
[lib]
|
|
11
|
+
# The `_lib` suffix may seem redundant but it is necessary
|
|
12
|
+
# to make the lib name unique and wouldn't conflict with the bin name.
|
|
13
|
+
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
|
14
|
+
name = "runebook_lib"
|
|
15
|
+
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
16
|
+
|
|
17
|
+
[build-dependencies]
|
|
18
|
+
tauri-build = { version = "2.5", features = [] }
|
|
19
|
+
|
|
20
|
+
[dependencies]
|
|
21
|
+
tauri = { version = "2.9", features = [] }
|
|
22
|
+
tauri-plugin-opener = "2.5"
|
|
23
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
24
|
+
serde_json = "1.0"
|
|
25
|
+
tokio = { version = "1.48", features = ["full"] }
|
|
26
|
+
reqwest = { version = "0.12", features = ["json"] }
|
|
27
|
+
flate2 = "1.0"
|
|
28
|
+
uuid = { version = "1.10", features = ["v4", "serde"] }
|
|
29
|
+
chrono = { version = "0.4", features = ["serde"] }
|
|
30
|
+
anyhow = "1.0"
|
|
31
|
+
thiserror = "1.0"
|
|
32
|
+
async-trait = "0.1"
|
|
33
|
+
log = "0.4"
|
|
34
|
+
env_logger = "0.11"
|
|
35
|
+
|
|
36
|
+
[dev-dependencies]
|
|
37
|
+
proptest = "1.5"
|
|
38
|
+
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//! Agent 1: Event Capture
|
|
2
|
+
//!
|
|
3
|
+
//! Owns: src/lib/agent/capture.ts, src/lib/core/observer.ts
|
|
4
|
+
//! Runs in parallel with Agent 2
|
|
5
|
+
|
|
6
|
+
use crate::agents::base::{Agent, AgentContext};
|
|
7
|
+
use crate::core::coordination::CoordinationHandle;
|
|
8
|
+
use crate::core::types::{AgentId, AgentStatus};
|
|
9
|
+
use async_trait::async_trait;
|
|
10
|
+
|
|
11
|
+
pub struct Agent1 {
|
|
12
|
+
context: Option<AgentContext>,
|
|
13
|
+
status: AgentStatus,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
impl Agent1 {
|
|
17
|
+
pub fn new() -> Self {
|
|
18
|
+
Self {
|
|
19
|
+
context: None,
|
|
20
|
+
status: AgentStatus::Pending,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[async_trait]
|
|
26
|
+
impl Agent for Agent1 {
|
|
27
|
+
fn id(&self) -> AgentId {
|
|
28
|
+
AgentId::Agent1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async fn initialize(&mut self, coordination: CoordinationHandle) -> Result<(), String> {
|
|
32
|
+
self.context = Some(AgentContext::new(coordination, AgentId::Agent1));
|
|
33
|
+
self.status = AgentStatus::Running;
|
|
34
|
+
Ok(())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async fn execute(&mut self) -> Result<(), String> {
|
|
38
|
+
// TODO: Implement event capture system
|
|
39
|
+
// - Implement captureCommandStart
|
|
40
|
+
// - Implement captureCommandResult
|
|
41
|
+
// - Integrate with terminal observer
|
|
42
|
+
|
|
43
|
+
log::info!("Agent 1 (Event Capture) executing...");
|
|
44
|
+
|
|
45
|
+
// Signal ready
|
|
46
|
+
if let Some(ref ctx) = self.context {
|
|
47
|
+
ctx.coordination.agent_ready(AgentId::Agent1)?;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Simulate work
|
|
51
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
52
|
+
|
|
53
|
+
self.status = AgentStatus::Completed;
|
|
54
|
+
Ok(())
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn status(&self) -> AgentStatus {
|
|
58
|
+
self.status.clone()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
impl Default for Agent1 {
|
|
63
|
+
fn default() -> Self {
|
|
64
|
+
Self::new()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//! Agent 2: Storage APIs
|
|
2
|
+
//!
|
|
3
|
+
//! Owns: src-tauri/src/memory
|
|
4
|
+
//! Runs in parallel with Agent 1
|
|
5
|
+
//! Publishes APIs that Agent 3 depends on
|
|
6
|
+
|
|
7
|
+
use crate::agents::base::{Agent, AgentContext};
|
|
8
|
+
use crate::core::coordination::CoordinationHandle;
|
|
9
|
+
use crate::core::types::{AgentId, AgentStatus, ApiPublished};
|
|
10
|
+
use async_trait::async_trait;
|
|
11
|
+
|
|
12
|
+
pub struct Agent2 {
|
|
13
|
+
context: Option<AgentContext>,
|
|
14
|
+
status: AgentStatus,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
impl Agent2 {
|
|
18
|
+
pub fn new() -> Self {
|
|
19
|
+
Self {
|
|
20
|
+
context: None,
|
|
21
|
+
status: AgentStatus::Pending,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#[async_trait]
|
|
27
|
+
impl Agent for Agent2 {
|
|
28
|
+
fn id(&self) -> AgentId {
|
|
29
|
+
AgentId::Agent2
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async fn initialize(&mut self, coordination: CoordinationHandle) -> Result<(), String> {
|
|
33
|
+
self.context = Some(AgentContext::new(coordination, AgentId::Agent2));
|
|
34
|
+
self.status = AgentStatus::Running;
|
|
35
|
+
Ok(())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async fn execute(&mut self) -> Result<(), String> {
|
|
39
|
+
// TODO: Implement storage APIs
|
|
40
|
+
// - Implement append_event
|
|
41
|
+
// - Implement list_sessions
|
|
42
|
+
// - Implement persist_suggestion
|
|
43
|
+
// - Publish APIs for Agent 3
|
|
44
|
+
|
|
45
|
+
log::info!("Agent 2 (Storage APIs) executing...");
|
|
46
|
+
|
|
47
|
+
// Signal ready
|
|
48
|
+
if let Some(ref ctx) = self.context {
|
|
49
|
+
ctx.coordination.agent_ready(AgentId::Agent2)?;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Simulate work
|
|
53
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
54
|
+
|
|
55
|
+
// Publish APIs
|
|
56
|
+
if let Some(ref ctx) = self.context {
|
|
57
|
+
let api = ApiPublished {
|
|
58
|
+
agent: AgentId::Agent2,
|
|
59
|
+
api_name: "StorageApi".to_string(),
|
|
60
|
+
interface_path: "src-tauri/src/memory/api.rs".to_string(),
|
|
61
|
+
version: "1.0.0".to_string(),
|
|
62
|
+
timestamp: chrono::Utc::now(),
|
|
63
|
+
};
|
|
64
|
+
ctx.coordination.api_published(api)?;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
self.status = AgentStatus::Completed;
|
|
68
|
+
Ok(())
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fn status(&self) -> AgentStatus {
|
|
72
|
+
self.status.clone()
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
impl Default for Agent2 {
|
|
77
|
+
fn default() -> Self {
|
|
78
|
+
Self::new()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//! Agent 3: Analysis Pipeline
|
|
2
|
+
//!
|
|
3
|
+
//! Owns: src/lib/agent/analysis-pipeline.ts, analysis-service.ts, analyzers/
|
|
4
|
+
//! Starts after Agent 2 publishes APIs
|
|
5
|
+
//! Writes suggestions to store (triggers Agent 4)
|
|
6
|
+
|
|
7
|
+
use crate::agents::base::{Agent, AgentContext};
|
|
8
|
+
use crate::core::coordination::CoordinationHandle;
|
|
9
|
+
use crate::core::types::{AgentId, AgentStatus};
|
|
10
|
+
use async_trait::async_trait;
|
|
11
|
+
|
|
12
|
+
pub struct Agent3 {
|
|
13
|
+
context: Option<AgentContext>,
|
|
14
|
+
status: AgentStatus,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
impl Agent3 {
|
|
18
|
+
pub fn new() -> Self {
|
|
19
|
+
Self {
|
|
20
|
+
context: None,
|
|
21
|
+
status: AgentStatus::Pending,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#[async_trait]
|
|
27
|
+
impl Agent for Agent3 {
|
|
28
|
+
fn id(&self) -> AgentId {
|
|
29
|
+
AgentId::Agent3
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async fn initialize(&mut self, coordination: CoordinationHandle) -> Result<(), String> {
|
|
33
|
+
self.context = Some(AgentContext::new(coordination, AgentId::Agent3));
|
|
34
|
+
self.status = AgentStatus::Running;
|
|
35
|
+
Ok(())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async fn execute(&mut self) -> Result<(), String> {
|
|
39
|
+
// TODO: Implement analysis pipeline
|
|
40
|
+
// - Implement enqueueFailure
|
|
41
|
+
// - Integrate with storage APIs from Agent 2
|
|
42
|
+
// - Write suggestions to store (triggers Agent 4)
|
|
43
|
+
|
|
44
|
+
log::info!("Agent 3 (Analysis Pipeline) executing...");
|
|
45
|
+
|
|
46
|
+
// Signal ready
|
|
47
|
+
if let Some(ref ctx) = self.context {
|
|
48
|
+
ctx.coordination.agent_ready(AgentId::Agent3)?;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Simulate work
|
|
52
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
53
|
+
|
|
54
|
+
// Complete task: write suggestions to store
|
|
55
|
+
if let Some(ref ctx) = self.context {
|
|
56
|
+
ctx.coordination
|
|
57
|
+
.task_completed(AgentId::Agent3, "agent3-2".to_string())?;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
self.status = AgentStatus::Completed;
|
|
61
|
+
Ok(())
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
fn status(&self) -> AgentStatus {
|
|
65
|
+
self.status.clone()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
impl Default for Agent3 {
|
|
70
|
+
fn default() -> Self {
|
|
71
|
+
Self::new()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//! Agent 4: Surfaces
|
|
2
|
+
//!
|
|
3
|
+
//! Owns: src/lib/agent/surfaces.ts, integrations/
|
|
4
|
+
//! Starts after Agent 3 writes suggestions to store
|
|
5
|
+
|
|
6
|
+
use crate::agents::base::{Agent, AgentContext};
|
|
7
|
+
use crate::core::coordination::CoordinationHandle;
|
|
8
|
+
use crate::core::types::{AgentId, AgentStatus};
|
|
9
|
+
use async_trait::async_trait;
|
|
10
|
+
|
|
11
|
+
pub struct Agent4 {
|
|
12
|
+
context: Option<AgentContext>,
|
|
13
|
+
status: AgentStatus,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
impl Agent4 {
|
|
17
|
+
pub fn new() -> Self {
|
|
18
|
+
Self {
|
|
19
|
+
context: None,
|
|
20
|
+
status: AgentStatus::Pending,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[async_trait]
|
|
26
|
+
impl Agent for Agent4 {
|
|
27
|
+
fn id(&self) -> AgentId {
|
|
28
|
+
AgentId::Agent4
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async fn initialize(&mut self, coordination: CoordinationHandle) -> Result<(), String> {
|
|
32
|
+
self.context = Some(AgentContext::new(coordination, AgentId::Agent4));
|
|
33
|
+
self.status = AgentStatus::Running;
|
|
34
|
+
Ok(())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async fn execute(&mut self) -> Result<(), String> {
|
|
38
|
+
// TODO: Implement suggestion surfaces
|
|
39
|
+
// - Implement displaySuggestion
|
|
40
|
+
// - Integrate with tmux, wezterm, vim, neovim
|
|
41
|
+
// - Read suggestions from store (written by Agent 3)
|
|
42
|
+
|
|
43
|
+
log::info!("Agent 4 (Surfaces) executing...");
|
|
44
|
+
|
|
45
|
+
// Signal ready
|
|
46
|
+
if let Some(ref ctx) = self.context {
|
|
47
|
+
ctx.coordination.agent_ready(AgentId::Agent4)?;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Simulate work
|
|
51
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
52
|
+
|
|
53
|
+
self.status = AgentStatus::Completed;
|
|
54
|
+
Ok(())
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn status(&self) -> AgentStatus {
|
|
58
|
+
self.status.clone()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
impl Default for Agent4 {
|
|
63
|
+
fn default() -> Self {
|
|
64
|
+
Self::new()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//! Agent 5: Nix + CI Scaffolding
|
|
2
|
+
//!
|
|
3
|
+
//! Owns: flake.nix, shell.nix, .github/workflows
|
|
4
|
+
//! Runs continuously (starts early)
|
|
5
|
+
|
|
6
|
+
use crate::agents::base::{Agent, AgentContext};
|
|
7
|
+
use crate::core::coordination::CoordinationHandle;
|
|
8
|
+
use crate::core::types::{AgentId, AgentStatus};
|
|
9
|
+
use async_trait::async_trait;
|
|
10
|
+
|
|
11
|
+
pub struct Agent5 {
|
|
12
|
+
context: Option<AgentContext>,
|
|
13
|
+
status: AgentStatus,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
impl Agent5 {
|
|
17
|
+
pub fn new() -> Self {
|
|
18
|
+
Self {
|
|
19
|
+
context: None,
|
|
20
|
+
status: AgentStatus::Pending,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[async_trait]
|
|
26
|
+
impl Agent for Agent5 {
|
|
27
|
+
fn id(&self) -> AgentId {
|
|
28
|
+
AgentId::Agent5
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async fn initialize(&mut self, coordination: CoordinationHandle) -> Result<(), String> {
|
|
32
|
+
self.context = Some(AgentContext::new(coordination, AgentId::Agent5));
|
|
33
|
+
self.status = AgentStatus::Running;
|
|
34
|
+
Ok(())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async fn execute(&mut self) -> Result<(), String> {
|
|
38
|
+
// TODO: Implement Nix + CI scaffolding
|
|
39
|
+
// - Set up flake.nix
|
|
40
|
+
// - Set up shell.nix
|
|
41
|
+
// - Set up CI workflows
|
|
42
|
+
// - Runs continuously (can be updated throughout)
|
|
43
|
+
|
|
44
|
+
log::info!("Agent 5 (Nix + CI) executing...");
|
|
45
|
+
|
|
46
|
+
// Signal ready
|
|
47
|
+
if let Some(ref ctx) = self.context {
|
|
48
|
+
ctx.coordination.agent_ready(AgentId::Agent5)?;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Simulate continuous work
|
|
52
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
53
|
+
|
|
54
|
+
// Agent 5 runs continuously, so we don't mark as completed
|
|
55
|
+
// Status remains Running
|
|
56
|
+
Ok(())
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
fn status(&self) -> AgentStatus {
|
|
60
|
+
self.status.clone()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
impl Default for Agent5 {
|
|
65
|
+
fn default() -> Self {
|
|
66
|
+
Self::new()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//! Agent 6: Finalization
|
|
2
|
+
//!
|
|
3
|
+
//! Owns: ValidationChecklist.md
|
|
4
|
+
//! Runs continuously but finalizes at the end
|
|
5
|
+
|
|
6
|
+
use crate::agents::base::{Agent, AgentContext};
|
|
7
|
+
use crate::core::coordination::CoordinationHandle;
|
|
8
|
+
use crate::core::types::{AgentId, AgentStatus};
|
|
9
|
+
use async_trait::async_trait;
|
|
10
|
+
|
|
11
|
+
pub struct Agent6 {
|
|
12
|
+
context: Option<AgentContext>,
|
|
13
|
+
status: AgentStatus,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
impl Agent6 {
|
|
17
|
+
pub fn new() -> Self {
|
|
18
|
+
Self {
|
|
19
|
+
context: None,
|
|
20
|
+
status: AgentStatus::Pending,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[async_trait]
|
|
26
|
+
impl Agent for Agent6 {
|
|
27
|
+
fn id(&self) -> AgentId {
|
|
28
|
+
AgentId::Agent6
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async fn initialize(&mut self, coordination: CoordinationHandle) -> Result<(), String> {
|
|
32
|
+
self.context = Some(AgentContext::new(coordination, AgentId::Agent6));
|
|
33
|
+
self.status = AgentStatus::Running;
|
|
34
|
+
Ok(())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async fn execute(&mut self) -> Result<(), String> {
|
|
38
|
+
// TODO: Finalize integration and testing
|
|
39
|
+
// - Update ValidationChecklist.md
|
|
40
|
+
// - Finalize integration
|
|
41
|
+
// - Run final tests
|
|
42
|
+
// - Runs continuously but finalizes at the end
|
|
43
|
+
|
|
44
|
+
log::info!("Agent 6 (Finalization) executing...");
|
|
45
|
+
|
|
46
|
+
// Signal ready
|
|
47
|
+
if let Some(ref ctx) = self.context {
|
|
48
|
+
ctx.coordination.agent_ready(AgentId::Agent6)?;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Simulate continuous work
|
|
52
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
53
|
+
|
|
54
|
+
// Agent 6 runs continuously, finalizes at end
|
|
55
|
+
// Status remains Running until finalization
|
|
56
|
+
Ok(())
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
fn status(&self) -> AgentStatus {
|
|
60
|
+
self.status.clone()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// Finalize the agent (called at the end)
|
|
64
|
+
async fn finalize(&mut self) -> Result<(), String> {
|
|
65
|
+
log::info!("Agent 6 (Finalization) finalizing...");
|
|
66
|
+
self.status = AgentStatus::Completed;
|
|
67
|
+
Ok(())
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
impl Default for Agent6 {
|
|
72
|
+
fn default() -> Self {
|
|
73
|
+
Self::new()
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//! Base agent trait and common functionality.
|
|
2
|
+
|
|
3
|
+
use crate::core::coordination::CoordinationHandle;
|
|
4
|
+
use crate::core::types::{AgentId, AgentStatus};
|
|
5
|
+
use async_trait::async_trait;
|
|
6
|
+
|
|
7
|
+
/// Base trait for all agents
|
|
8
|
+
#[async_trait]
|
|
9
|
+
pub trait Agent: Send + Sync {
|
|
10
|
+
/// Get the agent's ID
|
|
11
|
+
fn id(&self) -> AgentId;
|
|
12
|
+
|
|
13
|
+
/// Get the agent's name
|
|
14
|
+
fn name(&self) -> &'static str {
|
|
15
|
+
self.id().name()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// Initialize the agent
|
|
19
|
+
async fn initialize(&mut self, coordination: CoordinationHandle) -> Result<(), String>;
|
|
20
|
+
|
|
21
|
+
/// Execute the agent's main work
|
|
22
|
+
async fn execute(&mut self) -> Result<(), String>;
|
|
23
|
+
|
|
24
|
+
/// Get current status
|
|
25
|
+
fn status(&self) -> AgentStatus;
|
|
26
|
+
|
|
27
|
+
/// Check if agent can start (dependencies met)
|
|
28
|
+
fn can_start(&self) -> bool {
|
|
29
|
+
matches!(self.status(), AgentStatus::Pending | AgentStatus::Running)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Finalize the agent (called at the end of execution)
|
|
33
|
+
async fn finalize(&mut self) -> Result<(), String> {
|
|
34
|
+
// Default implementation does nothing
|
|
35
|
+
Ok(())
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// Agent execution context
|
|
40
|
+
pub struct AgentContext {
|
|
41
|
+
pub coordination: CoordinationHandle,
|
|
42
|
+
pub agent_id: AgentId,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
impl AgentContext {
|
|
46
|
+
pub fn new(coordination: CoordinationHandle, agent_id: AgentId) -> Self {
|
|
47
|
+
Self {
|
|
48
|
+
coordination,
|
|
49
|
+
agent_id,
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//! Agent implementations for parallel execution.
|
|
2
|
+
|
|
3
|
+
pub mod agent1;
|
|
4
|
+
pub mod agent2;
|
|
5
|
+
pub mod agent3;
|
|
6
|
+
pub mod agent4;
|
|
7
|
+
pub mod agent5;
|
|
8
|
+
pub mod agent6;
|
|
9
|
+
pub mod base;
|
|
10
|
+
|
|
11
|
+
pub use agent1::*;
|
|
12
|
+
pub use agent2::*;
|
|
13
|
+
pub use agent3::*;
|
|
14
|
+
pub use agent4::*;
|
|
15
|
+
pub use agent5::*;
|
|
16
|
+
pub use agent6::*;
|
|
17
|
+
pub use base::*;
|