From 1f4ff493ea71f234072d601e5e06cab61d40b04c Mon Sep 17 00:00:00 2001 From: Ivo Hedtke Date: Thu, 24 Sep 2026 16:10:00 +0200 Subject: [PATCH] Configure claude --- .claude/CLAUDE.md | 54 +++++++++++++++++++++++++ .claude/settings.json | 21 ++++++++++ .claude/skills/prepare-release/SKILL.md | 21 ++++++++++ .claude/skills/update-scip/SKILL.md | 27 +++++++++++++ .gitignore | 6 +++ 5 files changed, 129 insertions(+) create mode 100644 .claude/CLAUDE.md create mode 100644 .claude/settings.json create mode 100644 .claude/skills/prepare-release/SKILL.md create mode 100644 .claude/skills/update-scip/SKILL.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 00000000..d5ce2fea --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,54 @@ +# SCIP++ + +C++ wrapper around SCIP's C API: library target `ScipPP`, namespace `scippp`. +Distributed via Conan Center; API docs are generated by Doxygen and published to GitHub Pages. + +## Hard constraints + +* **C++17 only.** It is the minimum standard for consumers (`CMakeLists.txt`, `_min_cppstd` in `conanfile.py`), and + CI builds with GCC 11, AppleClang and MSVC and runs clang-tidy 14. No concepts, ranges, ``, `std::span`, + etc. +* Public API lives in `include/scippp/*.hpp`. The project follows SemVer, so do not break it: deprecate + (`@deprecated since X.Y.Z: Use #foo() instead`) instead of removing or changing signatures. +* `Model` owns the `SCIP*` (if it created it) and releases all vars/conss in its d'tor. `Var` and other wrappers are + non-owning handles. +* Every SCIP call inside `Model` goes through `m_scipCallWrapper(...)`, never `SCIP_CALL`. + +## Generated files: do not edit by hand + +* `include/scippp/parameters.hpp`: output of `utils/gen_constexpr_parameters.cpp`. +* `include/scippp/solving_statistics.hpp`: output of `utils/extract_solvingstats.py`. + +Both carry an `updated for SCIP X.Y.Z` header comment. See the `update-scip` skill. + +## Conventions + +* Formatting: `.clang-format` (WebKit), checked in CI with clang-format 17. +* Naming: enforced by `.clang-tidy` (`camelBack` functions/variables, `m_` private members, `UPPER_CASE` constants, + `CamelCase` types, `lower_case` namespaces). +* Every public symbol has a Doxygen block with `@since X.Y.Z` (the next release version). Write `%SCIP` in Doxygen + text so Doxygen does not autolink it. +* Getters are `[[nodiscard]]`. Member functions that do not change the C++ object are `const`, even if they change + the underlying SCIP state (see PR40). +* Every user-visible change adds an entry under `## [Unreleased]` in `changelog.md` (Keep a Changelog, format + `- [PRnn](https://github.com/scipopt/SCIPpp/pull/nn) ...`). +* Features that are part of the documented API also get a short example in `readme.md`. + +## Layout + +* `source/`: implementation. `source/version.cpp.in` is configured by CMake. +* `test/`: Boost.Test, one `test_.cpp` per area with `BOOST_AUTO_TEST_SUITE`. `test/examples.cpp` holds + small end-to-end models (e.g. knapsack). +* `utils/`: code generators, built only with `BUILD_UTILS=ON` / `-o with_utils=True`. +* `build/`, `html/`, `CMakeUserPresets.json`: generated, git-ignored. + +## Build and test (Conan) + +```bash +conan install -o with_tests=True --build=missing . # add -pr debug for build/Debug +cmake --preset conan-release . +cmake --build build/Release --target tests +build/Release/test/tests # --run_test=Var/GetSolVal for a single case +``` + +Without Conan: `cmake -DBUILD_TESTS=ON . && make tests && ./test/tests` (needs SCIP and Boost via `find_package`). diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000..7da5aa4b --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-settings.json", + "permissions": { + "allow": [ + "Bash(git status:*)", + "Bash(git diff:*)", + "Bash(git log:*)", + "Bash(git show:*)", + "Bash(cmake --build build/Debug:*)", + "Bash(cmake --build build/Release:*)", + "Bash(build/Debug/test/tests:*)", + "Bash(build/Release/test/tests:*)" + ], + "ask": [ + "Bash(git commit:*)", + "Bash(git push:*)", + "Bash(git rebase:*)", + "Bash(gh:*)" + ] + } +} diff --git a/.claude/skills/prepare-release/SKILL.md b/.claude/skills/prepare-release/SKILL.md new file mode 100644 index 00000000..0a1a5366 --- /dev/null +++ b/.claude/skills/prepare-release/SKILL.md @@ -0,0 +1,21 @@ +--- +name: prepare-release +description: Prepare a SCIP++ release (changelog section, compare links, Conan fallback version). Use when the user asks to prepare, cut or bump a release version. +argument-hint: +disable-model-invocation: true +--- + +Prepare release `$ARGUMENTS` (dated today). Past example: `git show 5068906`. + +1. Choose the SemVer level by reading `## [Unreleased]` in `changelog.md`. Warn the user if `$ARGUMENTS` does not fit, + e.g. a patch bump with `### Added` entries, or anything below a major bump if there are breaking changes. +2. `changelog.md`: + * Insert `## [$ARGUMENTS] - YYYY-MM-DD` directly below `## [Unreleased] - [Doc:Unreleased]`, so the unreleased + section is empty again. + * At the bottom, change `[Unreleased]: .../compare/...main` to `compare/$ARGUMENTS...main` and add + `[$ARGUMENTS]: https://github.com/scipopt/SCIPpp/releases/tag/$ARGUMENTS` above the previous release link. +3. `conanfile.py`: set the fallback in `set_version` to `self.version = "$ARGUMENTS"`. +4. Check that every `@since` for symbols added in this release uses `$ARGUMENTS` + (`git diff ..HEAD -- include/`). + +Do not create tags or commits. Print the `git tag` command for the user to copy. diff --git a/.claude/skills/update-scip/SKILL.md b/.claude/skills/update-scip/SKILL.md new file mode 100644 index 00000000..92a6fb79 --- /dev/null +++ b/.claude/skills/update-scip/SKILL.md @@ -0,0 +1,27 @@ +--- +name: update-scip +description: Update SCIP++ to a new SCIP version (Conan requirement, CI, generated parameters and statistics, changelog). Use when the user asks to bump, upgrade or update SCIP. +argument-hint: +--- + +Update SCIP++ to SCIP `$ARGUMENTS`. Past examples: `git log --grep "Update to SCIP"`. + +1. `conanfile.py`: set `self.requires("scip/$ARGUMENTS", ...)`. First check that this version exists on Conan Center. +2. `.github/workflows/main.yml`, job `test_without_conan`: update both occurrences of the `scipoptsuite_*.deb` + release URL / file name. +3. Regenerate `include/scippp/parameters.hpp`. Do not edit it by hand. + * Build the generator (it needs Boost headers, hence `with_tests`): + `conan install -o with_utils=True -o with_tests=True --build=missing .`, `cmake --preset conan-release .`, + `cmake --build build/Release --target gen_constexpr_parameters`. + * Run `build/Release/utils/gen_constexpr_parameters`. Its output replaces everything between + `// NOLINTBEGIN(readability-identifier-naming)` and `// NOLINTEND(...)`. Keep the hand-written header and + footer, and set the `// updated for SCIP ...` comment. + * Review the diff. Removed or renamed parameters break the API: point them out to the user and add them to the + changelog. +4. Check whether `scip_solvingstats.h` changed (new or removed `SCIPget*(SCIP*)` functions). If it did, regenerate + `include/scippp/solving_statistics.hpp` with `utils/extract_solvingstats.py` (dependencies in + `utils/requirements.txt`) and update its `updated for SCIP` comment. +5. `changelog.md`: under `## [Unreleased]` → `### Changed`, add `- [PRnn](...) Update to SCIP $ARGUMENTS.` Ask the + user for the PR number if it is unknown. + +Build and run the tests only if the user asks. diff --git a/.gitignore b/.gitignore index e2eea20f..480c4721 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,9 @@ CMakeUserPresets.json # CLion IDE files (seem to store local (non-shareable) settings since Nova is out) **/.idea + +# Claude Code: per-developer instructions, settings, worktrees and local agent memory (the rest of .claude is shared) +CLAUDE.local.md +.claude/settings.local.json +.claude/worktrees/ +.claude/agent-memory-local/