pub const TEMPLATE_PACK_STATUS: &str = "{%- macro render_pack(pack, view_mode) -%}\n{%- if view_mode == \"short\" -%}\n{{ pack.name | col(32) }} ({{ pack.summary_count }}) [{{ pack.summary_status }}]{{ pack.summary_status }}[/{{ pack.summary_status }}]\n{% else -%}\n[pack-name]{{ pack.name }}[/pack-name]\n{% for file in pack.files %} {{ file.name | col(24) }} [handler-symbol]{{ file.symbol }}[/handler-symbol] [description]{{ file.description | col(30) }}[/description] [{{ file.status }}]{{ file.status_label }}[/{{ file.status }}]{% if file.note_ref %} [dim][{{ file.note_ref }}][/dim]{% endif %}\n{% endfor %}\n{%- endif -%}\n{%- endmacro -%}\n{% if conflicts %}[conflict-banner] \u{2717} Cross-pack conflicts detected \u{2014} see details below [/conflict-banner]\n{% endif %}{% if message %}[message]{{ message }}[/message]\n{% endif %}{% if dry_run %}[dry-run] (dry run \u{2014} no changes made)[/dry-run]\n{% endif %}{% if group_mode == \"status\" %}{% if ignored_packs %}[group-banner-ignored]Ignored Packs[/group-banner-ignored]\n{% for name in ignored_packs %} [ignored-pack]{{ name }}[/ignored-pack]\n{% endfor %}\n{% endif %}{% set deployed_group = packs | selectattr(\"summary_status\", \"equalto\", \"deployed\") | list %}{% if deployed_group %}[group-banner-deployed]Deployed Packs[/group-banner-deployed]\n{% for pack in deployed_group %}{{ render_pack(pack, view_mode) }}{% endfor %}\n{% endif %}{% set pending_group = packs | selectattr(\"summary_status\", \"equalto\", \"pending\") | list %}{% if pending_group %}[group-banner-pending]Pending Packs[/group-banner-pending]\n{% for pack in pending_group %}{{ render_pack(pack, view_mode) }}{% endfor %}\n{% endif %}{% set error_group = packs | selectattr(\"summary_status\", \"equalto\", \"error\") | list %}{% if error_group %}[group-banner-error]Error Packs[/group-banner-error]\n{% for pack in error_group %}{{ render_pack(pack, view_mode) }}{% endfor %}\n{% endif %}{% else %}{% for pack in packs %}{{ render_pack(pack, view_mode) }}{% endfor %}{% if ignored_packs %}[pack-name]Ignored Packs[/pack-name]\n{% for name in ignored_packs %} [ignored-pack]{{ name }}[/ignored-pack]\n{% endfor %}{% endif %}{% endif %}{% if notes %}\n[header]Errors:[/header]\n{% for note in notes %} [dim][{{ loop.index }}][/dim] {{ note.body }}\n{% if note.hint %} [dim]hint:[/dim] {{ note.hint }}\n{% endif %}{% endfor %}{% endif %}{% if conflicts %}\n[conflict-header] Cross-pack conflicts [/conflict-header]\n{% for c in conflicts %}\n{% if c.kind == \"symlink\" %}The target path [conflict-target]{{ c.target }}[/conflict-target] would be used by multiple packs:\n{% else %}The executable [conflict-target]{{ c.target }}[/conflict-target] would be shadowed across multiple packs in $PATH:\n{% endif %}{% for cl in c.claimants %} - [conflict-pack]{{ cl.source }}[/conflict-pack]\n{% endfor %}{% endfor %}\n[conflict-hint]Common fixes: give them unique names, override the destination in the pack\'s config,[/conflict-hint]\n[conflict-hint]or ignore the pack entirely. See `dodot config --help` for the last option.[/conflict-hint]\n[conflict-hint]`dodot up` won\'t run while conflicts exist.[/conflict-hint]\n{% endif %}";Expand description
Status / up / down — pack-level output with file listings.
Per-item errors are surfaced as [N] markers next to the status label;
their bodies render in a dedicated Errors: section at the bottom so
the per-file columns stay single-line and aligned regardless of how
long an individual error message is.