Skip to content

Commit 940b60f

Browse files
authored
Merge pull request #8 from thedotmack/coderabbitai/docstrings/07f347a
📝 Add docstrings to `copilot/fix-6`
2 parents f261eea + 82cd6bd commit 940b60f

6 files changed

Lines changed: 202 additions & 12 deletions

File tree

claudia-server/examples/javascript/client.js

100755100644
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,16 @@ class ClaudiaClient {
177177
}
178178

179179
/**
180-
* Example usage
180+
* Example entrypoint demonstrating end-to-end usage of ClaudiaClient.
181+
*
182+
* Performs a health check against the Claudia server, starts a Claude session
183+
* for the current working directory, connects to the server WebSocket to stream
184+
* real-time responses, and installs a SIGINT handler for graceful shutdown.
185+
*
186+
* This is an example/demo helper — it performs network I/O, logs status to stdout,
187+
* and exits the process on error or when the user interrupts (Ctrl+C).
188+
*
189+
* @returns {Promise<void>} Resolves when the setup completes; the process may continue running to receive streamed responses.
181190
*/
182191
async function example() {
183192
const client = new ClaudiaClient();

claudia-server/examples/python/client.py

100755100644
Lines changed: 122 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,60 @@
2121

2222
class ClaudiaClient:
2323
def __init__(self, server_url: str = None):
24+
"""
25+
Initialize a ClaudiaClient.
26+
27+
If server_url is not provided, reads CLAUDIA_SERVER_URL from the environment and defaults to "http://localhost:3000".
28+
Derives the WebSocket URL by replacing the HTTP scheme with "ws" and appending "/ws", and initializes session and websocket attributes.
29+
30+
Parameters:
31+
server_url (str, optional): Base URL of the Claudia Server (e.g. "http://localhost:3000"). If omitted, the
32+
CLAUDIA_SERVER_URL environment variable is used; if that is unset, "http://localhost:3000" is used.
33+
"""
2434
self.server_url = server_url or os.environ.get('CLAUDIA_SERVER_URL', 'http://localhost:3000')
2535
self.ws_url = self.server_url.replace('http', 'ws') + '/ws'
2636
self.session = None
2737
self.websocket = None
2838

2939
async def __aenter__(self):
40+
"""
41+
Enter async context: create an aiohttp ClientSession and return the client instance.
42+
43+
Initializes and stores an aiohttp.ClientSession on self.session for use by other methods. Returns self so the class can be used as an asynchronous context manager.
44+
"""
3045
self.session = aiohttp.ClientSession()
3146
return self
3247

3348
async def __aexit__(self, exc_type, exc_val, exc_tb):
49+
"""
50+
Close the client's HTTP session and WebSocket when exiting the async context manager.
51+
52+
If an HTTP session or WebSocket is open, they are closed asynchronously. The method does not suppress exceptions raised in the managed block (it returns None).
53+
"""
3454
if self.session:
3555
await self.session.close()
3656
if self.websocket:
3757
await self.websocket.close()
3858

3959
async def start_session(self, project_path: str, prompt: str, model: str = 'claude-3-5-sonnet-20241022') -> str:
40-
"""Start a new Claude session"""
60+
"""
61+
Start a new Claude session on the configured Claudia Server.
62+
63+
Sends a POST to /api/claude/execute with the project path, prompt, and model.
64+
On success returns the created session's ID. On non-200 responses raises an
65+
Exception with the server-provided error message.
66+
67+
Parameters:
68+
project_path (str): Filesystem path of the project to run the prompt against.
69+
prompt (str): The text prompt to send to Claude.
70+
model (str): Model identifier to use for the session (defaults to 'claude-3-5-sonnet-20241022').
71+
72+
Returns:
73+
str: The newly created session_id.
74+
75+
Raises:
76+
Exception: If the server responds with a non-200 status; message includes server error.
77+
"""
4178
url = f"{self.server_url}/api/claude/execute"
4279
data = {
4380
'project_path': project_path,
@@ -54,7 +91,13 @@ async def start_session(self, project_path: str, prompt: str, model: str = 'clau
5491
return result['data']['session_id']
5592

5693
async def connect_websocket(self, session_id: str):
57-
"""Connect to WebSocket and subscribe to session"""
94+
"""
95+
Establish a WebSocket connection to the server, subscribe to a session, and stream incoming messages to the message handler.
96+
97+
Opens a connection to self.ws_url and stores the WebSocket in self.websocket, sends a JSON subscribe message for the given session, then iterates over incoming text messages, parsing each as JSON and delegating to self.handle_message. JSON parsing errors and handler exceptions are caught and logged; connection errors from establishing the WebSocket may propagate.
98+
Parameters:
99+
session_id (str): The server session identifier to subscribe to.
100+
"""
58101
self.websocket = await websockets.connect(self.ws_url)
59102
print("📡 Connected to WebSocket")
60103

@@ -76,7 +119,18 @@ async def connect_websocket(self, session_id: str):
76119
print(f"Error handling message: {e}")
77120

78121
async def handle_message(self, message: dict):
79-
"""Handle incoming WebSocket messages"""
122+
"""
123+
Dispatch and process a single incoming WebSocket message from the server.
124+
125+
Recognizes message types in the `message['type']` field:
126+
- "status": prints a short status line from `message['data']['status']`.
127+
- "claude_stream": forwards `message['data']` to `handle_claude_stream` for streaming output handling.
128+
- "error": prints the error text from `message['data']['error']`.
129+
- any other value: prints an "unknown message type" notice.
130+
131+
Parameters:
132+
message (dict): Parsed JSON message with at least a `type` key and a `data` payload whose structure depends on `type`.
133+
"""
80134
message_type = message.get('type')
81135

82136
if message_type == 'status':
@@ -89,7 +143,18 @@ async def handle_message(self, message: dict):
89143
print(f"📩 Unknown message type: {message_type}")
90144

91145
async def handle_claude_stream(self, data: dict):
92-
"""Handle Claude streaming messages"""
146+
"""
147+
Handle incoming Claude streaming events and render them to stdout.
148+
149+
The `data` payload is a dictionary that must include a 'type' field indicating the stream event:
150+
- 'start' : indicates the model has begun producing a response; prints a start notice.
151+
- 'partial' : contains incremental text under 'content'; prints text without a trailing newline to stream output progressively.
152+
- 'complete' : signals the end of the response; prints a newline and a completion notice.
153+
- 'error' : contains an error message under 'content'; prints the error with a leading newline.
154+
- other : prints the provided 'content' (or the full payload) as a generic Claude output.
155+
156+
This function has no return value; it side-effects by printing to stdout.
157+
"""
93158
stream_type = data.get('type')
94159

95160
if stream_type == 'start':
@@ -107,7 +172,15 @@ async def handle_claude_stream(self, data: dict):
107172
print(f"\\n📝 Claude output: {data.get('content', data)}")
108173

109174
async def get_running_sessions(self) -> list:
110-
"""Get list of running sessions"""
175+
"""
176+
Return the list of currently running Claude sessions.
177+
178+
Returns:
179+
list: Session objects parsed from the server response `data` field.
180+
181+
Raises:
182+
Exception: If the server responds with a non-200 status; message is taken from the server's `error` field.
183+
"""
111184
url = f"{self.server_url}/api/claude/sessions/running"
112185

113186
async with self.session.get(url) as response:
@@ -119,7 +192,20 @@ async def get_running_sessions(self) -> list:
119192
return result['data']
120193

121194
async def cancel_session(self, session_id: str) -> bool:
122-
"""Cancel a session"""
195+
"""
196+
Cancel a running Claude session on the server.
197+
198+
Sends a POST request to /api/claude/cancel/{session_id} and returns whether the session was successfully cancelled.
199+
200+
Parameters:
201+
session_id (str): The server-side identifier of the session to cancel.
202+
203+
Returns:
204+
bool: True if the server reports the session was cancelled, False otherwise.
205+
206+
Raises:
207+
Exception: If the HTTP response status is not 200; the exception message contains the server-provided error.
208+
"""
123209
url = f"{self.server_url}/api/claude/cancel/{session_id}"
124210

125211
async with self.session.post(url) as response:
@@ -131,7 +217,17 @@ async def cancel_session(self, session_id: str) -> bool:
131217
return result['data']['cancelled']
132218

133219
async def check_health(self) -> dict:
134-
"""Check server health"""
220+
"""
221+
Check the Claudia Server health status.
222+
223+
Performs a GET request to the server's /api/status/health endpoint and returns the parsed JSON health payload on success.
224+
225+
Returns:
226+
dict: The JSON response body describing server health.
227+
228+
Raises:
229+
Exception: If the server responds with a non-200 status code.
230+
"""
135231
url = f"{self.server_url}/api/status/health"
136232

137233
async with self.session.get(url) as response:
@@ -141,7 +237,18 @@ async def check_health(self) -> dict:
141237
return await response.json()
142238

143239
async def example():
144-
"""Example usage"""
240+
"""
241+
Run a self-contained example demonstrating ClaudiaClient usage.
242+
243+
This coroutine exercises the end-to-end flow against a Claudia Server:
244+
- Opens a ClaudiaClient session context.
245+
- Verifies server health.
246+
- Uses the current working directory as the project path.
247+
- Starts a Claude session with a sample prompt and model, printing the returned session ID.
248+
- Connects to the server WebSocket to stream real-time responses until interrupted.
249+
250+
Handles KeyboardInterrupt by printing a shutdown message; on other exceptions it prints the error and exits the process with code 1.
251+
"""
145252
async with ClaudiaClient() as client:
146253
try:
147254
# Check if server is healthy
@@ -174,6 +281,13 @@ async def example():
174281
if __name__ == "__main__":
175282
# Handle graceful shutdown
176283
def signal_handler(sig, frame):
284+
"""
285+
Handle an OS signal by printing a shutdown message and exiting the process with status code 0.
286+
287+
Parameters:
288+
sig: Signal number received.
289+
frame: Current stack frame (unused).
290+
"""
177291
print("\\n🛑 Shutting down...")
178292
sys.exit(0)
179293

claudia-server/src/index.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,24 @@ import { ClaudiaServer } from './server.js';
44
import type { ServerConfig } from './types/index.js';
55

66
/**
7-
* Parse command line arguments
7+
* Parse command-line arguments into a partial ServerConfig.
8+
*
9+
* Recognized options:
10+
* - `--port`, `-p <number>` — sets `port`
11+
* - `--host`, `-h <host>` — sets `host`
12+
* - `--claude-binary <path>` — sets `claude_binary_path`
13+
* - `--claude-home <path>` — sets `claude_home_dir`
14+
* - `--help` — prints help and exits (0)
15+
* - `--version` — prints the version and exits (0)
16+
*
17+
* Options that take a value expect the value as the next argument and will
18+
* ignore values that start with `-`. Unknown options beginning with `-`
19+
* result in an error message and exit(1).
20+
*
21+
* Note: this function may call `process.exit()` as a side effect for help,
22+
* version, or unrecognized option handling.
23+
*
24+
* @returns A Partial<ServerConfig> populated with any recognized CLI options.
825
*/
926
function parseArgs(): Partial<ServerConfig> {
1027
const args = process.argv.slice(2);
@@ -61,7 +78,10 @@ function parseArgs(): Partial<ServerConfig> {
6178
}
6279

6380
/**
64-
* Print help information
81+
* Print the command-line help/usage information for the Claudia Server CLI.
82+
*
83+
* Outputs usage, supported options, examples, relevant environment variables,
84+
* and available API endpoints to the process standard output.
6585
*/
6686
function printHelp(): void {
6787
console.log(`
@@ -106,7 +126,14 @@ For more information, visit: https://github.com/getAsterisk/claudia
106126
}
107127

108128
/**
109-
* Main function
129+
* Start the Claudia server using CLI arguments and environment variables.
130+
*
131+
* Parses command-line options, merges them with environment variables to construct a partial ServerConfig,
132+
* instantiates and starts a ClaudiaServer, and logs the effective runtime configuration (port, host,
133+
* CORS origins, max concurrent sessions, and optionally Claude binary/home paths). On startup failure
134+
* the function logs the error and exits the process with code 1.
135+
*
136+
* @returns A promise that resolves when the server has started.
110137
*/
111138
async function main(): Promise<void> {
112139
try {

claudia-server/src/routes/claude.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@ import type {
99
ErrorResponse
1010
} from '../types/index.js';
1111

12+
/**
13+
* Creates an Express Router with endpoints for managing and interacting with Claude code executions.
14+
*
15+
* The router exposes these routes:
16+
* - GET /version — check Claude code version/installation status
17+
* - POST /execute — start a new Claude execution (requires project_path, prompt, model)
18+
* - POST /continue — continue an existing conversation (requires project_path, prompt, model)
19+
* - POST /resume — resume a session (requires project_path, session_id, prompt, model)
20+
* - POST /cancel/:sessionId — cancel a running execution
21+
* - GET /sessions/running — list running Claude sessions
22+
* - GET /sessions/:sessionId — get session information
23+
* - GET /sessions/:sessionId/history — load session history/output
24+
*
25+
* All endpoints return a standardized SuccessResponse or ErrorResponse object with a timestamp and appropriate HTTP status codes for validation, not-found, and internal errors.
26+
*
27+
* @returns An Express Router configured with the Claude-related routes.
28+
*/
1229
export function createClaudeRoutes(
1330
claudeService: ClaudeService,
1431
projectService: ProjectService

claudia-server/src/routes/projects.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@ import { Router } from 'express';
22
import type { ProjectService } from '../services/project.js';
33
import type { SuccessResponse, ErrorResponse } from '../types/index.js';
44

5+
/**
6+
* Create an Express Router exposing project-related HTTP endpoints.
7+
*
8+
* The returned router is configured with routes for listing and creating projects,
9+
* retrieving project sessions, finding and reading/saving `CLAUDE.md` files, and
10+
* listing directory contents. Handlers delegate data operations to the provided
11+
* ProjectService and respond with a consistent SuccessResponse or ErrorResponse
12+
* shape that includes a timestamp. Validation failures return 400, missing
13+
* resources return 404 where appropriate, and unexpected errors return 500 with
14+
* route-specific error codes.
15+
*
16+
* @returns An Express Router wired with project management and CLAUDE file endpoints.
17+
*/
518
export function createProjectRoutes(projectService: ProjectService): Router {
619
const router = Router();
720

claudia-server/src/routes/status.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import type { SuccessResponse } from '../types/index.js';
33
import { homedir } from 'os';
44
import { join } from 'path';
55

6+
/**
7+
* Create an Express Router with status-related endpoints.
8+
*
9+
* Exposes three GET endpoints:
10+
* - GET /health: returns runtime health data (status, uptime, memory usage, Node version) and a timestamp.
11+
* - GET /info: returns server metadata (name, version, description) and runtime/environment details (node version, platform, architecture, pid, cwd, claude_home) with a timestamp.
12+
* - GET /home: returns the current user's home directory and the server's Claude-specific directory path with a timestamp.
13+
*
14+
* @returns An Express Router configured with the above endpoints.
15+
*/
616
export function createStatusRoutes(): Router {
717
const router = Router();
818

0 commit comments

Comments
 (0)