Resolved merge conflicts:
- CMakeLists.txt: Added both rebase_engine/utility and base64_util sources
- src/harness.cpp: Combined Content type with proper error handling
- src/main.cpp: Merged includes, test flags, and CLI parsing
- Renamed conflicting flags: -B→-Z (build_rebase), -T→-W (edit_prompt), -b→-K (base64_decode)
- tests/CMakeLists.txt: Added all test targets from both branches
- src/rebase_engine.cpp: Fixed to use get_content_string() for Content variant type
- Updated test files to use new flag names (-Z, -W, -K)
- Add base64_encode() function to encode binary data to base64 string
- Add base64_decode() function to decode base64 string to binary data
- Add get_mime_type_from_extension() for MIME type detection based on file extension
- Add generate_data_uri() for data URI prefix generation
- Add test flags -B (encode), -b (decode), -T (mime type), -U (data URI)
- Add comprehensive tests in test_base64_encode.sh
- No new dependencies added
Create new utility module (include/utility.hpp, src/utility.cpp) containing
common code that was duplicated between rebase_engine.cpp and editor.cpp:
- trim() function
- random_string() function
- random_file_name() function
- Defer RAII helper class
- spawn_editor() function
Both rebase_engine.cpp and editor.cpp now include utility.hpp instead of
duplicating these functions.
All 33 unit tests pass.
Add rebase parser that validates rebase editor format with:
- RebaseCommand enum (Pick, Edit, Drop)
- RebaseLine struct (command, index, role)
- parse_rebase_file() with strict validation and error aggregation
Validations:
- Invalid commands (not pick/edit/drop)
- Index out of range
- Duplicate indices
- Missing/malformed role brackets
- Invalid role values (must be user/assistant/tool)
- Comment lines (#) and empty lines are skipped
Tests cover all validation scenarios via -P debug flag.
- Upgrade CMakeLists.txt from C++20 to C++23 to enable std::expected
- Add parse_json_safely() to json_types.hpp: wraps json::parse with
allow_exceptions=false, returns discarded JSON on parse failure
- Add expect_or_exit() to json_types.hpp: helper for std::expected that
prints error to stderr and exits on failure
- Add test flags (-J, -E, -e) to CLI for testing the new functions
- Add bash tests for parse_json_safely() and expect_or_exit()
Consolidate skill_parsing, skill_scanner, and skill_tool modules into
a single skill.hpp / skill.cpp pair as specified in issue #16.
Changes:
- Created include/skill.hpp with all declarations
- Created src/skill.cpp with all implementations
- Updated CMakeLists.txt to use the new consolidated file
- Updated src/main.cpp to include the new consolidated header
- Removed old files: skill_parsing.hpp/cpp, skill_scanner.hpp/cpp,
skill_tool.hpp/cpp
All 21 tests pass without regression.
- Added make_skill_tool() which looks up requested skills in an enabled map.
- Tool returns XML-wrapped string with <skill_content> and <skill_files>.
- Skill files are returned as absolute paths.
- Added SkillToolParams to json_types.hpp.
- Registered skill_tool in main.cpp with the enabled map built from SkillScanner.
- Added test_tool_skill.sh to verify XML structure and absolute paths.
- Updated CMakeLists.txt and tests/CMakeLists.txt accordingly.
- Add skill_parsing.hpp and skill_parsing.cpp for YAML frontmatter parsing
- Extract name (required) and description (optional) from SKILL.md files
- Add -y flag to print parsed metadata and exit
- Add test_skill_parsing.sh to verify the -y flag functionality
- Update CMakeLists.txt to include the new source and test
- Add SkillScanner class to recursively find SKILL.md files
- Scan standard global (~/.local/share/harness/skills/, ~/.config/harness/skills/) and local (./skills/, ./.skills/) paths
- Add -D flag to print all discovered file paths and exit
- Add unit test for scanner functionality
- Update CMakeLists.txt and main.cpp accordingly
Each AgentProfile defines a model and a subset of tools. Profiles are
registered as callable tools in the main harness so the orchestrator LLM
can delegate tasks to specialized subagents. Each invocation runs an
isolated Harness with fresh history; only the final answer is returned,
keeping the orchestrator context clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
C++20 agentic loop targeting a local Ollama instance via the OpenAI-compatible
/v1/chat/completions API. Includes an extensible tool registry pattern and a
shell command runner as the first tool. Builds with CMake + system libcurl +
nlohmann-json.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>