Skip to content

Merge develop into master#4

Merged
tgittos merged 18 commits intomasterfrom
develop
Feb 24, 2026
Merged

Merge develop into master#4
tgittos merged 18 commits intomasterfrom
develop

Conversation

@tgittos
Copy link
Owner

@tgittos tgittos commented Feb 24, 2026

Summary

  • Add prompt caching with split system prompts for OpenAI and Anthropic
  • Optimize Python tools for better agent code navigation
  • Fix flaky test_message_store and unify build pipeline
  • Add user documentation (getting started, CLI reference, configuration, custom tools, etc.)
  • Eliminate ralph binary, consolidate to single scaffold binary
  • Add message_list_between for non-destructive conversation listing
  • Enable SMTP support
  • Add persistent goals and summary support to GOAP tools
  • Add pip_install and pip_list tools for pure-Python package management
  • Unify streaming display API with call-ID-aware tool functions
  • Bundle all deps into libagent.a fat archive

Test plan

  • CI passes on all platforms
  • Verify build with ./scripts/build.sh
  • Run full test suite with ./scripts/run_tests.sh
  • Verify prompt caching behavior with --debug flag
  • Test Python tool integration end-to-end

🤖 Generated with Claude Code

tgittos and others added 18 commits February 14, 2026 06:22
The GitHub Release was titled "ralph v0.1.0" when it should be
"scaffold v0.1.0" since scaffold is the top-level product.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
libagent.a now includes all dependency libraries (curl, mbedtls, cJSON,
sqlite, uuid, python, zlib, pdfio) so consumers only need
`libagent.a -lm -lpthread`. Uses GNU ar MRI scripts to merge both
x86_64 and aarch64 archives independently.

Release artifacts renamed to libagent.x86_64.a and libagent.aarch64.a.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route all tool display through display_streaming_tool_start (now
with id param), display_streaming_tool_delta, and
display_streaming_tool_result instead of mixing direct printf,
status_line_*, and log_tool_execution_improved calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Read-only query returning messages between two agents with cursor-based
pagination. Does not mark messages as read (unlike message_receive_direct).
Needed by ralphbot's GET /api/v1/messages endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…message ordering

- Add async_executor_continue() wrapping session_continue() in a background
  thread, mirroring how async_executor_start() wraps session_process_message()
- Make effects field optional in goap_create_actions (defaults to []),
  matching the existing preconditions default behavior
- Add mkdir -p guard for fat archive output directory in lib.mk
- Fix flaky test_message_store: message_list_between() ordered by created_at
  which was non-deterministic when messages shared the same millisecond
  timestamp; switched to rowid ordering for stable insertion-order results
- Add tests for async_executor_continue() and optional effects behavior
- Update test_create_actions_all_fail to test missing description (not effects)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enables installing py3-none-any wheels from PyPI into ~/.local/{app}/site-packages/.
Packages load automatically via sitecustomize.py path injection and persist across
sessions. Includes _ralph_sys C extension for app path discovery, _ralph_http.download()
for binary-safe file downloads, and zip-slip protection in wheel extraction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…load()

14 new tests covering: download() function existence and error handling,
_ralph_sys module import and return types, _version_key pre-release
ordering, _find_best_wheel wheel selection/rejection, _safe_extractall
zip-slip protection, and pip_list empty directory handling. Also fixes
_version_key bug where stable releases sorted below pre-releases due to
missing release sentinel in tuple comparison.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spinner now consults tool_extension_get_match_arg() to extract the
display parameter for extension tools, so pip_install shows
"pip_install (six)" instead of bare "pip_install". This makes the
existing Match: docstring directive actually drive the UI display
rather than relying solely on hardcoded parameter name chains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- goal_store_has_active_goals: query whether any ACTIVE goals exist
- goap_create_goal: new `persistent` param promotes goal to ACTIVE status
- goap_update_world_state: new `summary` param for context recovery
- 4 new goal_store tests for has_active_goals

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t/summary

- Check return values of goal_store_update_status and goal_store_update_summary
- Add status field to goap_create_goal response
- Use cJSON for summary extraction instead of redundant extract_string_param
- Add tool-level tests for persistent goal creation and world state summary
- Update ARCHITECTURE.md and CODE_OVERVIEW.md with new features and test counts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Returns the latest N messages in ASC order with has_more flag and
before_id cursor for backward pagination. Uses limit+1 fetch strategy
to detect additional older messages without a separate COUNT query.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the redundant ralph binary and make scaffold the sole output.
The ralph binary was a strict subset of scaffold, so maintaining both
added complexity without benefit.

Key changes:
- Move src/ralph/tools/ to src/tools/, delete src/ralph/ entirely
- Remove ralph target from build system (single TARGET, OBJECTS, embed-python)
- Remove all app_home_get_app_name() feature gating in lib/ — GOAP tools,
  orchestrator, /goals command, and scaffold prompt are now always active
- Consolidate prompts: delete system.txt, rename SCAFFOLD_SYSTEM_PROMPT_TEXT
  to SYSTEM_PROMPT_TEXT
- Change app_home default from "ralph" to "scaffold"
- Fix executable_path.c fallback from "./ralph" to "./scaffold"
- Fix GITHUB_REPO from "ralph" to "scaffold" (matches actual repo)
- Rename protected config file from ralph.config.json to scaffold.config.json
- Update CI docker image tag from ralph-dev to scaffold-dev
- Update all tests, documentation, and copilot-instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create docs/ with 8 guides covering getting started, configuration,
interactive mode, autonomous mode, memory, custom tools, MCP servers,
CLI reference, and building from source. Update README with quick start
section and documentation index linking to all guides.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Message ordering queries used ORDER BY created_at which is
non-deterministic when messages share the same millisecond timestamp.
Switch to ORDER BY rowid for guaranteed insertion order (matching
message_list_between which already did this correctly).

Build script now uses -j$(nproc) for parallel compilation, and CI
uses build.sh instead of invoking make directly — single source of
truth for the build command so issues surface locally, not just in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- search_files: add context_lines param, matched_files list,
  total_matches_found counter, use finditer() for all matches per line,
  increase MAX_LINE_DISPLAY to 500
- read_file: return dict with line-numbered content, total_lines, range
  instead of plain string
- list_dir: convert st_mtime to ISO timestamp strings
- apply_delta: add optional expected field on replace/delete ops for
  stale-content detection, verify all expected fields before mutations
- Add 4 integration tests covering all new features

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split the monolithic system prompt into a stable base prefix and
per-request dynamic context (todo state, mode, memories, context
retrieval). This enables cache hits across requests within a session:

- OpenAI: two system messages in messages array; first stays
  byte-identical across requests for automatic prefix caching
- Anthropic: system field as JSON array of content blocks with
  cache_control ephemeral markers on the base block and last tool

Rewrote build_json_payload_common to use cJSON throughout instead
of manual snprintf JSON assembly. Empty todo lists no longer emit
dynamic context, preserving cache stability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tgittos tgittos merged commit c735cde into master Feb 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant