The great storkit name conversion
This commit is contained in:
@@ -160,8 +160,7 @@ struct AllTokenUsageResponse {
|
||||
pub fn story_is_archived(project_root: &path::Path, story_id: &str) -> bool {
|
||||
let work = project_root.join(".storkit").join("work");
|
||||
let filename = format!("{story_id}.md");
|
||||
work.join("5_done").join(&filename).exists()
|
||||
|| work.join("6_archived").join(&filename).exists()
|
||||
work.join("5_done").join(&filename).exists() || work.join("6_archived").join(&filename).exists()
|
||||
}
|
||||
|
||||
pub struct AgentsApi {
|
||||
@@ -215,11 +214,7 @@ impl AgentsApi {
|
||||
|
||||
self.ctx
|
||||
.agents
|
||||
.stop_agent(
|
||||
&project_root,
|
||||
&payload.0.story_id,
|
||||
&payload.0.agent_name,
|
||||
)
|
||||
.stop_agent(&project_root, &payload.0.story_id, &payload.0.agent_name)
|
||||
.await
|
||||
.map_err(bad_request)?;
|
||||
|
||||
@@ -258,9 +253,7 @@ impl AgentsApi {
|
||||
|
||||
/// Get the configured agent roster from project.toml.
|
||||
#[oai(path = "/agents/config", method = "get")]
|
||||
async fn get_agent_config(
|
||||
&self,
|
||||
) -> OpenApiResult<Json<Vec<AgentConfigInfoResponse>>> {
|
||||
async fn get_agent_config(&self) -> OpenApiResult<Json<Vec<AgentConfigInfoResponse>>> {
|
||||
let project_root = self
|
||||
.ctx
|
||||
.agents
|
||||
@@ -288,9 +281,7 @@ impl AgentsApi {
|
||||
|
||||
/// Reload project config and return the updated agent roster.
|
||||
#[oai(path = "/agents/config/reload", method = "post")]
|
||||
async fn reload_config(
|
||||
&self,
|
||||
) -> OpenApiResult<Json<Vec<AgentConfigInfoResponse>>> {
|
||||
async fn reload_config(&self) -> OpenApiResult<Json<Vec<AgentConfigInfoResponse>>> {
|
||||
let project_root = self
|
||||
.ctx
|
||||
.agents
|
||||
@@ -440,10 +431,8 @@ impl AgentsApi {
|
||||
.get_project_root(&self.ctx.state)
|
||||
.map_err(bad_request)?;
|
||||
|
||||
let file_results = crate::http::workflow::read_test_results_from_story_file(
|
||||
&project_root,
|
||||
&story_id.0,
|
||||
);
|
||||
let file_results =
|
||||
crate::http::workflow::read_test_results_from_story_file(&project_root, &story_id.0);
|
||||
|
||||
Ok(Json(
|
||||
file_results.map(|r| TestResultsResponse::from_story_results(&r)),
|
||||
@@ -467,8 +456,7 @@ impl AgentsApi {
|
||||
.get_project_root(&self.ctx.state)
|
||||
.map_err(bad_request)?;
|
||||
|
||||
let log_path =
|
||||
crate::agent_log::find_latest_log(&project_root, &story_id.0, &agent_name.0);
|
||||
let log_path = crate::agent_log::find_latest_log(&project_root, &story_id.0, &agent_name.0);
|
||||
|
||||
let Some(path) = log_path else {
|
||||
return Ok(Json(AgentOutputResponse {
|
||||
@@ -480,10 +468,13 @@ impl AgentsApi {
|
||||
|
||||
let output: String = entries
|
||||
.iter()
|
||||
.filter(|e| {
|
||||
e.event.get("type").and_then(|t| t.as_str()) == Some("output")
|
||||
.filter(|e| e.event.get("type").and_then(|t| t.as_str()) == Some("output"))
|
||||
.filter_map(|e| {
|
||||
e.event
|
||||
.get("text")
|
||||
.and_then(|t| t.as_str())
|
||||
.map(str::to_owned)
|
||||
})
|
||||
.filter_map(|e| e.event.get("text").and_then(|t| t.as_str()).map(str::to_owned))
|
||||
.collect();
|
||||
|
||||
Ok(Json(AgentOutputResponse { output }))
|
||||
@@ -562,9 +553,7 @@ impl AgentsApi {
|
||||
///
|
||||
/// Returns the full history from the persistent token_usage.jsonl log.
|
||||
#[oai(path = "/token-usage", method = "get")]
|
||||
async fn get_all_token_usage(
|
||||
&self,
|
||||
) -> OpenApiResult<Json<AllTokenUsageResponse>> {
|
||||
async fn get_all_token_usage(&self) -> OpenApiResult<Json<AllTokenUsageResponse>> {
|
||||
let project_root = self
|
||||
.ctx
|
||||
.agents
|
||||
@@ -659,9 +648,7 @@ mod tests {
|
||||
ctx.agents
|
||||
.inject_test_agent("80_story_active", "coder-1", AgentStatus::Running);
|
||||
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.list_agents().await.unwrap().0;
|
||||
|
||||
// Archived story's agent should not appear
|
||||
@@ -686,9 +673,7 @@ mod tests {
|
||||
ctx.agents
|
||||
.inject_test_agent("42_story_whatever", "coder-1", AgentStatus::Completed);
|
||||
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.list_agents().await.unwrap().0;
|
||||
assert!(result.iter().any(|a| a.story_id == "42_story_whatever"));
|
||||
}
|
||||
@@ -705,9 +690,7 @@ mod tests {
|
||||
async fn get_agent_config_returns_default_when_no_toml() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.get_agent_config().await.unwrap().0;
|
||||
// Default config has one agent named "default"
|
||||
assert_eq!(result.len(), 1);
|
||||
@@ -734,9 +717,7 @@ model = "haiku"
|
||||
"#,
|
||||
);
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.get_agent_config().await.unwrap().0;
|
||||
assert_eq!(result.len(), 2);
|
||||
assert_eq!(result[0].name, "coder-1");
|
||||
@@ -753,9 +734,7 @@ model = "haiku"
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.get_agent_config().await;
|
||||
assert!(result.is_err());
|
||||
}
|
||||
@@ -766,9 +745,7 @@ model = "haiku"
|
||||
async fn reload_config_returns_default_when_no_toml() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.reload_config().await.unwrap().0;
|
||||
assert_eq!(result.len(), 1);
|
||||
assert_eq!(result[0].name, "default");
|
||||
@@ -788,9 +765,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
"#,
|
||||
);
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.reload_config().await.unwrap().0;
|
||||
assert_eq!(result.len(), 1);
|
||||
assert_eq!(result[0].name, "supervisor");
|
||||
@@ -807,9 +782,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.reload_config().await;
|
||||
assert!(result.is_err());
|
||||
}
|
||||
@@ -820,9 +793,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
async fn list_worktrees_returns_empty_when_no_worktree_dir() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.list_worktrees().await.unwrap().0;
|
||||
assert!(result.is_empty());
|
||||
}
|
||||
@@ -835,9 +806,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
std::fs::create_dir_all(worktrees_dir.join("43_story_bar")).unwrap();
|
||||
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let mut result = api.list_worktrees().await.unwrap().0;
|
||||
result.sort_by(|a, b| a.story_id.cmp(&b.story_id));
|
||||
|
||||
@@ -851,9 +820,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.list_worktrees().await;
|
||||
assert!(result.is_err());
|
||||
}
|
||||
@@ -865,9 +832,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.stop_agent(Json(StopAgentPayload {
|
||||
story_id: "42_story_foo".to_string(),
|
||||
@@ -881,9 +846,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
async fn stop_agent_returns_error_when_agent_not_found() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.stop_agent(Json(StopAgentPayload {
|
||||
story_id: "nonexistent_story".to_string(),
|
||||
@@ -899,9 +862,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
ctx.agents
|
||||
.inject_test_agent("42_story_foo", "coder-1", AgentStatus::Running);
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.stop_agent(Json(StopAgentPayload {
|
||||
story_id: "42_story_foo".to_string(),
|
||||
@@ -920,9 +881,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.start_agent(Json(StartAgentPayload {
|
||||
story_id: "42_story_foo".to_string(),
|
||||
@@ -949,9 +908,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
)
|
||||
.unwrap();
|
||||
let ctx = AppContext::new_test(root.to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_work_item_content(Path("42_story_foo".to_string()))
|
||||
.await
|
||||
@@ -973,9 +930,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
)
|
||||
.unwrap();
|
||||
let ctx = AppContext::new_test(root.to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_work_item_content(Path("43_story_bar".to_string()))
|
||||
.await
|
||||
@@ -989,9 +944,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
async fn get_work_item_content_returns_not_found_when_absent() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_work_item_content(Path("99_story_nonexistent".to_string()))
|
||||
.await;
|
||||
@@ -1003,9 +956,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_work_item_content(Path("42_story_foo".to_string()))
|
||||
.await;
|
||||
@@ -1018,9 +969,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
async fn get_agent_output_returns_empty_when_no_log_exists() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_agent_output(
|
||||
Path("42_story_foo".to_string()),
|
||||
@@ -1040,8 +989,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let root = tmp.path();
|
||||
|
||||
let mut writer =
|
||||
AgentLogWriter::new(root, "42_story_foo", "coder-1", "sess-test").unwrap();
|
||||
let mut writer = AgentLogWriter::new(root, "42_story_foo", "coder-1", "sess-test").unwrap();
|
||||
|
||||
writer
|
||||
.write_event(&AgentEvent::Status {
|
||||
@@ -1073,9 +1021,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
.unwrap();
|
||||
|
||||
let ctx = AppContext::new_test(root.to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_agent_output(
|
||||
Path("42_story_foo".to_string()),
|
||||
@@ -1094,9 +1040,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_agent_output(
|
||||
Path("42_story_foo".to_string()),
|
||||
@@ -1113,9 +1057,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.create_worktree(Json(CreateWorktreePayload {
|
||||
story_id: "42_story_foo".to_string(),
|
||||
@@ -1129,9 +1071,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
// project_root is set but has no git repo — git worktree add will fail
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.create_worktree(Json(CreateWorktreePayload {
|
||||
story_id: "42_story_foo".to_string(),
|
||||
@@ -1147,12 +1087,8 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
*ctx.state.project_root.lock().unwrap() = None;
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let result = api
|
||||
.remove_worktree(Path("42_story_foo".to_string()))
|
||||
.await;
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api.remove_worktree(Path("42_story_foo".to_string())).await;
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
@@ -1161,9 +1097,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
// project_root is set but no worktree exists for this story_id
|
||||
let ctx = AppContext::new_test(tmp.path().to_path_buf());
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.remove_worktree(Path("nonexistent_story".to_string()))
|
||||
.await;
|
||||
@@ -1177,9 +1111,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let root = make_work_dirs(&tmp);
|
||||
let ctx = AppContext::new_test(root);
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_test_results(Path("42_story_foo".to_string()))
|
||||
.await
|
||||
@@ -1214,9 +1146,7 @@ allowed_tools = ["Read", "Bash"]
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_test_results(Path("42_story_foo".to_string()))
|
||||
.await
|
||||
@@ -1255,7 +1185,7 @@ name: "Test story"
|
||||
|
||||
## Test Results
|
||||
|
||||
<!-- story-kit-test-results: {"unit":[{"name":"from_file","status":"pass","details":null}],"integration":[]} -->
|
||||
<!-- storkit-test-results: {"unit":[{"name":"from_file","status":"pass","details":null}],"integration":[]} -->
|
||||
"#;
|
||||
std::fs::write(
|
||||
root.join(".storkit/work/2_current/42_story_foo.md"),
|
||||
@@ -1264,9 +1194,7 @@ name: "Test story"
|
||||
.unwrap();
|
||||
|
||||
let ctx = AppContext::new_test(root);
|
||||
let api = AgentsApi {
|
||||
ctx: Arc::new(ctx),
|
||||
};
|
||||
let api = AgentsApi { ctx: Arc::new(ctx) };
|
||||
let result = api
|
||||
.get_test_results(Path("42_story_foo".to_string()))
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user