/ CONTRIBUTING.md
CONTRIBUTING.md
  1  # Contributing to Oxyjen
  2  
  3  First off, **thank you** for considering contributing to Oxyjen!
  4  
  5  This project is built in public and community-driven. Whether you're fixing a typo, adding a feature, or just providing feedback - every contribution matters.
  6  
  7  ---
  8  
  9  ## Table of Contents
 10  
 11  - [Code of Conduct](#code-of-conduct)
 12  - [How Can I Contribute?](#how-can-i-contribute)
 13  - [Getting Started](#getting-started)
 14  - [Development Workflow](#development-workflow)
 15  - [Pull Request Process](#pull-request-process)
 16  - [Coding Guidelines](#coding-guidelines)
 17  - [Project Structure](#project-structure)
 18  - [Current Priorities](#current-priorities)
 19  - [Recognition](#recognition)
 20  
 21  ---
 22  
 23  ## Code of Conduct
 24  
 25  ### Our Pledge
 26  
 27  We are committed to providing a welcoming and inspiring community for everyone. Please be respectful, constructive, and kind.
 28  
 29  ### Unacceptable Behavior
 30  
 31  - Harassment, trolling, or insulting comments
 32  - Personal or political attacks
 33  - Publishing others' private information
 34  - Any conduct that would be inappropriate in a professional setting
 35  
 36  ### Enforcement
 37  
 38  If you experience or witness unacceptable behavior, please report it by opening an issue or contacting [@11divyansh](https://github.com/11divyansh).
 39  
 40  ---
 41  
 42  ## How Can I Contribute?
 43  
 44  ### 1. Reporting Bugs
 45  
 46  Found a bug? Help us fix it!
 47  
 48  **Before submitting:**
 49  - Check if the bug has already been reported in [Issues](../../issues)
 50  - Make sure you're using the latest version
 51  
 52  **How to report:**
 53  1. Go to [Issues](../../issues/new)
 54  2. Use the "Bug Report" template if available
 55  3. Provide:
 56     - Clear title (e.g., "Executor throws NPE when graph is empty")
 57     - Description of what happened vs what you expected
 58     - Steps to reproduce
 59     - Java version, OS, and Oxyjen version
 60     - Code snippet if possible
 61     - Stack trace or error message
 62  
 63  **Example:**
 64  ````markdown
 65  **Title:** Executor crashes when NodeContext is null
 66  
 67  **Description:** 
 68  The Executor throws NullPointerException when NodeContext is null, 
 69  but it should throw a more descriptive error.
 70  
 71  **Steps to Reproduce:**
 72  1. Create a Graph with one node
 73  2. Call executor.run(graph, input, null)
 74  3. NPE is thrown
 75  
 76  **Expected:** IllegalArgumentException with message "NodeContext cannot be null"
 77  **Actual:** NullPointerException
 78  
 79  **Environment:**
 80  - Oxyjen v0.1.0
 81  - Java 11
 82  ````
 83  
 84  ---
 85  
 86  ### 2. Suggesting Features
 87  
 88  Have an idea? We'd love to hear it!
 89  
 90  **Before suggesting:**
 91  - Check [Issues](../../issues) and [Discussions](../../discussions) for similar ideas
 92  - Consider if it aligns with [Oxyjen's vision](README.md#-my-vision-for-oxyjen)
 93  
 94  **How to suggest:**
 95  1. Go to [Issues](../../issues/new) or [Discussions](../../discussions/new)
 96  2. Use "Feature Request" label
 97  3. Provide:
 98     - Clear title describing the feature
 99     - Use case - what problem does it solve?
100     - Proposed solution
101     - Alternative solutions you considered
102     - Code examples (if applicable)
103  
104  **Example:**
105  ````markdown
106  **Title:** Add support for conditional node execution
107  
108  **Use Case:**
109  I want to run different nodes based on previous outputs. 
110  E.g., if sentiment is negative, run escalation node, 
111  else run standard response node.
112  
113  **Proposed Solution:**
114  ```java
115  Graph pipeline = GraphBuilder.named("conditional")
116      .addNode(new SentimentNode())
117      .addConditionalBranch(
118          condition: ctx -> ctx.get("sentiment").equals("negative"),
119          ifTrue: new EscalationNode(),
120          ifFalse: new StandardNode()
121      )
122      .build();
123  ```
124  
125  **Alternatives:**
126  - Use separate graphs for each branch
127  - Implement logic inside node (but this mixes concerns)
128  ````
129  
130  ---
131  
132  ### 3. Contributing Code
133  
134  This is where the magic happens! Here's how to contribute code:
135  
136  ---
137  
138  ## Getting Started
139  
140  ### Prerequisites
141  
142  - **Java 11+** (Java 17+ recommended)
143  - **Maven 3.6+**
144  - **Git**
145  - Your favorite IDE (IntelliJ IDEA, Eclipse, VS Code)
146  
147  ### Fork & Clone
148  
149  1. **Fork the repository**
150     - Click "Fork" button on [GitHub](https://github.com/11divyansh/OxyJen)
151  
152  2. **Clone your fork**
153  ````bash
154     git clone https://github.com/YOUR_USERNAME/OxyJen.git
155     cd OxyJen
156  ````
157  
158  3. **Add upstream remote**
159  ````bash
160     git remote add upstream https://github.com/11divyansh/OxyJen.git
161  ````
162  
163  4. **Verify remotes**
164  ````bash
165     git remote -v
166     # origin    https://github.com/YOUR_USERNAME/OxyJen.git (fetch)
167     # origin    https://github.com/YOUR_USERNAME/OxyJen.git (push)
168     # upstream  https://github.com/11divyansh/OxyJen.git (fetch)
169     # upstream  https://github.com/11divyansh/OxyJen.git (push)
170  ````
171  
172  ### Build & Test
173  ````bash
174  # Build the project
175  mvn clean install
176  
177  # Run tests
178  mvn test
179  
180  # Run specific test
181  mvn test -Dtest=ExecutorTest
182  
183  # Skip tests (not recommended!)
184  mvn clean install -DskipTests
185  ````
186  
187  **Expected output:**
188  ````
189  [INFO] BUILD SUCCESS
190  [INFO] Total time: 5.234 s
191  ````
192  
193  ---
194  
195  ## Development Workflow
196  
197  ### Step 1: Create a Branch
198  
199  **Always create a new branch for your work. Never commit directly to `main`.**
200  ````bash
201  # Update your local main
202  git checkout main
203  git pull upstream main
204  
205  # Create feature branch
206  git checkout -b feature/your-feature-name
207  
208  # Or for bug fixes
209  git checkout -b fix/bug-description
210  ````
211  
212  **Branch naming conventions:**
213  - `feature/add-openai-integration` - New features
214  - `fix/executor-null-pointer` - Bug fixes
215  - `docs/improve-readme` - Documentation
216  - `refactor/simplify-context` - Code refactoring
217  - `test/add-executor-tests` - Adding tests
218  
219  ### Step 2: Make Your Changes
220  
221  **Write clean, focused code:**
222  - One feature/fix per branch
223  - Keep changes small and reviewable
224  - Write tests for new functionality
225  - Update documentation if needed
226  
227  **Example workflow:**
228  ````bash
229  # Make changes to files
230  vim src/main/java/io/oxyjen/core/Executor.java
231  
232  # Run tests frequently
233  mvn test
234  
235  # Add files
236  git add src/main/java/io/oxyjen/core/Executor.java
237  
238  # Commit with clear message
239  git commit -m "feat: add retry logic to Executor"
240  ````
241  
242  ### Step 3: Keep Your Branch Updated
243  ````bash
244  # Fetch latest changes from upstream
245  git fetch upstream
246  
247  # Rebase your branch on latest main
248  git rebase upstream/main
249  
250  # If conflicts occur, resolve them, then:
251  git add .
252  git rebase --continue
253  ````
254  
255  ### Step 4: Push Your Changes
256  ````bash
257  # Push to your fork
258  git push origin feature/your-feature-name
259  
260  # If you rebased, you might need force push
261  git push origin feature/your-feature-name --force-with-lease
262  ````
263  
264  ---
265  
266  ## Pull Request Process
267  
268  ### Before Opening a PR
269  
270  **Checklist:**
271  - [ ] Code builds successfully (`mvn clean install`)
272  - [ ] All tests pass (`mvn test`)
273  - [ ] Added tests for new features
274  - [ ] Updated documentation (JavaDocs, README)
275  - [ ] Followed [coding guidelines](#coding-guidelines)
276  - [ ] Commits are clean and descriptive
277  - [ ] Branch is up-to-date with `main`
278  
279  ### Opening a PR
280  
281  1. Go to [Pull Requests](../../pulls)
282  2. Click "New Pull Request"
283  3. Select:
284     - **base:** `11divyansh/OxyJen` → `main`
285     - **compare:** `YOUR_USERNAME/OxyJen` → `feature/your-feature`
286  4. Fill in the template:
287  ````markdown
288  ## Description
289  Brief description of what this PR does.
290  
291  ## Related Issues
292  Fixes #123
293  Relates to #456
294  
295  ## Changes Made
296  - Added retry logic to Executor
297  - Updated Executor tests
298  - Added JavaDoc for new methods
299  
300  ## Testing
301  - [ ] Unit tests added/updated
302  - [ ] Manual testing completed
303  - [ ] All tests pass locally
304  
305  ## Screenshots (if applicable)
306  [Add screenshots for UI changes]
307  
308  ## Checklist
309  - [ ] Code builds successfully
310  - [ ] Tests pass
311  - [ ] Documentation updated
312  - [ ] Follows coding guidelines
313  ````
314  
315  ### PR Review Process
316  
317  1. **Automated checks run** (if CI is set up)
318  2. **Maintainer reviews** within 24-48 hours
319  3. **You address feedback** by pushing new commits
320  4. **Approval & merge** once everything looks good
321  
322  **During review:**
323  - Be open to feedback
324  - Ask questions if something is unclear
325  - Make requested changes promptly
326  - Be patient and professional
327  
328  **After merge:**
329  - Your branch will be deleted (automatically or manually)
330  - You'll be credited in release notes
331  - Your name will be added to Contributors list
332  
333  ---
334  
335  ## Coding Guidelines
336  
337  ### Java Style
338  
339  **Follow standard Java conventions:**
340  ````java
341  // Good
342  public class OpenAIClient {
343      private final String apiKey;
344      
345      public OpenAIClient(String apiKey) {
346          this.apiKey = Objects.requireNonNull(apiKey);
347      }
348      
349      /**
350       * Sends a chat completion request to OpenAI.
351       * 
352       * @param request The chat request
353       * @return The response from OpenAI
354       * @throws IOException if network error occurs
355       */
356      public ChatResponse chat(ChatRequest request) throws IOException {
357          // Implementation
358      }
359  }
360  
361  // Bad
362  public class openAIClient {
363      String apiKey; // Not final, not private
364      
365      public openAIClient(String key) {
366          apiKey = key; // No null check
367      }
368      
369      // No JavaDoc
370      public ChatResponse chat(ChatRequest request) {
371          // Implementation
372      }
373  }
374  ````
375  
376  ### Code Quality Rules
377  
378  **1. Naming**
379  - Classes: `PascalCase` (e.g., `OpenAIClient`, `NodeContext`)
380  - Methods/variables: `camelCase` (e.g., `processInput`, `apiKey`)
381  - Constants: `UPPER_SNAKE_CASE` (e.g., `MAX_RETRIES`)
382  - Packages: `lowercase` (e.g., `io.oxyjen.core`)
383  
384  **2. Methods**
385  - Keep methods short (<50 lines ideally)
386  - One responsibility per method
387  - Use descriptive names (avoid abbreviations)
388  ````java
389  // Good
390  public String formatResponse(String raw) {
391      String trimmed = trim(raw);
392      String escaped = escapeHtml(trimmed);
393      return addMetadata(escaped);
394  }
395  
396  // Bad
397  public String fmt(String r) {
398      return doStuff(r);
399  }
400  ````
401  
402  **3. Error Handling**
403  - Use specific exceptions
404  - Provide helpful error messages
405  - Don't swallow exceptions
406  ````java
407  // Good
408  if (input == null) {
409      throw new IllegalArgumentException(
410          "Input cannot be null. Provide a valid input string."
411      );
412  }
413  
414  // Bad
415  if (input == null) {
416      throw new Exception("error");
417  }
418  ````
419  
420  **4. JavaDoc**
421  - Document all public classes and methods
422  - Explain WHY, not just WHAT
423  - Include `@param`, `@return`, `@throws`
424  ````java
425  /**
426   * Executes a graph pipeline with the given input.
427   * 
428   * <p>This method runs each node sequentially, passing the output
429   * of one node as the input to the next. If any node fails, execution
430   * stops and an exception is thrown.
431   * 
432   * @param graph The pipeline to execute
433   * @param input The initial input for the first node
434   * @param context Shared context for all nodes
435   * @param <I> Type of initial input
436   * @param <O> Type of final output
437   * @return The output from the last node in the pipeline
438   * @throws RuntimeException if any node fails during execution
439   */
440  public <I, O> O run(Graph graph, I input, NodeContext context) {
441      // Implementation
442  }
443  ````
444  
445  **5. Tests**
446  - Write tests for new features
447  - Use descriptive test names
448  - Follow Arrange-Act-Assert pattern
449  ````java
450  @Test
451  void executorShouldThrowExceptionWhenGraphIsEmpty() {
452      // Arrange
453      Graph emptyGraph = new Graph("empty");
454      NodeContext context = new NodeContext();
455      Executor executor = new Executor();
456      
457      // Act & Assert
458      assertThrows(IllegalStateException.class, () -> {
459          executor.run(emptyGraph, "input", context);
460      });
461  }
462  ````
463  
464  ---
465  
466  ## Project Structure
467  ````
468  OxyJen/
469  ├── src/
470  │   ├── main/
471  │   │   └── java/
472  │   │       └── io/oxyjen/
473  │   │           ├── core/           # Core classes
474  │   │           │   ├── Executor.java
475  │   │           │   ├── Graph.java
476  │   │           │   ├── GraphBuilder.java
477  │   │           │   ├── NodePlugin.java
478  │   │           │   └── NodeContext.java
479  │   │           ├── llm/            # LLM integrations (v0.2+)
480  │   │           ├── tools/          # Tool integrations (v0.3+)
481  │   │           └── util/           # Utilities
482  │   └── test/
483  │       └── java/
484  │           └── io/oxyjen/
485  │               └── core/           # Tests mirror main structure
486  ├── examples/                       # Example usage(not added yet)
487  ├── docs/                           # Documentation
488  ├── pom.xml
489  ├── README.md
490  ├── CONTRIBUTING.md
491  └── LICENSE
492  ````
493  
494  **Where to add your code:**
495  - New LLM provider → `src/main/java/io/oxyjen/llm/`
496  - New utility → `src/main/java/io/oxyjen/util/`
497  - New example → `examples/`(not added yet)
498  - Tests → Mirror the main structure in `src/test/`
499  
500  ---
501  
502  ## Current Priorities
503  
504  ### High Priority (v0.2 - Next 1-2 Weeks)
505  
506  **Help wanted on these tasks:**
507  
508  #### 1. OpenAI Integration
509  **Goal:** Add ChatGPT support with streaming
510  
511  **Tasks:**
512  - [ ] Create `OpenAIClient` with HTTP client
513  - [ ] Implement chat completions endpoint
514  - [ ] Add streaming support (Server-Sent Events)
515  - [ ] Create `OpenAIChatNode` implementing `NodePlugin`
516  - [ ] Add token counting
517  - [ ] Write comprehensive tests
518  - [ ] Add example usage in `examples/`
519  
520  **Resources:**
521  - [OpenAI API Docs](https://platform.openai.com/docs/api-reference/chat)
522  - Use `java.net.http.HttpClient` (Java 11+)
523  
524  **Related:** [Issue #1](../../issues/1) *(create this issue)*
525  
526  ---
527  
528  ### Medium Priority (v0.3+)
529  
530  - [ ] Async execution with `CompletableFuture`
531  - [ ] DAG (Directed Acyclic Graph) support
532  - [ ] Conditional branching
533  - [ ] Retry logic with exponential backoff
534  - [ ] Circuit breaker pattern
535  - [ ] Performance benchmarking
536  
537  ### Good First Issues
538  
539  **New to the project? Start here:**
540  
541  - [ ] Add examples
542  - [ ] Improve JavaDoc coverage
543  - [ ] Write unit tests for existing classes
544  - [ ] Fix typos in documentation
545  - [ ] Add inline code comments for complex logic
546  - [ ] Create utility methods (e.g., `StringUtils`, `JsonUtils`)
547  
548  **Look for issues labeled:** `good-first-issue` or `help-wanted`
549  
550  ---
551  
552  ## Recognition
553  
554  **All contributors are valued and recognized:**
555  
556  ### Contributors List
557  Your name will be added to:
558  - README Contributors section
559  - Release notes for the version you contributed to
560  - GitHub's Contributors page
561  
562  ### Special Recognition
563  - **First-time contributors** get a special shoutout
564  - **Significant contributions** get highlighted on social media
565  - **Regular contributors** may be invited as collaborators
566  
567  ### Hall of Fame (Coming Soon)
568  We'll track:
569  - Most commits
570  - Most issues resolved
571  - Most helpful reviewer
572  - Best documentation
573  
574  ---
575  
576  ## Questions?
577  
578  **Need help or have questions?**
579  
580  - **Discussions:** [Start a discussion](../../discussions)
581  - **Issues:** [Check existing issues](../../issues)
582  - **Email:** *(Add your email if you want)*
583  - **Twitter:** *(Add your Twitter if you want)*
584  
585  **Don't be shy!** No question is too basic. We're all learning together.
586  
587  ---
588  
589  ## Additional Resources
590  
591  - [Java Code Conventions](https://www.oracle.com/java/technologies/javase/codeconventions-contents.html)
592  - [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/)
593  - [GitHub Flow](https://guides.github.com/introduction/flow/)
594  
595  ---
596  
597  ## Thank You!
598  
599  Every contribution, no matter how small, makes Oxyjen better.
600  
601  **You're helping build the future of AI orchestration in Java.**
602  
603  ---
604  
605  *This document is a living guide. If you see ways to improve it, please submit a PR!*