Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions openwiki/.last-update.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"updatedAt": "2026-08-08T05:14:38.711Z",
"updatedAt": "2026-08-22T05:02:48.949Z",
"command": "update",
"gitHead": "0d29c3191ed9eb02197a92a6e51032faa634434c",
"gitHead": "ab598c51719af0ac6658af4720a345ebf6622792",
"model": "xiaomi/mimo-v2.5-pro",
"status": "complete",
"language": "en"
Expand Down
82 changes: 62 additions & 20 deletions openwiki/architecture/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ The orchestration layer that coordinates all components. Responsibilities:
- **Configuration Management**: Delegates to ConfigManager
- **Lifecycle Management**: Handles startup, shutdown, and cleanup

**Key Methods**:
- `install(version, force)`: Delegates to Installer
- `build(mvnParams, skipTests)`: Delegates to Builder
- `deploy()`: Delegates to Builder.deploy()
- `run(restheartOptions)`: Delegates to ProcessManager
- `watchFiles(restheartOptions)`: Delegates to Watcher
- `kill()`: Delegates to ProcessManager.kill()
- `status()`: Delegates to ProcessManager.status()
- `isRunning()`: Delegates to ProcessManager.isRunning()
- `checkAndKill()`: Delegates to ProcessManager.checkAndKill()
- `onlyPrintConfig(restheartOptions)`: Checks if options are config-print-only flags (`-t`, `-c`, `-v`)
- `printConfiguration()`: Logs all current config values
- `setHttpPort(port)`, `setDebugMode(debug)`, `setBuildSystem(buildSystem)`: Config setters

**Key Design Decisions**:
- Single responsibility: each component handles one domain
- Dependency injection: components receive ConfigManager in constructor
Expand Down Expand Up @@ -134,51 +148,65 @@ Manages all configuration settings. Responsibilities:

Handles building and deploying RESTHeart plugins. Responsibilities:

- **Build Execution**: Runs Maven or Gradle build commands
- **Build Execution**: Runs Maven or Gradle build commands (prefers wrapper scripts `mvnw`/`gradlew`)
- **Artifact Deployment**: Copies built JARs to RESTHeart plugins directory
- **Build System Resolution**: Determines which build system to use
- **Error Handling**: Deduplicates and formats build output
- **Build System Resolution**: Determines which build system to use via `resolveBuildSystem`
- **Error Handling**: Deduplicates consecutive error output lines

**Key Design Decisions**:
- Delegates build system specifics to `build-systems/` module
- Cleans target directory before building
- Returns to original directory after build (even on failure)
- Uses silent shell execution with deduplicated error output
- Build params use Maven conventions (`clean package`); Gradle maps these via `mapBuildParams`

#### Installer (`lib/installer.js`)

Manages RESTHeart installation. Responsibilities:

- **Version Resolution**: Handles "latest", specific versions, and local paths
- **Download Management**: Downloads RESTHeart from GitHub releases
- **Local Installation**: Installs from local RESTHeart builds
- **Version Verification**: Checks existing installations
- **Download Management**: Downloads RESTHeart from GitHub releases using native Node.js HTTPS
- **Local Installation**: Installs from local RESTHeart build directories
- **Version Verification**: Checks existing installations, verifies via `java -jar ... -v`

