-
Notifications
You must be signed in to change notification settings - Fork 785
feat: Add Orchestrator Client Mode for Remote Access via Central Hub #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
liamhelmer
wants to merge
43
commits into
siteboon:main
Choose a base branch
from
Epiphytic:feat/orchestrator-client-mode
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 33 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
d4732b3
feat: add protocol.js
liamhelmer 7853613
feat: add client.js
liamhelmer a78d2a3
feat: add status-tracker.js
liamhelmer d1b7392
feat: add proxy.js
liamhelmer ec114eb
feat: add index.js
liamhelmer 4cc88ca
feat: add index.js
liamhelmer 694fea0
feat: add index.js
liamhelmer fdb4a45
feat: add index.js
liamhelmer e04e347
feat: add index.js
liamhelmer 10da083
feat: add index.js
liamhelmer 7368c38
feat: add index.js
liamhelmer 307bdc7
feat: add cli.js
liamhelmer a4cc597
feat: add cli.js
liamhelmer 08267ce
feat: add cli.js
liamhelmer 5cf5720
feat: add cli.js
liamhelmer 1947227
feat: add cli.js
liamhelmer 1b83340
feat: add .env.example
liamhelmer f216a07
feat(orchestrator): implement client mode for claudecodeui orchestrat…
liamhelmer 2a8be94
feat: add github-auth.js
liamhelmer 65606ae
feat: add protocol.js
liamhelmer df5ab89
feat: add proxy.js
liamhelmer 599f9d6
feat: add proxy.js
liamhelmer 04075a7
feat: add .env.example
liamhelmer 3878b5b
feat: add cli.js
liamhelmer 04ff458
feat: add cli.js
liamhelmer 0fba3b0
feat: add cli.js
liamhelmer 1b548e0
feat: add cli.js
liamhelmer 8420337
feat: add index.js
liamhelmer 5ee0456
feat(orchestrator): implement github oauth and websocket proxy for cl…
liamhelmer 8f85682
feat: progressive app support through orchestrator
liamhelmer c03b915
feat(orchestrator): implement github oauth and websocket proxy for cl…
liamhelmer 4eae09a
feat(orchestrator): implement github oauth and websocket proxy for cl…
liamhelmer f6c6565
feat(orchestrator): implement github oauth and websocket proxy for cl…
liamhelmer 8eb5944
docs: add orchestrator client documentation
liamhelmer f8a2d5a
feat(orchestrator): implement client mode with github oauth and webso…
liamhelmer 97116c7
chore: ignore .fork-join/ directory
liamhelmer 7f0f0d6
fix(orchestrator): wire up follow-up message routing
liamhelmer ff7d30c
fix: address CodeRabbit security and correctness issues
liamhelmer 09e576a
chore: address CodeRabbit nitpicks
liamhelmer 01770de
feat(orchestrator): implement client mode with github oauth and webso…
liamhelmer 5de3c9e
feat(server): orchestrator client mode
liamhelmer 952f0f4
feat(orchestrator): implement client mode with github oauth and webso…
liamhelmer 585391f
feat(orchestrator): implement client mode with github oauth and webso…
liamhelmer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| session-1768779775 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "session_id": "session-1768779775", | ||
| "feature_branch": "feat/orchestrator-client-mode", | ||
| "base_branch": "main", | ||
| "prompt": "Look in @~/repos/liamhelmer/ai-orchestrator/CLAUDE.md . I'm building an orchestrator that will act as a central server where instances of claudecodeui can connect to. We need to create a mode of claudecodeui that works with the orchestrator: it should create a websocket connection to the orchestrator at a URL defined in the config, and it should authenticate itself using github oauth authentication. Then it will accept user traffic over the websocket connection which will be authenticated with the github token, and it will send back app data that will be consumed by the orchestrator. Create a plan for building this functionality.\n", | ||
| "state": "STARTED", | ||
| "started_at": "2026-01-18T23:42:55Z", | ||
| "agents": [], | ||
| "merged_count": 0, | ||
| "conflict_count": 0, | ||
| "prompts": [ | ||
| { | ||
| "prompt": "Fix all of the following. If any would break new functionality, ask before implementing the fix. Assign an agent to each fix for clarity: In `@server/database/db.js`:\n- Around line 229-268: The getOrCreateOrchestratorUser function currently\nignores githubId and can bind an orchestrator user to any local account with the\nsame username; update this logic to (1) validate githubUsername is\nnon-empty/defined before DB ops, (2) prefer finding users by a persisted\ngithub_id column (add/ensure users.github_id exists), (3) if a user is found by\nusername but github_id differs, reject or namespace the orchestrator user\ninstead of reusing the local account, and (4) when creating a new orchestrator\nuser insert the github_id (and a namespaced username if you choose that\napproach) and set last_login; update the SELECT, INSERT and UPDATE statements in\ngetOrCreateOrchestratorUser to use github_id checks and handle mismatch cases\nexplicitly.\n\nIn `@server/middleware/auth.js`:\n- Around line 9-112: The middleware logs sensitive token fragments, decoded\npayloads, and secret hashes unguarded (see secretHash, authenticateToken,\ngenerateToken), which must be disabled in production; wrap all\nconsole.log/console.error calls that print token/payload/secret information\nbehind an explicit AUTH_DEBUG env check (e.g., process.env.AUTH_DEBUG ===\n\"true\") so logs only run when AUTH_DEBUG is enabled, leaving non-sensitive error\nhandling intact and keeping validateApiKey, authenticateToken, and generateToken\nlogic unchanged except for gating their debug logging.\n\nIn `@server/orchestrator/client.js`:\n- Around line 255-264: In sendPing(), clear any existing heartbeat timeout\nbefore setting a new one to prevent stale timers from firing; call\nclearTimeout(this.heartbeatTimeoutTimer) (and reset it to null) right before\nassigning this.heartbeatTimeoutTimer = setTimeout(...), so overlapping pings\nwon’t cause a healthy connection to be terminated in sendPing(), keeping the\nexisting DEFAULTS.heartbeatTimeout and the ws?.terminate() behavior unchanged.\n- Around line 501-516: Remove logging of token material: keep the token format\nvalidation for orchestratorToken and still set\nfetchOptions.headers[\"authorization\"] = `Bearer ${orchestratorToken}` when\nvalid, but change the console.log to omit the raw token (do not use\norchestratorToken.substring). Instead log only non-sensitive context such as\norchestratorUsername or a fixed placeholder (e.g., \"[REDACTED]\" or masked\nindicator) so no bearer token characters are emitted; update the message near\nthe existing token-format check and header assignment in\nserver/orchestrator/client.js that references orchestratorToken,\norchestratorUsername, and fetchOptions.headers.\n- Around line 734-769: The issue is that '.' and other regex metacharacters in\nentries of urlPrefixes (e.g., \"socket.io\", \"manifest.json\") are being\ninterpreted by RegExp, causing unintended matches; in rewriteJsUrls(js,\nproxyBase) escape each prefix before constructing the RegExp (e.g., compute an\nescapedPrefix by replacing /[.*+?^${}()|[\\]\\\\]/g with '\\\\[Pasted text #1 +107 lines]') and use\nescapedPrefix in the three new RegExp(...) calls so the patterns match the\nliteral prefix characters.\n- Around line 525-539: The current code always calls response.text() which\ncorrupts binary payloads; change the logic around the response handling in\nserver/orchestrator/client.js (the block that builds responseHeaders,\ncontentType, and responseBody from response) to detect binary vs text via\ncontentType (inspect the contentType variable from the response.headers loop),\nand for binary types (non-text/* and not application/json or lacking utf-8) read\nthe body with response.arrayBuffer(), base64-encode it, set a sentinel header\n(e.g. add [\"x-orch-encoding\",\"base64\"] into responseHeaders) and set\nresponseBody to the base64 string; for text types continue to use\nresponse.text() and keep no encoding header; apply the same change to the second\nsimilar block later in the file where response.text() is used.\n\nIn `@server/orchestrator/github-auth.js`:\n- Around line 32-47: The githubFetch function currently can hang indefinitely;\nmodify githubFetch to use an AbortController with an 8 second timeout: create an\nAbortController, pass its signal to fetch, set a timeout (8000ms) that calls\ncontroller.abort(), and clear that timeout after the fetch completes (both\nsuccess and error) to avoid leaks; ensure the thrown error when aborted is\nsurfaced as a fetch failure so the existing response.ok handling still applies\n(update references to the controller and signal usage inside githubFetch).\n\nIn `@server/orchestrator/index.js`:\n- Around line 67-69: The function createOrchestratorClientFromEnv uses\nrequire(\"./client.js\") which fails in this ESM module; replace that with either\na static top-level import \"import { OrchestratorClient } from './client.js'\" or\nswitch to the existing dynamic-import pattern (use await import(\"./client.js\")\nand destructure OrchestratorClient) inside createOrchestratorClientFromEnv and\nmake the function async if you choose dynamic import so the destructuring works\ncorrectly.\n\nIn `@server/orchestrator/protocol.js`:\n- Around line 133-139: The createResponseCompleteMessage function currently\nomits valid falsy values because it spreads ...(data && { data }); change the\nconditional to only exclude when data is null or undefined (e.g., use a\nconditional like data !== null && data !== undefined) so that empty string, 0,\nfalse are preserved; update createResponseCompleteMessage to build the returned\nobject for OutboundMessageTypes.RESPONSE_COMPLETE and include the data property\nwhen data !== null && data !== undefined (leave it out when null/undefined).\n\nIn `@server/orchestrator/proxy.js`:\n- Around line 215-285: handleUserRequest may destructure payload as undefined\nand then do payload.user = ..., causing a crash when githubAuth is configured;\nfix by ensuring payload is initialized before mutation: change the\ndestructuring/assignment so payload is a defined object (e.g., let payload =\nmessage.payload || {}) prior to using githubAuth.validate and assigning\npayload.user, and then pass that initialized payload into\nOrchestratorProxySocket and handlers.handleChatMessage so subsequent code\n(OrchestratorProxySocket, OrchestratorProxyWriter, handlers.handleChatMessage)\ncan safely read/write payload without throwing.\n\nIn `@src/App.jsx`:\n- Around line 109-140: The mediaQuery listener leaks because\nwindow.matchMedia(\"(display-mode: standalone)\") is invoked multiple times;\ncapture the MediaQueryList once (e.g., const mql = window.matchMedia(...)) in\nthe useEffect, add the \"change\" listener to mql and remove it from the same mql\nin the cleanup, and stop calling matchMedia inside checkPWA. Also move the\ntouchstart listener setup out of checkPWA (or guard so it only attaches once),\nprovide a real handler function instead of {} (e.g., handleTouchStart) and\nremove that same handler in the useEffect cleanup; update references to\ncheckPWA, mql, and handleTouchStart accordingly so listeners are added/removed\nfrom the same objects.", | ||
| "timestamp": "2026-01-20 22:06:35 UTC" | ||
| }, | ||
| { | ||
| "prompt": "close both PRs from this branch without merging. Force push the branch. Then change the origin to https://github.com/Epiphytic/claudecodeui and push all changes there. Then make new PRs to https://github.com/Epiphytic/claudecodeui and https://github.com/siteboon/claudecodeui/", | ||
| "timestamp": "2026-01-20 22:24:35 UTC" | ||
| } | ||
| ] | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/database/db.js | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/middleware/auth.js | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/orchestrator/client.js | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/orchestrator/github-auth.js | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/orchestrator/index.js | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/orchestrator/protocol.js | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/orchestrator/proxy.js | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/src/App.jsx | ||
| /Users/liam.helmer/repos/epiphytic/claudecodeui/server/database/init.sql | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.