mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-06 02:48:25 +00:00
Strip markdown headings and "Plan:" prefix from GOAL column in fabro ps (#111)
This change cleans up the `GOAL` column in `fabro ps` output by
stripping common markdown noise before displaying goal text.
Specifically, `truncate_goal` now removes leading `#` heading markers
and an optional `Plan:` prefix (applied in order, so `## Plan: migrate
DB` correctly becomes `migrate DB`). Whitespace is trimmed after each
strip step to avoid leading spaces in the result.
As a minor refactor, the truncation logic was extracted into a
standalone `truncate_str` helper. This allows `truncate_goal` to
delegate cleanly after preprocessing, and also lets the workflow name
column (which doesn't need heading/prefix stripping) call `truncate_str`
directly. Five new unit tests cover the stripping behavior, combined
stripping, passthrough of plain text, and that truncation still applies
correctly after stripping.
### Fabro Details
<details>
<summary>Ran 9 stages in 9m 0s for $1.17</summary>
| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 0s | – | 0 |
| preflight_compile | 1m 10s | – | 0 |
| preflight_lint | 12s | – | 0 |
| implement | 2m 28s | $0.42 | 0 |
| simplify_opus | 3m 20s | $0.75 | 0 |
| simplify_gpt | 0s | – | 0 |
| verify | 1m 20s | – | 0 |
| fmt | 1s | – | 0 |
| **Total** | **9m 0s** | **$1.17** | **0** |
</details>
<details>
<summary>Ran <code>ImplementAndSimplify.fabro</code> (12 nodes and 15
edges)</summary>
```dot
digraph ImplementAndSimplify {
graph [
goal="Implement and simplify",
model_stylesheet="
* { backend: api; model: claude-opus-4-6;}
"
]
rankdir=LR
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
toolchain [label="Toolchain", shape=parallelogram, script="command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", max_retries=0]
preflight_compile [label="Preflight Compile", shape=parallelogram, script="cargo check -q --workspace 2>&1", max_retries=0]
preflight_lint [label="Preflight Lint", shape=parallelogram, script="cargo clippy -q --workspace -- -D warnings 2>&1", max_retries=0]
fix_lints [label="Fix Lints", prompt="The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.", max_visits=3]
implement [label="Implement", prompt="Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan. Use red/green TDD."]
simplify_opus [label="Simplify (Opus)", prompt="@prompts/simplify.md"]
simplify_gpt [label="Simplify (GPT-54)", prompt="@prompts/simplify.md", model="gpt-54"]
verify [label="Verify", shape=parallelogram, script="cargo clippy -q --workspace -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1", goal_gate=true, retry_target="fixup"]
fixup [label="Fixup", prompt="The verify step failed. Read the build output from context and fix all clippy lint warnings and test failures.", max_visits=3]
fmt [label="Format", shape=parallelogram, script="cargo fmt --all 2>&1", max_retries=0]
start -> toolchain
toolchain -> preflight_compile [condition="outcome=success"]
toolchain -> exit
preflight_compile -> preflight_lint [condition="outcome=success"]
preflight_compile -> exit
preflight_lint -> implement [condition="outcome=success"]
preflight_lint -> fix_lints
fix_lints -> preflight_lint
implement -> simplify_opus -> simplify_gpt -> verify
verify -> fmt [condition="outcome=success"]
verify -> fixup
fixup -> verify
fmt -> exit
}
```
</details>
⚒️ Generated with [Fabro](https://fabro.sh)
---------
Co-authored-by: Fabro <noreply@fabro.sh>
This commit is contained in:
parent
62c310bcec
commit
4a5f9f698f
1 changed files with 40 additions and 4 deletions
|
|
@ -228,11 +228,17 @@ fn short_run_id(id: &str) -> &str {
|
|||
|
||||
fn truncate_goal(goal: &str, max_len: usize) -> String {
|
||||
let line = goal.lines().next().unwrap_or("");
|
||||
let char_count = line.chars().count();
|
||||
let line = line.trim_start_matches('#').trim();
|
||||
let line = line.strip_prefix("Plan:").map(|s| s.trim()).unwrap_or(line);
|
||||
truncate_str(line, max_len)
|
||||
}
|
||||
|
||||
fn truncate_str(s: &str, max_len: usize) -> String {
|
||||
let char_count = s.chars().count();
|
||||
if char_count <= max_len {
|
||||
return line.to_string();
|
||||
return s.to_string();
|
||||
}
|
||||
let truncated: String = line.chars().take(max_len - 3).collect();
|
||||
let truncated: String = s.chars().take(max_len - 3).collect();
|
||||
format!("{truncated}...")
|
||||
}
|
||||
|
||||
|
|
@ -404,7 +410,7 @@ fn df_from(args: &DfArgs, data_dir: &Path, runs_base: &Path, logs_base: &Path) -
|
|||
};
|
||||
vec![
|
||||
short_run_id(&detail.run_id).cell(),
|
||||
truncate_goal(&detail.workflow_name, 16).cell(),
|
||||
truncate_str(&detail.workflow_name, 16).cell(),
|
||||
detail.status.to_string().cell(),
|
||||
age.cell().justify(Justify::Right),
|
||||
size_display.cell().justify(Justify::Right),
|
||||
|
|
@ -588,4 +594,34 @@ mod tests {
|
|||
assert_eq!(format_size(1024), "1.0 KB");
|
||||
assert_eq!(format_size(1024 * 1024), "1.0 MB");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate_goal_strips_markdown_headings() {
|
||||
assert_eq!(truncate_goal("## Fix bug", 50), "Fix bug");
|
||||
assert_eq!(truncate_goal("# Title", 50), "Title");
|
||||
assert_eq!(truncate_goal("### Deep heading", 50), "Deep heading");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate_goal_strips_plan_prefix() {
|
||||
assert_eq!(truncate_goal("Plan: do stuff", 50), "do stuff");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate_goal_strips_heading_and_plan_prefix() {
|
||||
assert_eq!(truncate_goal("## Plan: migrate DB", 50), "migrate DB");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate_goal_plain_text_unchanged() {
|
||||
assert_eq!(truncate_goal("Fix the login bug", 50), "Fix the login bug");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate_goal_still_truncates_after_stripping() {
|
||||
assert_eq!(
|
||||
truncate_goal("## A long goal description", 10),
|
||||
"A long ..."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue