mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-08 17:10:50 -10:00
fix(workflow,skills): portable receipt report path; clippy type alias; warm rustfmt in test
- Workflow receipts rendered the report path with Path::display, so Windows emitted `.codewhale\reports\<id>.md`. written_run_report now returns a `/`-joined workspace-relative string on every platform (fixes the two windows-latest workflow receipt tests). - parse_frontmatter's return type tripped clippy::type_complexity under -D warnings; name it with a `Frontmatter<'a>` alias. - patch_normalizes_rust_in_an_already_clean_file warms the rustfmt proxy first: a cold Windows runner exceeded the 5s formatter budget on the first launch (5.23s), which skips normalization by design. Pre-existing flake, passes on other branches in 1.4-3.1s. Local: cargo clippy -p codewhale-tui --all-targets --all-features with CI flags clean; cargo test -p codewhale-tui --lib (workflow, apply_patch, rust_format, skills filters) 415 passed, 0 failed; cargo fmt --check and git diff --check clean; check-versions.sh --range-audit-advisory OK. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
This commit is contained in:
1 parent
9225bed083
commit
8bc34f9bf4
4 files changed
+21
-6
No files matched your search
@@ -762,6 +762,9 @@ fn is_valid_skill_name(name: &str) -> bool {
|
||||
.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '-')
|
||||
}
|
||||
|
||||
/// Parsed frontmatter: lowercased metadata keys and the body after the fence.
|
||||
pub(crate) type Frontmatter<'a> = (HashMap<String, String>, &'a str);
|
||||
|
||||
/// Split a Markdown file into its `---` frontmatter metadata and body.
|
||||
///
|
||||
/// Returns `Ok(None)` when the file does not open with a `---` fence. Keys are
|
||||
@@ -770,7 +773,7 @@ fn is_valid_skill_name(name: &str) -> bool {
|
||||
/// one frontmatter reader: skills and Claude Code agent files both use it.
|
||||
pub(crate) fn parse_frontmatter(
|
||||
content: &str,
|
||||
) -> std::result::Result<Option<(HashMap<String, String>, &str)>, String> {
|
||||
) -> std::result::Result<Option<Frontmatter<'_>>, String> {
|
||||
if !content.trim_start().starts_with("---") {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -1677,6 +1677,12 @@ mod tests {
|
||||
/// text, so the model's next patch context matches the bytes on disk.
|
||||
#[tokio::test]
|
||||
async fn patch_normalizes_rust_in_an_already_clean_file() {
|
||||
// Warm the `rustfmt` proxy first: on a cold CI runner the first rustup
|
||||
// shim launch alone can exceed the formatter's 5s budget, which skips
|
||||
// normalization (by design) and fails this test for the wrong reason.
|
||||
let _ = std::process::Command::new("rustfmt")
|
||||
.arg("--version")
|
||||
.output();
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let ctx = ToolContext::new(tmp.path().to_path_buf());
|
||||
let file = tmp.path().join("clean.rs");
|
||||
|
||||
@@ -337,8 +337,7 @@ fn finish_workflow_controller(state: &WorkflowWorkspaceState, record: &WorkflowR
|
||||
"child_count": record.child_ids.len(),
|
||||
"detail": { "tool": "workflow", "action": "status", "run_id": truncate_chars(&record.run_id, 64) },
|
||||
});
|
||||
let report = written_run_report(&controller.driver.workspace, &record.run_id)
|
||||
.map(|path| path.display().to_string());
|
||||
let report = written_run_report(&controller.driver.workspace, &record.run_id);
|
||||
if let Some(report) = &report {
|
||||
receipt["report"] = json!(report);
|
||||
}
|
||||
|
||||
@@ -52,10 +52,17 @@ fn run_report_relative_path(run_id: &str) -> Option<PathBuf> {
|
||||
}
|
||||
|
||||
/// The run's report path relative to the workspace, only when the report
|
||||
/// was actually written.
|
||||
pub(super) fn written_run_report(workspace: &Path, run_id: &str) -> Option<PathBuf> {
|
||||
/// was actually written. Always `/`-separated: the path is shown to the model
|
||||
/// and the user in receipts, and must read the same on every platform.
|
||||
pub(super) fn written_run_report(workspace: &Path, run_id: &str) -> Option<String> {
|
||||
let relative = run_report_relative_path(run_id)?;
|
||||
workspace.join(&relative).is_file().then_some(relative)
|
||||
workspace.join(&relative).is_file().then(|| {
|
||||
relative
|
||||
.components()
|
||||
.map(|part| part.as_os_str().to_string_lossy())
|
||||
.collect::<Vec<_>>()
|
||||
.join("/")
|
||||
})
|
||||
}
|
||||
|
||||
/// Bounded preview of a raw `responseSchema` reply for run records and
|
||||
|
||||
Reference in new issue
Block a user