summaryrefslogtreecommitdiff
path: root/makima
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-04 01:59:40 +0000
committersoryu <soryu@soryu.co>2026-02-04 01:59:40 +0000
commit612cecc5bd5dbfc73d4a3a9d38626378eaf39041 (patch)
treee23a4772b5299082a99c5ec449cbe222dc038e98 /makima
parent40f4c4ebbb41a46d83fa67fa43e6ec683ab7fdb2 (diff)
downloadsoryu-612cecc5bd5dbfc73d4a3a9d38626378eaf39041.tar.gz
soryu-612cecc5bd5dbfc73d4a3a9d38626378eaf39041.zip
Remove chain supervisor capability
Chains no longer spawn a supervisor task. Checkpoint contracts will be automatically run as part of the DAG execution when dependencies complete. - Remove supervisor task creation from start_chain handler - Remove chain supervisor CLI commands - Remove supervisor_task_id from StartChainResponse - Remove withSupervisor option from frontend Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'makima')
-rw-r--r--makima/frontend/src/components/chains/ChainEditor.tsx32
-rw-r--r--makima/frontend/src/lib/api.ts27
-rw-r--r--makima/src/bin/makima.rs89
-rw-r--r--makima/src/daemon/cli/mod.rs14
-rw-r--r--makima/src/daemon/cli/supervisor.rs63
-rw-r--r--makima/src/db/models.rs8
-rw-r--r--makima/src/db/repository.rs16
-rw-r--r--makima/src/server/handlers/chains.rs136
8 files changed, 18 insertions, 367 deletions
diff --git a/makima/frontend/src/components/chains/ChainEditor.tsx b/makima/frontend/src/components/chains/ChainEditor.tsx
index 49e585c..d278607 100644
--- a/makima/frontend/src/components/chains/ChainEditor.tsx
+++ b/makima/frontend/src/components/chains/ChainEditor.tsx
@@ -54,7 +54,6 @@ export function ChainEditor({
const [isStarting, setIsStarting] = useState(false);
const [isStopping, setIsStopping] = useState(false);
const [error, setError] = useState<string | null>(null);
- const [withSupervisor, setWithSupervisor] = useState(false);
// Load definitions when chain changes
useEffect(() => {
@@ -174,14 +173,14 @@ export function ChainEditor({
setIsStarting(true);
setError(null);
try {
- await startChain(chain.id, { withSupervisor });
+ await startChain(chain.id);
onRefresh();
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to start chain");
} finally {
setIsStarting(false);
}
- }, [chain.id, onRefresh, withSupervisor]);
+ }, [chain.id, onRefresh]);
const handleStopChain = useCallback(async () => {
if (!confirm("Are you sure you want to stop this chain?")) return;
@@ -261,26 +260,13 @@ export function ChainEditor({
</span>
{/* Chain control buttons */}
{chain.status === "pending" && definitions.length > 0 && (
- <>
- <label className="flex items-center gap-1 font-mono text-[10px] text-[#9bc3ff] cursor-pointer">
- <input
- type="checkbox"
- checked={withSupervisor}
- onChange={(e) => setWithSupervisor(e.target.checked)}
- className="w-3 h-3 accent-[#75aafc]"
- />
- <span title="Create a Claude supervisor task to monitor chain progress">
- Supervisor
- </span>
- </label>
- <button
- onClick={handleStartChain}
- disabled={isStarting}
- className="px-3 py-1 font-mono text-xs text-[#dbe7ff] bg-green-600 hover:bg-green-700 border border-green-500 transition-colors disabled:opacity-50"
- >
- {isStarting ? "Starting..." : "Start Chain"}
- </button>
- </>
+ <button
+ onClick={handleStartChain}
+ disabled={isStarting}
+ className="px-3 py-1 font-mono text-xs text-[#dbe7ff] bg-green-600 hover:bg-green-700 border border-green-500 transition-colors disabled:opacity-50"
+ >
+ {isStarting ? "Starting..." : "Start Chain"}
+ </button>
)}
{chain.status === "active" && (
<button
diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts
index a08cba7..6a40aec 100644
--- a/makima/frontend/src/lib/api.ts
+++ b/makima/frontend/src/lib/api.ts
@@ -3323,7 +3323,6 @@ export interface UpdateContractDefinitionRequest {
/** Response when starting a chain */
export interface StartChainResponse {
chainId: string;
- supervisorTaskId: string | null;
contractsCreated: string[];
status: string;
}
@@ -3422,30 +3421,10 @@ export async function getChainDefinitionGraph(
return res.json();
}
-/** Options for starting a chain */
-export interface StartChainOptions {
- /** Whether to create a supervisor task that monitors chain progress */
- withSupervisor?: boolean;
- /** Repository URL for the supervisor task to work with */
- repositoryUrl?: string;
-}
-
-/** Start a chain (creates root contracts and optionally spawns supervisor) */
-export async function startChain(
- chainId: string,
- options?: StartChainOptions
-): Promise<StartChainResponse> {
- const body = options
- ? JSON.stringify({
- withSupervisor: options.withSupervisor ?? false,
- repositoryUrl: options.repositoryUrl,
- })
- : undefined;
-
+/** Start a chain (creates root contracts based on DAG) */
+export async function startChain(chainId: string): Promise<StartChainResponse> {
const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/start`, {
method: "POST",
- headers: body ? { "Content-Type": "application/json" } : undefined,
- body,
});
if (!res.ok) {
const error = await res.json().catch(() => ({ message: res.statusText }));
@@ -3454,7 +3433,7 @@ export async function startChain(
return res.json();
}
-/** Stop a chain (kills supervisor, marks as archived) */
+/** Stop a chain (marks as archived) */
export async function stopChain(chainId: string): Promise<{ stopped: boolean; status: string }> {
const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/stop`, {
method: "POST",
diff --git a/makima/src/bin/makima.rs b/makima/src/bin/makima.rs
index fa5378f..2037b47 100644
--- a/makima/src/bin/makima.rs
+++ b/makima/src/bin/makima.rs
@@ -612,95 +612,6 @@ async fn run_supervisor(
.await?;
println!("{}", serde_json::to_string(&result.0)?);
}
- // Chain supervisor commands
- SupervisorCommand::ChainStatus(args) => {
- let client = ApiClient::new(args.common.api_url, args.common.api_key)?;
- eprintln!("Getting chain status for {}...", args.common.chain_id);
- let result = client.get_chain(args.common.chain_id).await?;
- if args.verbose {
- // Get contracts as well
- let contracts = client.get_chain_contracts(args.common.chain_id).await?;
- println!("{}", serde_json::to_string(&serde_json::json!({
- "chain": result.0,
- "contracts": contracts.0
- }))?);
- } else {
- println!("{}", serde_json::to_string(&result.0)?);
- }
- }
- SupervisorCommand::ChainContracts(args) => {
- let client = ApiClient::new(args.common.api_url, args.common.api_key)?;
- eprintln!("Listing contracts in chain {}...", args.common.chain_id);
- let result = client.get_chain_contracts(args.common.chain_id).await?;
- if let Some(status) = &args.status {
- // Filter by status client-side
- let empty_vec = vec![];
- let contracts: Vec<_> = result.0.as_array()
- .unwrap_or(&empty_vec)
- .iter()
- .filter(|c| c.get("status").and_then(|s| s.as_str()) == Some(status.as_str()))
- .collect();
- println!("{}", serde_json::to_string(&contracts)?);
- } else {
- println!("{}", serde_json::to_string(&result.0)?);
- }
- }
- SupervisorCommand::ChainProgress(args) => {
- let client = ApiClient::new(args.common.api_url, args.common.api_key)?;
- eprintln!("Triggering chain progression for {}...", args.common.chain_id);
- // Use the start endpoint to progress (it handles already-active chains)
- let result = client.start_chain(args.common.chain_id).await;
- match result {
- Ok(r) => println!("{}", serde_json::to_string(&r.0)?),
- Err(e) => {
- // Check if already active - in that case, just get status
- if e.to_string().contains("ALREADY_ACTIVE") {
- eprintln!("Chain is already active, checking current status...");
- let status = client.get_chain(args.common.chain_id).await?;
- println!("{}", serde_json::to_string(&status.0)?);
- } else {
- return Err(e.into());
- }
- }
- }
- }
- SupervisorCommand::ChainGraph(args) => {
- let client = ApiClient::new(args.common.api_url, args.common.api_key)?;
- let result = client.get_chain_graph(args.common.chain_id).await?;
- if args.format == "json" {
- println!("{}", serde_json::to_string(&result.0)?);
- } else {
- // ASCII visualization (similar to chain graph command)
- if let Some(nodes) = result.0.get("nodes").and_then(|n| n.as_array()) {
- // Group by depth
- let mut by_depth: std::collections::BTreeMap<i64, Vec<(&str, &str)>> =
- std::collections::BTreeMap::new();
- for node in nodes {
- let name = node.get("name").and_then(|n| n.as_str()).unwrap_or("?");
- let status = node.get("status").and_then(|s| s.as_str()).unwrap_or("pending");
- let depth = node.get("depth").and_then(|d| d.as_i64()).unwrap_or(0);
- by_depth.entry(depth).or_default().push((name, status));
- }
- let chain_name = result.0.get("name").and_then(|v| v.as_str()).unwrap_or("Chain");
- println!("Chain: {}", chain_name);
- println!();
- for (depth, contracts) in by_depth {
- let prefix = " ".repeat(depth as usize);
- for (name, status) in contracts {
- let icon = match status {
- "completed" => "\u{2713}",
- "active" => "\u{21bb}",
- "failed" => "\u{2717}",
- _ => "\u{25cb}",
- };
- println!("{}[{}] {} ({})", prefix, icon, name, status);
- }
- }
- } else {
- println!("{}", serde_json::to_string(&result.0)?);
- }
- }
- }
}
Ok(())
diff --git a/makima/src/daemon/cli/mod.rs b/makima/src/daemon/cli/mod.rs
index 25163c2..035a784 100644
--- a/makima/src/daemon/cli/mod.rs
+++ b/makima/src/daemon/cli/mod.rs
@@ -170,20 +170,6 @@ pub enum SupervisorCommand {
/// Mark a deliverable as complete
MarkDeliverable(supervisor::MarkDeliverableArgs),
-
- // Chain supervisor commands (for chain-level orchestration)
-
- /// Get chain status with progress info
- ChainStatus(supervisor::ChainStatusArgs),
-
- /// List contracts in the chain
- ChainContracts(supervisor::ChainContractsArgs),
-
- /// Manually trigger chain progression
- ChainProgress(supervisor::ChainProgressArgs),
-
- /// Get chain DAG visualization
- ChainGraph(supervisor::ChainGraphArgs),
}
/// Contract subcommands for task-contract interaction.
diff --git a/makima/src/daemon/cli/supervisor.rs b/makima/src/daemon/cli/supervisor.rs
index 0b52c9c..82d3900 100644
--- a/makima/src/daemon/cli/supervisor.rs
+++ b/makima/src/daemon/cli/supervisor.rs
@@ -446,66 +446,3 @@ pub struct ResumeContractArgs {
pub contract_id: Uuid,
}
-// ============================================================================
-// Chain Supervisor Command Args
-// ============================================================================
-
-/// Common arguments for chain supervisor commands.
-#[derive(Args, Debug, Clone)]
-pub struct ChainSupervisorArgs {
- /// API URL
- #[arg(long, env = "MAKIMA_API_URL", default_value = "https://api.makima.jp")]
- pub api_url: String,
-
- /// API key for authentication
- #[arg(long, env = "MAKIMA_API_KEY")]
- pub api_key: String,
-
- /// Current task ID (the chain supervisor's own task ID)
- #[arg(long, env = "MAKIMA_TASK_ID")]
- pub self_task_id: Option<Uuid>,
-
- /// Chain ID
- #[arg(long, env = "MAKIMA_CHAIN_ID")]
- pub chain_id: Uuid,
-}
-
-/// Arguments for chain-status command (get chain status with progress info).
-#[derive(Args, Debug)]
-pub struct ChainStatusArgs {
- #[command(flatten)]
- pub common: ChainSupervisorArgs,
-
- /// Include contract details
- #[arg(long)]
- pub verbose: bool,
-}
-
-/// Arguments for chain-contracts command (list contracts in the chain).
-#[derive(Args, Debug)]
-pub struct ChainContractsArgs {
- #[command(flatten)]
- pub common: ChainSupervisorArgs,
-
- /// Filter by status (active, completed, failed)
- #[arg(long)]
- pub status: Option<String>,
-}
-
-/// Arguments for chain-progress command (manually trigger chain progression).
-#[derive(Args, Debug)]
-pub struct ChainProgressArgs {
- #[command(flatten)]
- pub common: ChainSupervisorArgs,
-}
-
-/// Arguments for chain-graph command (get chain DAG visualization).
-#[derive(Args, Debug)]
-pub struct ChainGraphArgs {
- #[command(flatten)]
- pub common: ChainSupervisorArgs,
-
- /// Output format (ascii, json)
- #[arg(long, default_value = "ascii")]
- pub format: String,
-}
diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs
index 0b8ef43..4e569ec 100644
--- a/makima/src/db/models.rs
+++ b/makima/src/db/models.rs
@@ -3064,14 +3064,11 @@ pub struct UpdateContractDefinitionRequest {
pub editor_y: Option<f64>,
}
-/// Request to start a chain
+/// Request to start a chain (kept for backwards compatibility)
#[derive(Debug, Clone, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct StartChainRequest {
- /// Whether to create a supervisor task that monitors chain progress
- #[serde(default)]
- pub with_supervisor: bool,
- /// Repository URL for the supervisor task to work with
+ /// Repository URL (reserved for future use)
pub repository_url: Option<String>,
}
@@ -3080,7 +3077,6 @@ pub struct StartChainRequest {
#[serde(rename_all = "camelCase")]
pub struct StartChainResponse {
pub chain_id: Uuid,
- pub supervisor_task_id: Option<Uuid>,
/// Root contracts created (those with no dependencies)
pub contracts_created: Vec<Uuid>,
pub status: String,
diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs
index fb430ab..ec233ba 100644
--- a/makima/src/db/repository.rs
+++ b/makima/src/db/repository.rs
@@ -5687,22 +5687,6 @@ pub async fn get_chain_definition_graph(
}))
}
-/// Set the supervisor task ID for a chain.
-pub async fn set_chain_supervisor_task(
- pool: &PgPool,
- chain_id: Uuid,
- supervisor_task_id: Option<Uuid>,
-) -> Result<(), sqlx::Error> {
- sqlx::query(
- "UPDATE chains SET supervisor_task_id = $2, updated_at = NOW() WHERE id = $1",
- )
- .bind(chain_id)
- .bind(supervisor_task_id)
- .execute(pool)
- .await?;
- Ok(())
-}
-
/// Update chain status.
pub async fn update_chain_status(
pool: &PgPool,
diff --git a/makima/src/server/handlers/chains.rs b/makima/src/server/handlers/chains.rs
index ae19ca0..6cef72c 100644
--- a/makima/src/server/handlers/chains.rs
+++ b/makima/src/server/handlers/chains.rs
@@ -15,8 +15,8 @@ use uuid::Uuid;
use crate::db::models::{
AddContractDefinitionRequest, ChainContractDefinition, ChainContractDetail,
ChainDefinitionGraphResponse, ChainEditorData, ChainEvent, ChainGraphResponse, ChainSummary,
- ChainWithContracts, CreateChainRequest, CreateTaskRequest, StartChainRequest,
- StartChainResponse, UpdateChainRequest, UpdateContractDefinitionRequest,
+ ChainWithContracts, CreateChainRequest, StartChainRequest, StartChainResponse,
+ UpdateChainRequest, UpdateContractDefinitionRequest,
};
use crate::db::repository::{self, RepositoryError};
use crate::server::auth::Authenticated;
@@ -1067,7 +1067,7 @@ pub async fn start_chain(
State(state): State<SharedState>,
Authenticated(auth): Authenticated,
Path(chain_id): Path<Uuid>,
- body: Option<Json<StartChainRequest>>,
+ _body: Option<Json<StartChainRequest>>,
) -> impl IntoResponse {
let Some(ref pool) = state.db_pool else {
return (
@@ -1077,11 +1077,6 @@ pub async fn start_chain(
.into_response();
};
- let req = body.map(|b| b.0).unwrap_or(StartChainRequest {
- with_supervisor: false,
- repository_url: None,
- });
-
// Verify ownership and get chain
let chain = match repository::get_chain_for_owner(pool, chain_id, auth.owner_id).await {
Ok(Some(c)) => c,
@@ -1152,114 +1147,6 @@ pub async fn start_chain(
}
}
- // Create supervisor task if requested
- let mut supervisor_task_id: Option<Uuid> = None;
- if req.with_supervisor {
- let supervisor_name = format!("Chain Supervisor: {}", chain.name);
- let supervisor_plan = format!(
- r#"You are the supervisor for chain "{}".
-
-## Environment Variables
-- MAKIMA_CHAIN_ID={}
-- MAKIMA_API_URL (configured)
-- MAKIMA_API_KEY (configured)
-
-## Your Responsibilities
-1. Monitor chain progress by periodically checking chain status
-2. Validate that contracts are completing successfully
-3. Identify and report any issues or blockers
-4. Track the overall chain progress through the DAG
-
-## Available Commands
-Use these makima CLI commands to monitor the chain:
-
-```bash
-# Check chain status
-makima chain status {}
-
-# List contracts in the chain
-makima chain contracts {}
-
-# View the chain DAG with current status
-makima chain graph {} --with-status
-```
-
-## Monitoring Loop
-1. Check chain status every few minutes
-2. If a contract fails, investigate the issue
-3. Report progress to the user when milestones are reached
-4. Mark the chain as complete when all contracts finish
-
-## Current Chain Info
-- Chain ID: {}
-- Chain Name: {}
-- Total definitions: {}
-
-Begin monitoring the chain. Check the initial status and report what you find."#,
- chain.name,
- chain_id,
- chain_id,
- chain_id,
- chain_id,
- chain_id,
- chain.name,
- definitions.len()
- );
-
- let supervisor_req = CreateTaskRequest {
- name: supervisor_name,
- description: Some(format!("Supervisor task for chain: {}", chain.name)),
- plan: supervisor_plan,
- repository_url: req.repository_url.clone(),
- base_branch: None,
- target_branch: None,
- parent_task_id: None,
- contract_id: None, // Chain supervisor is not tied to a specific contract
- target_repo_path: None,
- completion_action: None,
- continue_from_task_id: None,
- copy_files: None,
- is_supervisor: true,
- checkpoint_sha: None,
- priority: 0,
- merge_mode: None,
- branched_from_task_id: None,
- conversation_history: None,
- supervisor_worktree_task_id: None,
- };
-
- match repository::create_task_for_owner(pool, auth.owner_id, supervisor_req).await {
- Ok(supervisor_task) => {
- tracing::info!(
- chain_id = %chain_id,
- supervisor_task_id = %supervisor_task.id,
- "Created supervisor task for chain"
- );
-
- // Update chain with supervisor_task_id
- if let Err(e) =
- repository::set_chain_supervisor_task(pool, chain_id, Some(supervisor_task.id))
- .await
- {
- tracing::warn!(
- chain_id = %chain_id,
- error = %e,
- "Failed to link supervisor task to chain"
- );
- }
-
- supervisor_task_id = Some(supervisor_task.id);
- }
- Err(e) => {
- tracing::warn!(
- chain_id = %chain_id,
- error = %e,
- "Failed to create supervisor task for chain"
- );
- }
- }
- }
-
// Progress the chain - this creates root contracts (definitions with no dependencies)
let progression = match repository::progress_chain(pool, chain_id, auth.owner_id).await {
Ok(p) => p,
@@ -1268,7 +1155,6 @@ Begin monitoring the chain. Check the initial status and report what you find."#
// Chain is active but no contracts created - return partial success
return Json(StartChainResponse {
chain_id,
- supervisor_task_id,
contracts_created: vec![],
status: "active".to_string(),
})
@@ -1278,7 +1164,6 @@ Begin monitoring the chain. Check the initial status and report what you find."#
Json(StartChainResponse {
chain_id,
- supervisor_task_id,
contracts_created: progression.contracts_created,
status: if progression.chain_completed {
"completed".to_string()
@@ -1357,20 +1242,7 @@ pub async fn stop_chain(
.into_response();
}
- // TODO: Kill the supervisor task if running
- // Clear supervisor task ID and set status to archived
- match repository::set_chain_supervisor_task(pool, chain_id, None).await {
- Ok(_) => {}
- Err(e) => {
- tracing::error!("Failed to clear chain supervisor: {}", e);
- return (
- StatusCode::INTERNAL_SERVER_ERROR,
- Json(ApiError::new("DB_ERROR", e.to_string())),
- )
- .into_response();
- }
- }
-
+ // Archive the chain
match repository::update_chain_status(pool, chain_id, "archived").await {
Ok(_) => Json(serde_json::json!({"stopped": true, "status": "archived"})).into_response(),
Err(e) => {