|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Build & Test Commands |
| 6 | + |
| 7 | +```bash |
| 8 | +# Full build (default task) |
| 9 | +./gradlew build |
| 10 | + |
| 11 | +# Build with coverage reports (used in CI) |
| 12 | +./gradlew build jacocoTestReport jacocoTestCoverageVerification |
| 13 | + |
| 14 | +# Run all tests |
| 15 | +./gradlew test |
| 16 | + |
| 17 | +# Run tests for a specific module |
| 18 | +./gradlew :symphony-bdk-core:test |
| 19 | + |
| 20 | +# Run a single test class or method |
| 21 | +./gradlew :symphony-bdk-core:test --tests "com.symphony.bdk.core.service.MessageServiceTest" |
| 22 | +./gradlew :symphony-bdk-core:test --tests "com.symphony.bdk.core.service.MessageServiceTest.shouldSendMessage" |
| 23 | + |
| 24 | +# Publish to local Maven repository |
| 25 | +./gradlew publishToMavenLocal |
| 26 | + |
| 27 | +# OWASP dependency vulnerability check (requires NVD_API_KEY env var for reasonable speed) |
| 28 | +./gradlew dependencyCheck |
| 29 | + |
| 30 | +# Check for dependency updates |
| 31 | +./gradlew dependencyUpdates |
| 32 | +``` |
| 33 | + |
| 34 | +## Module Architecture |
| 35 | + |
| 36 | +The project is a multi-module Gradle build. All modules import the `symphony-bdk-bom` platform for dependency version alignment. |
| 37 | + |
| 38 | +### Core modules |
| 39 | + |
| 40 | +| Module | Role | |
| 41 | +|--------|------| |
| 42 | +| `symphony-bdk-bom` | Bill of Materials — version constraints for all dependencies | |
| 43 | +| `symphony-bdk-config` | Loads and parses `bdk-config.yaml` into `BdkConfig` | |
| 44 | +| `symphony-bdk-core` | Entry point, services, auth, datafeed loop, activity framework | |
| 45 | +| `symphony-bdk-extension-api` | SPI for third-party BDK extensions | |
| 46 | + |
| 47 | +### Abstraction layers with multiple implementations |
| 48 | + |
| 49 | +| API module | Implementations | |
| 50 | +|------------|-----------------| |
| 51 | +| `symphony-bdk-http:symphony-bdk-http-api` | `symphony-bdk-http-jersey2`, `symphony-bdk-http-webclient` | |
| 52 | +| `symphony-bdk-template:symphony-bdk-template-api` | `symphony-bdk-template-freemarker`, `symphony-bdk-template-handlebars` | |
| 53 | + |
| 54 | +### Spring Boot integration |
| 55 | + |
| 56 | +`symphony-bdk-spring:symphony-bdk-core-spring-boot-starter` and `symphony-bdk-app-spring-boot-starter` wrap the core in auto-configured Spring beans. These do not change core behaviour — they only wire configuration and lifecycle. |
| 57 | + |
| 58 | +### Test utilities |
| 59 | + |
| 60 | +`symphony-bdk-test:symphony-bdk-test-jupiter` provides JUnit 5 extensions; `symphony-bdk-test-spring-boot` wraps them for Spring context tests. |
| 61 | + |
| 62 | +## symphony-bdk-core Internals |
| 63 | + |
| 64 | +`SymphonyBdk` is the user-facing entry point. It is built via `SymphonyBdkBuilder` and owns a `ServiceFactory` that instantiates all services lazily. |
| 65 | + |
| 66 | +Key sub-packages: |
| 67 | + |
| 68 | +- **`auth`** — session authentication and JWT token management (`AuthSession`, `BotAuthenticator`, `OboAuthenticator`) |
| 69 | +- **`service`** — one service class per Symphony API domain (`MessageService`, `StreamService`, `UserService`, `DatafeedService`, etc.) |
| 70 | +- **`activity`** — activity framework: `ActivityRegistry` dispatches `DatafeedEvent`s to registered `AbstractActivity` handlers (command, form reply, room events) |
| 71 | +- **`retry`** — Resilience4j-backed retry decorators applied to all HTTP calls |
| 72 | +- **`client`** — HTTP client load-balancing and exception translation |
| 73 | + |
| 74 | +OBO (On-Behalf-Of) flows are surfaced through `OboServices` / `OboService`, which mirror the main services but authenticate with a delegated session. |
| 75 | + |
| 76 | +## Build Conventions (`buildSrc/`) |
| 77 | + |
| 78 | +Four Groovy convention plugins used by sub-modules: |
| 79 | + |
| 80 | +- `bdk.java-common-conventions` — Java 17, UTF-8, JaCoCo, JUnit Platform, sources+javadoc jars, BOM platform import |
| 81 | +- `bdk.java-library-conventions` — extends common + `java-library` plugin (used by all published libs) |
| 82 | +- `bdk.java-publish-conventions` — `maven-publish` + `signing`; signing is **only required for release versions** (`isReleaseVersion = !version.endsWith('SNAPSHOT')`) |
| 83 | +- `bdk.java-codegen-conventions` — OpenAPI Generator (Jersey2, Java 8 date library) reading `src/main/resources/api.yaml`; generated sources land in `build/generated/openapi` |
| 84 | + |
| 85 | +## Publishing |
| 86 | + |
| 87 | +Snapshots are published to Sonatype OSSRH via the `publishToSonatype` Gradle task (nexus-publish-plugin). This task is automatically triggered in CI on every PR build. Releases use `publishToSonatype closeAndReleaseStagingRepository` and are triggered by a GitHub Release event. |
| 88 | + |
| 89 | +Credentials are passed as Gradle properties: `-PmavenRepoUsername` and `-PmavenRepoPassword`. |
| 90 | + |
| 91 | +# context-mode — MANDATORY routing rules |
| 92 | + |
| 93 | +You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session. |
| 94 | + |
| 95 | +## BLOCKED commands — do NOT attempt these |
| 96 | + |
| 97 | +### curl / wget — BLOCKED |
| 98 | +Any Bash command containing `curl` or `wget` is intercepted and replaced with an error message. Do NOT retry. |
| 99 | +Instead use: |
| 100 | +- `ctx_fetch_and_index(url, source)` to fetch and index web pages |
| 101 | +- `ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox |
| 102 | + |
| 103 | +### Inline HTTP — BLOCKED |
| 104 | +Any Bash command containing `fetch('http`, `requests.get(`, `requests.post(`, `http.get(`, or `http.request(` is intercepted and replaced with an error message. Do NOT retry with Bash. |
| 105 | +Instead use: |
| 106 | +- `ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context |
| 107 | + |
| 108 | +### WebFetch — BLOCKED |
| 109 | +WebFetch calls are denied entirely. The URL is extracted and you are told to use `ctx_fetch_and_index` instead. |
| 110 | +Instead use: |
| 111 | +- `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` to query the indexed content |
| 112 | + |
| 113 | +## REDIRECTED tools — use sandbox equivalents |
| 114 | + |
| 115 | +### Bash (>20 lines output) |
| 116 | +Bash is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands. |
| 117 | +For everything else, use: |
| 118 | +- `ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call |
| 119 | +- `ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context |
| 120 | + |
| 121 | +### Read (for analysis) |
| 122 | +If you are reading a file to **Edit** it → Read is correct (Edit needs content in context). |
| 123 | +If you are reading to **analyze, explore, or summarize** → use `ctx_execute_file(path, language, code)` instead. Only your printed summary enters context. The raw file content stays in the sandbox. |
| 124 | + |
| 125 | +### Grep (large results) |
| 126 | +Grep results can flood context. Use `ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context. |
| 127 | + |
| 128 | +## Tool selection hierarchy |
| 129 | + |
| 130 | +1. **GATHER**: `ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls. |
| 131 | +2. **FOLLOW-UP**: `ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call. |
| 132 | +3. **PROCESSING**: `ctx_execute(language, code)` | `ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context. |
| 133 | +4. **WEB**: `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context. |
| 134 | +5. **INDEX**: `ctx_index(content, source)` — Store content in FTS5 knowledge base for later search. |
| 135 | + |
| 136 | +## Subagent routing |
| 137 | + |
| 138 | +When spawning subagents (Agent/Task tool), the routing block is automatically injected into their prompt. Bash-type subagents are upgraded to general-purpose so they have access to MCP tools. You do NOT need to manually instruct subagents about context-mode. |
| 139 | + |
| 140 | +## Output constraints |
| 141 | + |
| 142 | +- Keep responses under 500 words. |
| 143 | +- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description. |
| 144 | +- When indexing content, use descriptive source labels so others can `ctx_search(source: "label")` later. |
| 145 | + |
| 146 | +## ctx commands |
| 147 | + |
| 148 | +| Command | Action | |
| 149 | +|---------|--------| |
| 150 | +| `ctx stats` | Call the `ctx_stats` MCP tool and display the full output verbatim | |
| 151 | +| `ctx doctor` | Call the `ctx_doctor` MCP tool, run the returned shell command, display as checklist | |
| 152 | +| `ctx upgrade` | Call the `ctx_upgrade` MCP tool, run the returned shell command, display as checklist | |
0 commit comments