{% extends "curb_base.html" %} {# Projects › CI: agent steps in each project's workflows, the export, and the safe fixes. #} {% block scope %}{{ k.picker(project) }}{% endblock %} {% block part %} {% set mine = view.fixable | selectattr("project", "equalto", one.name) | list if one else [] %} {% set fixes = mine | sum(attribute="fixes", start=[]) | length %}
{% call k.head("Agent steps in your GitHub Actions workflows, and what an outsider could make them do.", "Read from .github/workflows in each project. Nothing is run." ~ ("" if one or not projects else " Pick one project to export or fix.")) %} {{ k.again() }} {% if one and view.rows %} {{ ico.icon('download', 14) }} Export for code scanning {% endif %} {% if one and fixes %}{{ k.act("Apply " ~ fixes ~ (" safe fix" if fixes == 1 else " safe fixes"), "cifix", "btn-primary") }}{% endif %} {% endcall %} {% for line in view.problems %}
Curb could not read a workflow. {{ line }}
{% endfor %} {% if not projects %} {% call empty.state("project", "No projects yet") %}

Curb checks the projects on your Projects page. Add one there first.

New project {% endcall %} {% elif view.rows %}
Findings {{ k.tally() }} {% call k.tools("Search findings", {"project": project}) %} {% endcall %}
RiskWorkflow{% if not one %}Project{% endif %}Problem, and the fix
{% for row in table.rows %}
{{ k.risk(row.level, row.tone) }} {{ row.where }}{{ row.step }} {% if not one %}{{ row.project }}{% endif %} {{ row.why }}{% if row.fix %}{{ row.fix }}{% endif %}
{% endfor %} {{ k.foot("No finding matches that search.") }}
{% else %} {% call empty.state("clear", "No agent steps found") %}

No workflow in {{ one.name if one else "your projects" }} runs Claude Code, Codex or Gemini CLI.

{% endcall %} {% endif %} {% call k.explain("Check every pull request", "The same check, as a GitHub Action.") %}

Add this step to a workflow. It writes its findings to GitHub code scanning, so they show on the pull request that causes them.

{{ k.cmd("uses: elandlabs/flanner/actions/curb-ci@v" ~ app_version) }}

Safe fixes are one-line changes that cannot break a workflow, such as removing a flag that skips permission checks. The rest need your judgement.

{{ k.cmd("flanner curb ci --fix") }} {% endcall %}
{% endblock %} {% block reviews %} {% if one %} {% set mine = view.fixable | selectattr("project", "equalto", one.name) | list %} {% call k.review_box("cifix", "Apply the safe fixes in " ~ one.name ~ "?", "/curb/projects/ci/fix", {"project": one.id}) %}

Curb edits the workflow files in your working folder. It commits nothing.

To undo, discard the changes with git. Read them, then open a pull request.

{% endcall %} {% endif %} {% endblock %}