**Installation Strategies**:
1. **Remote**: Downloads from GitHub releases (latest or specific version)
2. **Local**: Copies from local RESTHeart build directory
2. **Local**: Copies from local RESTHeart build directory (detected by `/` or `\` in the argument)

**Constructor Dependencies**:
- `ConfigManager`: For directory paths and settings
- `Builder`: Used for post-install build if needed

**Key Design Decisions**:
- Checks for Java installation before proceeding
- Checks for Java installation before proceeding (via `commandExists`)
- Verifies existing installations to avoid redundant downloads
- Supports force reinstallation with `--force` flag
- Supports force reinstallation with `--force` flag (cleans cache directory)
- Uses native Node.js HTTPS for downloads (no external dependencies)

#### ProcessManager (`lib/process-manager.js`)

Manages RESTHeart process lifecycle. Responsibilities:

- **Process Execution**: Starts RESTHeart with configured options
- **Process Termination**: Kills running RESTHeart instances
- **Port Management**: Checks port availability and finds free ports
- **Process Termination**: Kills running RESTHeart instances with SIGTERM/SIGKILL fallback
- **Port Management**: Checks port availability on both IPv4 (`127.0.0.1`) and IPv6 (`::1`)
- **Status Monitoring**: Checks if RESTHeart is running
- **Config Detection**: Parses `-o` flag from RESTHeart options to find YAML config for host/port

**Key Methods**:
- `run(restheartOptions)`: Starts RESTHeart as a background process
- `kill()`: Uses `lsof` for port-specific detection, falls back to `ps-list`; SIGTERM then SIGKILL after 15s timeout
- `isRunning()`: Checks both `httpPort` and `httpPort + 1000` (RESTHeart's MongoDB wire protocol port)
- `status()`: Logs whether RESTHeart is running at the configured port
- `checkAndKill()`: Conditionally kills if already running
- `onlyPrintConfig(restheartOptions)`: Returns `true` when options contain `-t`, `-c`, or `-v` (RESTHeart print/config flags)

**Key Design Decisions**:
- Prefers `lsof` for port-specific process detection
- Falls back to `ps-list` for process discovery
- Parses RESTHeart YAML config for host/port settings
- Captures and manages RHO environment variable
- Implements graceful shutdown with timeout
- Captures RHO environment variable at startup (`originalRHO`) to prevent duplication on restart
- Implements graceful shutdown with SIGTERM, escalating to SIGKILL after 15s timeout

#### Watcher (`lib/watcher.js`)

Expand Down Expand Up @@ -237,12 +265,23 @@ Shared utility functions. Responsibilities:
Abstracts build system differences. Responsibilities:

- **Build System Resolution**: Determines Maven vs Gradle based on project files
- **Command Generation**: Generates appropriate build commands
- **Output Directory**: Returns correct target directory for each build system
- **Command Generation**: Generates appropriate build commands, preferring wrapper scripts
- **Output Directory**: Returns correct target directory for each build system (`target` for Maven, `build` for Gradle)

**Supported Build Systems**:
- **Maven**: `mvn clean package` with configurable parameters
- **Gradle**: `gradle build` with wrapper support
- **Maven** (`maven.js`): Prefers `./mvnw -f pom.xml ...`, falls back to `mvn`; uses `-DskipTests={true|false}`
- **Gradle** (`gradle.js`): Prefers `./gradlew ...`, falls back to `gradle`; uses `-x test` to skip tests

**Gradle Parameter Mapping** (`mapBuildParams`):
- `'package'` → `'build'`
- `'clean package'` → `'clean build'`
- Other values passed through unchanged

**Auto-Detection Logic** (`resolveBuildSystem` in `index.js`):
1. Check for explicit `--build-system` option → use that system
2. Check for `pom.xml` or `mvnw` → Maven
3. Check for `gradlew`, `build.gradle`, `build.gradle.kts`, `settings.gradle`, `settings.gradle.kts` → Gradle
4. Default to Maven when neither detected

## Data Flow

Expand Down Expand Up @@ -274,12 +313,15 @@ sequenceDiagram
participant PM as ProcessManager
participant CH as chokidar

CLI->>RH: watchFiles(restheartOptions, watchOptions)
RH->>W: watchFiles(restheartOptions, watchOptions)
CLI->>RH: watch(restheartOptions)
RH->>PM: checkAndKill()
Note over RH: If --build: build('clean package', true), deploy()
RH->>PM: run(restheartOptions)
RH->>W: watchFiles(restheartOptions)
W->>CH: watch(paths, options)
CH-->>W: change event (filePath)
W->>W: debounce timeout
W->>B: build()
W->>B: build('clean package', true)
B->>B: resolveBuildCommand()
B->>B: shell.exec(buildCommand)
B->>B: deploy()
Expand Down
85 changes: 70 additions & 15 deletions openwiki/architecture/source-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ restheart-cli/
├── .github/workflows/ # CI/CD configuration
│ ├── ci.yml # CI pipeline (test, lint, format)
│ └── openwiki-update.yml # Scheduled OpenWiki documentation refresh
├── .github/copilot-instructions.md # Agent instruction context
├── AGENTS.md # Repository agent guidance (OpenWiki section)
├── CLAUDE.md # Claude Code agent brief
├── rh.js # Executable entry point
├── package.json # Project configuration
├── README.md # Main documentation
Expand Down Expand Up @@ -75,8 +78,16 @@ initCLI()
The main CLI setup and command routing.

**Key Functions**:
- `initCLI()`: Sets up yargs, registers commands, handles global options
- `runCommand()`: Routes commands to appropriate RESTHeartManager methods
- `initCLI()`: Sets up yargs, registers commands, handles global options, prints welcome banner
- `runCommand(command, argv, rh)`: (exported) Routes commands to RESTHeartManager methods

**Command Routing** (`runCommand`):
- `install` → `rh.install(version, force)`
- `build` → `rh.build('clean package')` + `rh.deploy()` (tests enabled)
- `run` → `rh.checkAndKill()` → optionally `rh.build('clean package', true)` + `rh.deploy()` → `rh.run(options)`
- `kill` → `rh.checkAndKill()`
- `watch` → `rh.checkAndKill()` → optionally build/deploy → `rh.run()` → `rh.watchFiles()`
- `status` → `rh.status()`

**Command Registration Pattern**:
```javascript
Expand Down Expand Up @@ -154,15 +165,22 @@ yargs(hideBin(process.argv))

**Key Responsibilities**:
- Starts RESTHeart process
- Kills running instances
- Checks port availability
- Monitors process status
- Kills running instances (SIGTERM with SIGKILL fallback after 15s)
- Checks port availability on both IPv4 and IPv6
- Monitors process status (checks both httpPort and httpPort+1000)
- Detects RESTHeart config-print flags (`-t`, `-c`, `-v`) via `onlyPrintConfig`

**Constructor**: Receives `ConfigManager`; captures `originalRHO` environment variable at startup

**Key Methods**:
- `run(restheartOptions)`: Starts RESTHeart
- `kill()`: Terminates RESTHeart processes
- `isRunning()`: Checks if RESTHeart is active
- `checkPortAvailability(port)`: Verifies port is free
- `isRunning()`: Checks if RESTHeart is active (ports httpPort and httpPort+1000)
- `status()`: Logs running status
- `checkAndKill()`: Conditionally kills if already running
- `onlyPrintConfig(restheartOptions)`: Checks for config-print flags
- `parseConfigPath(restheartOptions)`: Extracts `-o` config file path
- `getHostAndPortFromConfig(configPath)`: Parses RESTHeart YAML config for host/port

**When to modify**: When changing process lifecycle, adding health checks, or modifying port management.

Expand Down Expand Up @@ -193,6 +211,8 @@ yargs(hideBin(process.argv))

**Class**: `RESTHeartManager`

**Constructor**: `(httpPort, debugMode)` - creates ConfigManager, then Builder, ProcessManager, Installer, Watcher

**Key Responsibilities**:
- Coordinates all components
- Provides public API for CLI commands
Expand All @@ -201,15 +221,33 @@ yargs(hideBin(process.argv))
**Key Methods**:
- `install(version, force)`: Delegates to Installer
- `build(mvnParams, skipTests)`: Delegates to Builder
- `deploy()`: Delegates to Builder.deploy()
- `run(restheartOptions)`: Delegates to ProcessManager
- `watchFiles(restheartOptions, watchOptions)`: Delegates to Watcher
- `kill()`: Delegates to ProcessManager
- `status()`: Delegates to ProcessManager
- `watchFiles(restheartOptions)`: Delegates to Watcher
- `kill()`: Delegates to ProcessManager.kill()
- `status()`: Delegates to ProcessManager.status()
- `isRunning()`: Delegates to ProcessManager.isRunning()
- `checkAndKill()`: Delegates to ProcessManager.checkAndKill()
- `onlyPrintConfig(restheartOptions)`: Checks for config-print flags
- `printConfiguration()`: Logs all config values
- `setHttpPort(port)`, `setDebugMode(debug)`, `setBuildSystem(buildSystem)`: Config setters

**When to modify**: When adding new top-level features or changing component coordination.

## Infrastructure Components

### CLI Help: `lib/help.js`

**Exported**: `getVersion`, `commandDescriptions`, `addCommandExamples`

**Key Responsibilities**:
- Reads version from `package.json` via `getVersion()`
- Provides command descriptions and usage examples for all CLI commands
- `commandDescriptions`: Object with keys for each command (`install`, `build`, `run`, `kill`, `watch`, `status`)
- `addCommandExamples(yargs, commandName)`: Attaches examples to yargs command definitions

**When to modify**: When adding new commands, updating help text, or changing examples.

### Logging: `lib/logger.js`

**Exported**: `logger`, `LogLevel`
Expand Down Expand Up @@ -237,10 +275,10 @@ yargs(hideBin(process.argv))
### Utilities: `lib/utils.js`

**Key Functions**:
- `checkPort(port)`: Checks port availability
- `commandExists(command)`: Verifies system command exists
- `checkPort(port)`: Checks port availability on IPv4 (`127.0.0.1`) and IPv6 (`::1`) via TCP connection
- `commandExists(command)`: Verifies system command exists; exits process if not found
- `ensureDir(dir)`: Creates directory recursively
- `createSpinner(text)`: Creates progress spinner
- `createSpinner(text)`: Creates progress spinner (via `ora`)

**When to modify**: When adding new utility functions or changing existing behavior.

Expand All @@ -256,8 +294,19 @@ build-systems/

**Resolution Logic** (`index.js`):
1. Check for explicit `--build-system` option
2. Auto-detect based on project files
3. Default to Maven if no detection
2. Auto-detect: `pom.xml` or `mvnw` → Maven; `gradlew`, `build.gradle`, `build.gradle.kts`, `settings.gradle`, `settings.gradle.kts` → Gradle
3. Default to Maven if neither detected

**MavenBuildSystem** (`maven.js`):
- Prefers `./mvnw -f pom.xml` wrapper, falls back to `mvn`
- Uses `-DskipTests={true|false}` for test control
- Output directory: `target`

**GradleBuildSystem** (`gradle.js`):
- Prefers `./gradlew` wrapper, falls back to `gradle`
- Uses `-x test` to skip tests
- Maps Maven-style params: `'package'` → `'build'`, `'clean package'` → `'clean build'`
- Output directory: `build`

**When to modify**: When adding new build systems or changing detection logic.

Expand Down Expand Up @@ -340,6 +389,12 @@ npx vitest run --coverage

**When to modify**: When changing the documentation update schedule or OpenWiki configuration.

### `.github/copilot-instructions.md`

Context file for AI coding assistants. Contains repository conventions and patterns.

**When to modify**: When updating agent guidance for the repository.

## Key Code Patterns

### Command Registration Pattern
Expand Down
Loading