Files
OrcaSlicer/AGENTS.md
T
packerlschupfer 9321f24959 CLI: --strict, and a warnings array in result.json (#14601)
# Description

Add `--strict` for CI and scripted pipelines, and a structured
`warnings`
array in `result.json`.

## `--strict`

A NON_CRITICAL slicing warning is logged and the slice succeeds: return
code
`0`, G-code written. That suits interactive use, but a pipeline then
ships a
slice with a warning nobody saw. With `--strict`, such a warning fails
the run
with `CLI_SLICING_ERROR` before the G-code is exported. Without the
flag,
nothing changes.

In FFF the warning that reaches this path is "support needed but
disabled"
(`PrintObject::generate_support_material`). `--no-check` skips that
check, so
`--strict --no-check` is rejected with `CLI_INVALID_PARAMS`.

`--strict` is read before any work, so it doesn't depend on argument
order and
`result.json` reports it for early failures as well.

## `result.json`

Two new top-level fields:

- `warnings`: `[{"class", ...details}]`. One class is wired:
`slicing_warning_non_critical` with `plate_id` and `text`, recorded
whenever
such a warning fires, with or without `--strict`. The array also fills
on
  runs that succeed, so `return_code` stays the verdict.
- `strict_mode`: whether `--strict` was on.

`record_exit_reson` writes `result.json` on Linux only, so both fields
exist
only there. The non-zero exit works on every platform.

## Tests

- `tests/fff_print/test_support_material.cpp` (all platforms): an
overhang
sliced with support off raises the NON_CRITICAL support-needed status,
and
  the no-check flag suppresses it.
- `tests/cli/test_cli_strict.sh` (Linux only): runs `orca-slicer`
without
flags, with `--strict`, and with `--strict --no-check`, and checks the
shell
status and `result.json` of each. It runs the built binary, so it
carries the
`RequiresApp` label, which `scripts/run_unit_tests.sh` excludes because
the
  unit-test job only receives `build/tests`. Run it with
  `ctest --test-dir build/tests -C Release -L RequiresApp`.
- CI: `unit_tests.yml` now passes `Release` on Linux too.
`build_linux.sh`
configures Ninja Multi-Config, and without a config ctest drops the
labels of
plain `add_test()` tests, so this test ran as "Not Run" instead of being
excluded. The docs that assumed Linux was single-config are corrected
too.

Built and run locally on Linux (GCC 14) on current `main`: both tests
pass,
and the touched files compile clean under Clang with `-Werror`.
2026-09-16 12:54:48 +08:00

7.1 KiB

CLAUDE.md

OrcaSlicer — open-source C++17 3D slicer. wxWidgets GUI, CMake build system.

Build Commands

# macOS
cmake --build build/arm64 --config RelWithDebInfo --target all --

# Linux
cmake --build build --config RelWithDebInfo --target all --

# Windows (replace %build_type% with Debug/Release/RelWithDebInfo)
cmake --build . --config %build_type% --target ALL_BUILD -- -m

Testing

Catch2 framework. Tests in tests/; see tests/AGENTS.md for where a new test belongs and the conventions to follow.

cd build && ctest -C Release --output-on-failure    # all tests
ctest --test-dir ./tests/libslic3r -C Release       # individual suite
ctest --test-dir ./tests/fff_print -C Release

Documentation

  • Docs live in docs/; the high-level design of a subsystem goes in docs/HLSD/<subsystem>.md.
  • Describe the design as it stands — what the subsystem does, why it exists, and the constraints that shape it. Not the route that got there: no phases, task lists, status markers, or "before/after this PR" framing.
  • Planning and investigation output (brainstorms, superpowers design and plan docs) stays in docs/superpowers/, which is gitignored. Never commit it.
  • Write a doc only when the design is not evident from the code, and when a change invalidates an existing one, update it in the same PR.

Code Style

  • C++17, selective C++20. PascalCase classes, snake_case functions/variables
  • #pragma once for headers. Smart pointers and RAII preferred
  • Parallelization via TBB — be mindful of shared state
  • Always use SetSizerAndFit(sizer) instead of SetSizer(sizer) on top level window. Unless SetSizer must be called before the full layout is built, call sizer->SetSizeHints(window) afterwards in this case.

Key Entry Points

  • App startup: src/OrcaSlicer.cpp
  • Slicing pipeline: src/libslic3r/Print.cpp
  • All print/printer/material settings: src/libslic3r/PrintConfig.cpp
  • GUI: src/slic3r/GUI/
  • Core algorithms: src/libslic3r/ (GCode/, Fill/, Support/, Geometry/, Format/, Arachne/)
  • Printer profiles: resources/profiles/[manufacturer].json

Critical Constraints

  • Backward compatibility required for .3mf project files and printer profiles
  • Cross-platform — all changes must work on Windows, macOS, and Linux
  • Profile/format changes need version migration handling
  • Dependencies built separately in deps/build/, then linked to main app

Code review focus areas

  • Changes must not cause regressions in existing functionality, defaults, profiles, or project compatibility.
  • Features gated by options must not affect existing behavior when those options are disabled.
  • Changes should follow the existing code style and architecture. Architectural changes should be justified in code comments and the PR description.
  • Add helper functions or utilities only when existing code cannot reasonably be reused. Avoid duplication.
  • Keep code concise and clear. Manually simplify AI generated bloated codes before review.
  • Include targeted tests or documented verification for behavior changes, especially in slicing logic, profiles, formats, and GUI defaults.
  • For profile changes (resources/profiles/<Vendor>/**), check that version in the sibling resources/profiles/<Vendor>.json was bumped.
  • For translation changes (localization/i18n/**/*.po), check that recurring terms match the Localization glossary for that language.

Localization & translations

Catalogs live in localization/i18n/<lang>/OrcaSlicer_<lang>.po; the template is OrcaSlicer.pot. See the Localization guide for the human-facing version of these principles.

Terminology

  • Use the Localization glossary as the source of truth for recurring terms, so the same English term is always rendered the same way within a language, and terms that must stay in English (brand/product names, acronyms, materials, file formats, G-code tokens, macros/variables/identifiers) are not translated.
  • If a term's established translation changes, update both the affected .po files and the glossary (localization_glossary.tsv, then regenerate) so they stay in sync.
  • Translate the meaning, not the words. Check what the string actually controls before translating it — English reuses one word for different things. Flow ratio (multiplier), Flow Rate (throughput) and Flow Dynamics (pressure compensation) are three different terms; extruder may mean the toolhead, the feeder motor, or the nozzle depending on the string.
  • Reuse one template per recurring message shape (Failed to connect to …, Are you sure you want to …?), even where the English wording varies.

Editing rules

  • Only edit msgstrnever change msgid, and never "fix" wrong English in the translation alone. Report the source string instead.
  • Preserve exactly: placeholders (%s, %d, %1%, %zu, %%), every \n (count and position, including leading/trailing), leading/trailing spaces, HTML tags, , and the file's encoding and line endings.
  • Never reorder positional arguments in a c-format string. If the msgid is %d then %s, that order must hold — swapping them breaks at runtime.
  • msgctxt separates homonyms — always read it. Back/Camera View is the rear view of the 3D navigator, while Back/Navigation is the go-back button; Top exists in the Alignment, Layers and Camera View senses.
  • When a string needs disambiguating, add context in the source (_L_CONTEXT/_u8L_CONTEXT), don't work around it in the translation.
  • A literal % inside a string xgettext flagged possible-c-format will fail msgfmt. Fix it with a // xgettext:no-c-format, no-boost-format comment above the string in the source — do not mangle the translation or use %% in text that is never passed through printf.
  • Plural entries: read nplurals from the catalog's Plural-Forms header (it is not always 2 — ja/ko/zh/th/vi use 1, ru/cs/pl/lt use 3, uk uses 4). Each form must be genuinely inflected for its quantity; repeating one sentence across all forms is a bug in Slavic/Baltic languages, though it is correct for Turkish and Hungarian.
  • An entry whose msgstr equals its msgid is untranslated even though it is not empty; a plural entry with any empty form is likewise incomplete.
  • Mark machine-produced translations with an # AI Translated translator comment. Don't add it to a human translation you didn't actually rewrite.
  • Don't reflow or re-wrap unrelated entries — keep the diff limited to the strings you changed.

Verifying

  • scripts/run_gettext.bat --full (Windows) regenerates the template, merges every catalog and compiles the .mo files. It must exit 0.
  • Or check a single catalog with msgfmt --check-format -o <out>.mo localization/i18n/<lang>/OrcaSlicer_<lang>.po.
  • Fuzzy entries are not shown to users. If you correct one, clear its fuzzy flag, otherwise the fix never ships.