Skip to content

Conversation

@matleh
Copy link
Contributor

@matleh matleh commented Jan 16, 2026

Summary

Adds CLI flags and GraphQL mutations for partial body modifications, enabling agents to update bean content without direct file access. Builds on #59 (ETag support) and supersedes #57.

Changes

CLI: Body Modification Flags

  • --body-replace-old / --body-replace-new for exact text replacement (must match exactly once)
  • --body-append for appending content (supports stdin with -)
  • Mutual exclusivity with existing --body/--body-file flags

GraphQL: Partial Body Mutations

  • replaceInBody(id, old, new, ifMatch) - replace exactly one occurrence of text
  • appendToBody(id, content, ifMatch) - append content with blank line separator
  • Both support ifMatch for optimistic locking

Shared Logic

  • Extract ReplaceOnce and AppendWithSeparator to internal/bean/content.go
  • Reused by both CLI and GraphQL resolvers

Documentation

  • Add GraphQL API section to README with examples

Usage

# CLI: Check off a task
beans update <id> --body-replace-old "- [ ] Task" --body-replace-new "- [x] Task"

# CLI: Append notes
beans update <id> --body-append "## Notes\n\nSome notes"

# GraphQL: Check off a task
beans query 'mutation { replaceInBody(id: "bean-xxx", old: "- [ ] Task", new: "- [x] Task") { body } }'

# GraphQL: Append content
beans query 'mutation { appendToBody(id: "bean-xxx", content: "## Notes") { body } }'

Why This Matters for Agents

Agents can now modify bean bodies entirely through CLI/GraphQL without needing:

  • Direct file access to the .beans/ directory
  • Knowledge of where beans are stored (which can be configured outside the repo)
  • Special file permissions

Testing

  • Comprehensive tests for shared logic in internal/bean/content_test.go
  • GraphQL resolver tests for both mutations
  • CLI tests updated for new behavior

Copy link
Owner

@hmans hmans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, this is looking very good now. I've taken the liberty of removing the change in README.md, I hope you don't mind.

@hmans
Copy link
Owner

hmans commented Jan 17, 2026

@matleh Had some unexpected merge conflicts when updating this branch with the latest stuff from main, can I ask you to do a quick check that everything is still intact & as intended?

@hmans hmans self-assigned this Jan 17, 2026
matleh and others added 3 commits January 19, 2026 10:50
- Add --body-replace-old/--body-replace-new flags for partial text replacement
- Add --body-append flag for appending content (supports stdin with -)
- Add require_if_match config option to enforce ETag usage
- Mutual exclusivity with existing --body/--body-file flags
- Update prompt template with body modification and concurrency control docs

Usage:
  beans update <id> --body-replace-old "- [ ] Task" --body-replace-new "- [x] Task"
  beans update <id> --body-append "## Notes"
  echo "content" | beans update <id> --body-append -
- Add replaceInBody mutation to replace exactly one occurrence of text
- Add appendToBody mutation to append content with blank line separator
- Extract shared logic to internal/bean/content.go (ReplaceOnce, AppendWithSeparator)
- Refactor CLI to use shared functions
- Add GraphQL API section to README with examples
@matleh matleh force-pushed the feature/body-modification branch from ccf4bb7 to cbb5cbb Compare January 19, 2026 09:51
@matleh
Copy link
Contributor Author

matleh commented Jan 19, 2026

@hmans I updated the branch and ran some manual tests to verify that the functionality works as expected.

@hmans hmans merged commit b726959 into hmans:main Jan 19, 2026
1 check passed
@hmans
Copy link
Owner

hmans commented Jan 19, 2026

Thank you! 🙏

@matleh matleh deleted the feature/body-modification branch January 22, 2026 09:31
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.

2 participants