Skip to content

feat: Separated Addon Server To A Separate Package#126

Merged
Nat3z merged 7 commits intomainfrom
feat/addon-server-package
May 5, 2026
Merged

feat: Separated Addon Server To A Separate Package#126
Nat3z merged 7 commits intomainfrom
feat/addon-server-package

Conversation

@Nat3z
Copy link
Copy Markdown
Owner

@Nat3z Nat3z commented Apr 30, 2026

This pull request introduces significant refactoring and modernization of the add-on server integration in the Electron application. The main changes include replacing internal implementations with the @ogi-sdk/addon-server package, improving type safety and process management, and simplifying the add-on server startup and IPC handling. Additionally, the PR updates development tooling and makes several dependency and configuration adjustments.

Add-on Server Integration Refactor:

  • Replaced internal AddonConnection and related logic with the @ogi-sdk/addon-server package throughout the Electron codebase, updating imports and method calls accordingly. (application/src/electron/handlers/handler.addon.ts, application/src/electron/manager/manager.addon.ts, application/src/electron/handlers/handler.app.ts, application/src/electron/server/addon-server.ts) [1] [2] [3] [4]
  • Centralized add-on server process management by replacing direct access to clients and server with addonServer and addonIPC methods, and updating how add-on server is started and stopped. (application/src/electron/handlers/handler.addon.ts, application/src/electron/main.ts) [1] [2]

IPC and UI Interaction Improvements:

  • Added a callback mechanism for screen input requests using a new screenInputCallbacks map, ensuring responses are handled asynchronously and safely. (application/src/electron/main.ts, application/src/electron/handlers/handler.app.ts) [1] [2]
  • Registered UI handlers for add-on server events, such as input requests and notifications, enhancing communication between the main process and renderer. (application/src/electron/main.ts)

Security and Startup Changes:

  • Removed the use of the applicationAddonSecret from URLs and configuration, simplifying the security model and startup logic. (application/src/electron/main.ts) [1] [2] [3] [4]
  • Ensured the add-on server is started with improved error handling and logging, particularly for port conflicts. (application/src/electron/main.ts)

Dependency and Configuration Updates:

  • Updated package.json to use workspace:* for real-debrid-js and added @ogi-sdk/addon-server as a dependency. (application/package.json)
  • Improved typechecking scripts for Svelte and TypeScript to enforce stricter error thresholds and cleaner output. (application/package.json)
  • Adjusted Vite config to only exclude ogi-addon from dependency externalization. (application/electron.vite.config.ts)
  • Updated VSCode settings to exclude auto-imports from the server/ directory for TypeScript and JavaScript. (.vscode/settings.json)

Overall, these changes modernize the add-on server architecture, improve maintainability, and streamline both development and runtime behaviors.

Summary by CodeRabbit

  • New Features

    • Added concurrent action execution protection—actions now prevent overlapping execution with running state indicators.
    • Introduced "View in Library" navigation for owned games in the store.
  • Bug Fixes

    • Fixed header back button state clearing issue.
  • Refactor

    • Restructured addon server architecture with new dedicated package.
    • Simplified store UI by removing platform-specific library removal flow.
    • Enhanced security configuration handling during startup.
  • Chores

    • Updated build configuration and TypeScript settings.
    • Added VS Code editor preferences for auto-imports.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
open-game-installer-web Ready Ready Preview, Comment May 5, 2026 7:45pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4be3ec3e-220a-483e-864e-02b5a2550296

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR refactors the addon-server architecture into a new @ogi-sdk/addon-server package with an AddonServer class and event emitter pattern, replacing singleton patterns and direct clients/addonSecret exports. Electron handlers and the main process are updated to use the new APIs. Configuration changes, startup flow adjustments, callback-based screen input, and frontend refinements accompany the migration.

Changes

Cohort / File(s) Summary
Build & VS Code Configuration
.vscode/settings.json, application/electron.vite.config.ts, package.json (root)
Added auto-import exclusion rules for server/ imports in TS/JS; updated webtorrent bundling behavior in Electron config; added --silent and --pretty false flags to typecheck scripts; added @ogi-sdk/addon-server workspace dependency.
Addon-Server Package Extraction
packages/addon-server/* (new package)
Created new @ogi-sdk/addon-server package with AddonServer class, AddonConnection, DeferredTasksManager (refactored from singleton), supporting utilities, build configuration, and documentation; exports refactored APIs replacing global state patterns.
Electron Server Core
application/src/electron/server/addon-server.ts, application/src/electron/server/ipc.ts, application/src/electron/server/constants.ts (removed), application/src/electron/server/dev-server.ts (removed)
Rewrote addon-server.ts to use @ogi-sdk/addon-server; renamed AddonServer IPC class to AddonIPC; removed singleton secret constants; deleted dev-server startup file.
Electron Server APIs
application/src/electron/server/api/addons.ts, application/src/electron/server/api/defer.ts
Updated addon client access from clients map to addonServer.getClient() and addonServer.getConnections().values(); switched IPC imports from serve.js to ipc.js; updated task access via addonServer.getDeferredTasksManager().
Electron Handlers
application/src/electron/handlers/handler.addon.ts, application/src/electron/handlers/handler.app.ts, application/src/electron/handlers/handler.rest.ts
Replaced direct server/client manipulation with addonServer APIs; added screen input callback tracking; updated IPC routing to addonIPC.handleRequest; changed addon path/icon/connection lookups to use addonServer accessors.
Electron Main Process & Startup
application/src/electron/main.ts, application/src/electron/startup.ts, application/src/electron/manager/manager.addon.ts
Removed secret query parameter from renderer URLs; introduced screenInputCallbacks map and callback parameter to sendAskForInput; deferred NixOS/environment detection into startupEnvironmentReady async initializer; updated addon secret/client retrieval to use addonServer APIs.
Frontend UI Updates
application/src/frontend/components/StorePage.svelte, application/src/frontend/views/FocusedAddonView.svelte, application/src/frontend/App.svelte, application/src/frontend/components/PlayPage.svelte
Simplified StorePage by removing library-removal logic and platform checks, adding viewInLibrary() navigation; added concurrency control to FocusedAddonView action execution; fixed App.svelte back-button callback clearing; adjusted PlayPage styling and formatting.
TypeScript Configuration & Typing
application/src/frontend/tsconfig.json, application/typings/ogi-addon.d.ts, packages/ogi-addon/src/main.ts, packages/addon-server/tsconfig.json
Added ../lib/storefronts.ts to frontend TS includes; removed ogi-addon/config module declaration; exported Notification interface from ogi-addon; created addon-server TypeScript config with bundler-mode settings.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Hop skip through the refactored code,
A singleton shed like an old bunny abode,
Now AddonServer reigns supreme and true,
With events and callbacks, shiny and new!
The wheels spin faster, the code flows clear,
Architecture blooming—spring is here! 🌱

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: separating the addon server into a distinct package (@ogi-sdk/addon-server). This is the core refactoring objective reflected throughout the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/addon-server-package

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

const launchUrl = `${baseUrl}&launchGameId=${gameId}${wrapperQuery}`;

P1 Badge Build launch URLs with a query separator

Since baseUrl no longer contains ?secret=..., concatenating launch parameters with & produces malformed URLs (for example http://localhost:8080&launchGameId=...) instead of query strings. In both launch-hook and direct-launch flows this prevents launchGameId/hook params from being parsed by the renderer, so Steam shortcut launches and pre/post hook launches can silently lose their launch context.


this.ws.on('close', () => {
for (const [_, pending] of this.pendingResponses.entries()) {
pending.reject(new Error('Websocket closed'));
}
this.pendingResponses.clear();
});

P1 Badge Remove closed websocket clients from addon registries

On websocket close, the connection only rejects pending responses and never unregisters itself from the server’s connections/clients collections. This leaves stale addon IDs marked as connected, so reconnect attempts with the same ID can be rejected as duplicates and APIs that enumerate active addons can return disconnected entries.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return;
}
resolve(false);
resolve(stderr.includes('nixos-rebuild'));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect NixOS from stdout instead of stderr

command -v nixos-rebuild writes the match to stdout, but this check reads stderr, so detectNixOS() now resolves false even on NixOS. That means Nix-specific startup work (like resolving the steamtinkerlaunch path) is skipped for all Nix users, which can break launch configuration on that platform.

Useful? React with 👍 / 👎.

@Nat3z
Copy link
Copy Markdown
Owner Author

Nat3z commented Apr 30, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

🧹 Nitpick comments (5)
packages/ogi-addon/src/main.ts (1)

819-823: ⚡ Quick win

Use the newly exported Notification type to remove duplicate local interfaces

Now that this type is exported, import it where duplicates exist (application/src/electron/main.ts and application/src/electron/server/addon-server.ts) to prevent type drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ogi-addon/src/main.ts` around lines 819 - 823, Replace the duplicate
local Notification interface declarations with the exported Notification type:
remove the local interface named Notification in the modules that declared it,
add an import of the exported Notification type (from the addon package) and
update any type annotations/usages to reference that imported Notification type
instead of redeclaring it; ensure no other local symbols conflict with the
imported Notification and run type checks to confirm the types align for
functions/methods that previously used the local interface.
packages/addon-server/package.json (2)

22-23: 💤 Low value

Pin @types/bun to a specific version.

Using "latest" for @types/bun can cause non-reproducible builds. Consider pinning to a specific version for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/addon-server/package.json` around lines 22 - 23, The devDependency
"@types/bun" is set to "latest" which makes builds non-reproducible; update the
package.json devDependencies entry for "@types/bun" to a specific exact version
(no "latest" or floating range) by replacing "latest" with a pinned semver (e.g.
"x.y.z") to ensure consistent installs—edit the packages/addon-server
package.json devDependencies "@types/bun" entry accordingly.

31-35: ⚖️ Poor tradeoff

Consider using built-in WebSocket instead of ws library.

The ws and websocket packages are listed as dependencies, but according to the coding guidelines for packages/addon-server/**, the built-in WebSocket should be preferred over the ws library for WebSocket functionality.

Additionally, the elysia dependency appears unused based on the code in addon.ts which uses Node's http.createServer and ws.WebSocketServer directly.

As per coding guidelines: "Use built-in WebSocket instead of ws library for WebSocket functionality".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/addon-server/package.json` around lines 31 - 35, Remove the external
WebSocket deps and unused elysia: delete "ws" and "websocket" from the
dependencies in package.json and also remove "elysia" if it's unused; then
update addon.ts which currently creates the server with http.createServer and
references ws.WebSocketServer to instead use the platform's built-in
WebSocket/WebSocketServer APIs (replace any imports or references to the ws
package), ensuring server creation and connection handling remain the same but
rely on the built-in WebSocket implementation.
packages/addon-server/lib/addon.ts (1)

43-48: ⚡ Quick win

Secret generation uses weak entropy sources.

The secret is generated using Date.getTime() combined with Math.random(), both of which are predictable. For security-sensitive secrets, consider using crypto.randomUUID() or crypto.randomBytes() for better entropy.

🔒 Proposed fix using crypto
+import { randomUUID } from 'crypto';
+
 export class AddonServer {
   // ...
   public constructor(private readonly config: AddonConfig) {
     // create a random secret if not provided
     if (config.securityCheck && !config.secret) {
-      config.secret = `${Math.floor(new Date().getTime() + Math.random() * 10000)}-${Math.floor(Math.random() * 10000)}`;
+      config.secret = randomUUID();
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/addon-server/lib/addon.ts` around lines 43 - 48, The constructor
currently seeds config.secret with predictable values using Date.getTime() and
Math.random(); update the Addon constructor to use a cryptographically secure
generator instead (e.g., call crypto.randomUUID() or generate bytes via
crypto.randomBytes() and hex/base64 encode) when config.securityCheck is true
and no config.secret is provided, assigning the secure value to config.secret;
ensure you import/require Node's crypto and replace the current
`${Math.floor...}` expression used in the constructor with the secure generator
so secret creation is non-deterministic.
packages/addon-server/lib/addon-connection.ts (1)

188-191: 💤 Low value

Silent return on addon owner mismatch may hide issues.

When deferredTask.addonOwner !== this.addonInfo!.id, the code returns silently without logging. This could make debugging difficult if an addon incorrectly tries to update another addon's task.

📝 Proposed fix to add logging
-            if (deferredTask.addonOwner !== this.addonInfo!.id) return;
+            if (deferredTask.addonOwner !== this.addonInfo!.id) {
+              console.warn(
+                `Addon ${this.addonInfo!.id} attempted to update task owned by ${deferredTask.addonOwner}`
+              );
+              return;
+            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/addon-server/lib/addon-connection.ts` around lines 188 - 191, When
deferredTask.addonOwner !== this.addonInfo!.id the code returns silently; update
that branch to log a warning/error before returning so owner mismatches are
visible. Add a log call (using the existing logger instance, e.g., this.logger
or processLogger) that records the deferredTask id (deferredTask.id or
deferredTask.taskId), the observed deferredTask.addonOwner and the expected
this.addonInfo!.id, and any relevant context (e.g., method name in
addon-connection.ts) then return as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@application/src/electron/handlers/handler.addon.ts`:
- Around line 64-72: The call to addonServer.stop() is currently synchronous but
this.server.close() is async, causing a race where await startAddonServer() may
run before the port is freed; update the stop() implementation (in addon server
class where this.server.close() is called) to return a Promise that resolves in
the close callback (and rejects on error), and then change the restart flow
(restartAddonServer or the handler using addonServer.stop()) to await
addonServer.stop() before killing processes and calling await
startAddonServer(); alternatively, instead of changing stop(), wrap the existing
close call at the restart site in a Promise and await it before proceeding so
startAddonServer() only runs after the server is fully closed.

In `@application/src/electron/handlers/handler.app.ts`:
- Around line 192-195: The one-shot screen input callback stored in
screenInputCallbacks is not removed if callback(data.data) throws, leaving a
stale entry; update the IPC handler around the retrieval of callback (using
screenInputCallbacks.get(data.id)) so you always remove the entry
(screenInputCallbacks.delete(data.id)) in a finally-like guarantee: get the
callback, if present run it inside a try/catch but ensure
screenInputCallbacks.delete(data.id) is executed regardless of success or error,
and rethrow or handle the error after deletion so behavior is preserved.

In `@application/src/electron/manager/manager.addon.ts`:
- Around line 176-181: The call to executeScript('run', ...) is currently
fire-and-forget so any rejection escapes the surrounding try/catch and becomes
an unhandled rejection; change it to handle the returned Promise (either await
it or attach .catch) and on error invoke the same crash handling used for
startup (write run-crash.log and log the error). Locate executeScript usage in
manager.addon.ts and ensure the Promise returned by executeScript is awaited or
chained with .catch that writes run-crash.log (using addonName/addonPath
context) and rethrows or logs as appropriate so the error is not unhandled.
- Around line 6-7: The import of AddonConnection from '@ogi-sdk/addon-server'
fails because the package's build artifacts (./build/index.mjs,
./build/index.d.mts) are absent; update the repo build workflow to build
packages/addon-server before the app resolves it by adding packages/addon-server
to the root build:typecheck-deps script (or run the package's own npm run build
as a prestep), then re-run the root dependency/setup so the module referenced in
manager.addon.ts (AddonConnection and addon-server) can be resolved; ensure the
package.json export paths in packages/addon-server match the generated build
outputs.

In `@application/src/electron/server/addon-server.ts`:
- Around line 183-205: The event handlers on addonServer (the 'input-asked',
'notification', and 'disconnect' listeners) use implicitly typed parameters;
update the callback signatures to add explicit parameter types to fix the
pipeline errors—for example, annotate the 'input-asked' callback parameters
(title: string, description: string, configuration: YourConfigType | unknown,
reply: (result: unknown) => void) and the 'notification' and 'disconnect'
callbacks (notification: YourNotificationType | unknown, reason: string). Use
the existing types or declare/ import appropriate interfaces (or use unknown
instead of implicit any) and keep the usages in inputAskedHandler and
notificationHandler consistent with those types.
- Around line 236-240: The current use of the void operator on
addonServer.start() silently ignores async rejections; change the call to handle
promise rejections explicitly by awaiting the async start() or attaching a
.catch handler so errors go to onError — e.g., replace the void
addonServer.start() call with an awaited call (await addonServer.start()) inside
an async function or addonServer.start().catch(onError) so any async failures
during WebSocket/setup are passed to onError; keep the existing try/catch for
synchronous throws around the awaited call if you choose await.
- Around line 162-166: The code uses __dirname inside addon-server.ts but
doesn't import it; add the named import for __dirname from
'@/electron/manager/manager.paths.js' at the top of the file so the references
in the block that reads config/option/developer.json (where developerConfig and
isSecurityCheckEnabled are used) use the project’s managed __dirname instead of
an undeclared global.
- Line 4: The build pipeline is missing packages/addon-server so the imported
AddonServer (reference: AddonServer import in
application/src/electron/server/addon-server.ts) may not be built; update the
root build:typecheck-deps script to include cd packages/addon-server && bun run
build (add it after all-debrid) and update the application package.json
build:ogiaddon script to include cd ../addon-server/ && bun x tsdown (add it
after all-debrid) so packages/addon-server is built and typechecked along with
ogi-addon, real-debrid, and all-debrid.

In `@application/src/electron/server/api/defer.ts`:
- Around line 48-53: The current 404 branch prints the entire
deferredTasksManager.getTasks() registry which may expose unrelated task data;
change the behavior in the branch that checks
deferredTasksManager.getTasks()[input.taskID] === undefined so it does not dump
the full registry but logs a minimal warning containing only the missing task ID
(use input.taskID and context such as "task not found") and, if needed, return
the 404/appropriate error to the caller; update references in this block around
deferredTasksManager and input.taskID accordingly.

In `@application/src/electron/server/ipc.ts`:
- Line 1: The project typecheck fails because `@ogi-sdk/addon-server`'s published
exports point to ./build/ artifacts that are missing; update the root script
named build:typecheck-deps to include running the addon-server package build (so
the package's build script is invoked before type checking). Ensure the root
script invokes the addon-server build (referencing the package
`@ogi-sdk/addon-server`) so that the DeferrableTask and other exported symbols
referenced in files like application/src/electron/server/ipc.ts resolve to
generated artifacts prior to running typecheck.

In `@application/src/electron/startup.ts`:
- Around line 295-301: The NixOS detection callback for exec('command -v
nixos-rebuild', ...) currently inspects stderr which is empty on success; update
the callback used to set IS_NIXOS to check stdout (e.g., use stdout.trim() or
stdout.includes('nixos-rebuild')) instead of stderr, so resolve(true) when
stdout contains the command path and resolve(false) on error or empty stdout;
keep the existing error handling and resolution flow in the same callback.

In `@packages/addon-server/.gitignore`:
- Line 15: Replace the literal _.log entry in .gitignore with a wildcard pattern
so all log files are ignored: locate the "_.log" pattern and change it to
"*.log" so any filename ending in .log is matched.

In `@packages/addon-server/lib/addon-connection.ts`:
- Line 12: Update the misspelled import path from "@/deffered" to "@/deferred"
where DeferrableTask and DeferredTasksManager are imported (in the import
statement that references DeferrableTask, DeferredTasksManager); also rename the
source module file from deffered.ts to deferred.ts so the module resolution
matches the corrected import, and update any other imports that reference the
old "deffered" filename to "deferred".

In `@packages/addon-server/lib/addon.ts`:
- Around line 93-103: The stop() method may close the same WebSocket twice
because AddonConnection instances appear in both this.connections and
this.clients; update stop() to deduplicate WebSocket closes by tracking
already-closed sockets (e.g., a Set of ws instances) and only call ws.close() if
the ws is not already in the set. Instruct changes in the stop() method to
iterate this.connections and this.clients, add each connection.ws to the seen
set after closing (or skip if already seen), then call this.server.close() and
clear both collections as before.
- Around line 89-91: getSecret() currently uses a non-null assertion on
this.config.secret which can be undefined at runtime; update getSecret to
explicitly handle the missing-secret case: either change its signature to return
string | undefined and return this.config.secret, or (preferred) keep returning
string but validate and throw a descriptive Error when this.config.secret is
undefined (e.g., "Missing secret in config") so callers of getSecret() never
receive undefined; modify the method body in the getSecret implementation and
any callers that assume a string accordingly.

---

Nitpick comments:
In `@packages/addon-server/lib/addon-connection.ts`:
- Around line 188-191: When deferredTask.addonOwner !== this.addonInfo!.id the
code returns silently; update that branch to log a warning/error before
returning so owner mismatches are visible. Add a log call (using the existing
logger instance, e.g., this.logger or processLogger) that records the
deferredTask id (deferredTask.id or deferredTask.taskId), the observed
deferredTask.addonOwner and the expected this.addonInfo!.id, and any relevant
context (e.g., method name in addon-connection.ts) then return as before.

In `@packages/addon-server/lib/addon.ts`:
- Around line 43-48: The constructor currently seeds config.secret with
predictable values using Date.getTime() and Math.random(); update the Addon
constructor to use a cryptographically secure generator instead (e.g., call
crypto.randomUUID() or generate bytes via crypto.randomBytes() and hex/base64
encode) when config.securityCheck is true and no config.secret is provided,
assigning the secure value to config.secret; ensure you import/require Node's
crypto and replace the current `${Math.floor...}` expression used in the
constructor with the secure generator so secret creation is non-deterministic.

In `@packages/addon-server/package.json`:
- Around line 22-23: The devDependency "@types/bun" is set to "latest" which
makes builds non-reproducible; update the package.json devDependencies entry for
"@types/bun" to a specific exact version (no "latest" or floating range) by
replacing "latest" with a pinned semver (e.g. "x.y.z") to ensure consistent
installs—edit the packages/addon-server package.json devDependencies
"@types/bun" entry accordingly.
- Around line 31-35: Remove the external WebSocket deps and unused elysia:
delete "ws" and "websocket" from the dependencies in package.json and also
remove "elysia" if it's unused; then update addon.ts which currently creates the
server with http.createServer and references ws.WebSocketServer to instead use
the platform's built-in WebSocket/WebSocketServer APIs (replace any imports or
references to the ws package), ensuring server creation and connection handling
remain the same but rely on the built-in WebSocket implementation.

In `@packages/ogi-addon/src/main.ts`:
- Around line 819-823: Replace the duplicate local Notification interface
declarations with the exported Notification type: remove the local interface
named Notification in the modules that declared it, add an import of the
exported Notification type (from the addon package) and update any type
annotations/usages to reference that imported Notification type instead of
redeclaring it; ensure no other local symbols conflict with the imported
Notification and run type checks to confirm the types align for
functions/methods that previously used the local interface.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: df4222ae-1e28-45d2-9a76-a5ac472308db

📥 Commits

Reviewing files that changed from the base of the PR and between 998e3b3 and 35414cc.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (35)
  • .vscode/settings.json
  • application/electron.vite.config.ts
  • application/package.json
  • application/src/electron/handlers/handler.addon.ts
  • application/src/electron/handlers/handler.app.ts
  • application/src/electron/handlers/handler.rest.ts
  • application/src/electron/main.ts
  • application/src/electron/manager/manager.addon.ts
  • application/src/electron/server/addon-server.ts
  • application/src/electron/server/api/addons.ts
  • application/src/electron/server/api/defer.ts
  • application/src/electron/server/constants.ts
  • application/src/electron/server/dev-server.ts
  • application/src/electron/server/ipc.ts
  • application/src/electron/startup.ts
  • application/src/frontend/App.svelte
  • application/src/frontend/components/PlayPage.svelte
  • application/src/frontend/components/StorePage.svelte
  • application/src/frontend/tsconfig.json
  • application/src/frontend/views/FocusedAddonView.svelte
  • application/typings/ogi-addon.d.ts
  • package.json
  • packages/addon-server/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc
  • packages/addon-server/.gitignore
  • packages/addon-server/CLAUDE.md
  • packages/addon-server/README.md
  • packages/addon-server/lib/addon-connection.ts
  • packages/addon-server/lib/addon.ts
  • packages/addon-server/lib/deffered.ts
  • packages/addon-server/lib/index.ts
  • packages/addon-server/lib/lib.ts
  • packages/addon-server/package.json
  • packages/addon-server/tsconfig.json
  • packages/addon-server/tsdown.config.js
  • packages/ogi-addon/src/main.ts
💤 Files with no reviewable changes (3)
  • application/typings/ogi-addon.d.ts
  • application/src/electron/server/constants.ts
  • application/src/electron/server/dev-server.ts

Comment on lines +64 to +72
addonServer.stop();
// stop all of the addons
for (const process of Object.keys(processes)) {
console.log(`Killing process ${process}`);
const killed = processes[process].kill('SIGKILL');
console.log(`Killed process ${process}: ${killed}`);
}
// start the server and wait for it to be listening before starting addons
await new Promise<void>((resolve, reject) => {
server.once('error', reject);
server.listen(port, () => {
server.removeListener('error', reject);
console.log(`Addon Server is running on http://localhost:${port}`);
console.log(`Server is being executed by electron!`);
resolve();
});
});
await startAddonServer();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== restartAddonServer callsite =="
sed -n '61,76p' application/src/electron/handlers/handler.addon.ts

echo
echo "== addon server start/stop definitions =="
rg -n -C3 'class AddonServer|stop\s*\(|startAddonServer|listen\s*\(' \
  packages/addon-server \
  application/src/electron/server

Repository: Nat3z/OpenGameInstaller

Length of output: 4155


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Full AddonServer class implementation =="
rg -n -A 150 'export class AddonServer' packages/addon-server/lib/addon.ts | head -200

echo
echo "== Full startAddonServer implementation =="
rg -n -A 30 'function startAddonServer' application/src/electron/server/addon-server.ts

echo
echo "== Server object initialization in addon-server.ts =="
rg -n -B 5 'server\.listen|new.*Server|import.*Server|const.*server' application/src/electron/server/addon-server.ts | head -50

Repository: Nat3z/OpenGameInstaller

Length of output: 4447


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Full addonServer initialization and setup =="
rg -n -A 20 'const addonServer = new AddonServer' application/src/electron/server/addon-server.ts

echo
echo "== Search for addonServer.extend calls =="
rg -n 'addonServer\.extend|\.extend\(' application/src/electron/server/addon-server.ts

Repository: Nat3z/OpenGameInstaller

Length of output: 733


Make addonServer.stop() awaitable or add proper close handling before restarting the server.

The addonServer.stop() method calls this.server.close() synchronously (line 100 of packages/addon-server/lib/addon.ts), but http.Server.close() is asynchronous and doesn't block. In restartAddonServer(), calling stop() without awaiting means await startAddonServer() runs before the port is fully released, creating a potential EADDRINUSE race condition. Either make stop() return a Promise that waits for the close callback, or add explicit close handling in the restart flow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@application/src/electron/handlers/handler.addon.ts` around lines 64 - 72, The
call to addonServer.stop() is currently synchronous but this.server.close() is
async, causing a race where await startAddonServer() may run before the port is
freed; update the stop() implementation (in addon server class where
this.server.close() is called) to return a Promise that resolves in the close
callback (and rejects on error), and then change the restart flow
(restartAddonServer or the handler using addonServer.stop()) to await
addonServer.stop() before killing processes and calling await
startAddonServer(); alternatively, instead of changing stop(), wrap the existing
close call at the restart site in a Promise and await it before proceeding so
startAddonServer() only runs after the server is fully closed.

Comment on lines +192 to +195
const callback = screenInputCallbacks.get(data.id);
if (callback) {
callback(data.data);
screenInputCallbacks.delete(data.id);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Always clear one-shot screen callbacks even if they throw.

If callback(data.data) throws, the map entry survives and this IPC handler rejects, so a stale callback can hang around indefinitely.

Suggested fix
     const callback = screenInputCallbacks.get(data.id);
     if (callback) {
-      callback(data.data);
-      screenInputCallbacks.delete(data.id);
+      screenInputCallbacks.delete(data.id);
+      callback(data.data);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const callback = screenInputCallbacks.get(data.id);
if (callback) {
callback(data.data);
screenInputCallbacks.delete(data.id);
const callback = screenInputCallbacks.get(data.id);
if (callback) {
screenInputCallbacks.delete(data.id);
callback(data.data);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@application/src/electron/handlers/handler.app.ts` around lines 192 - 195, The
one-shot screen input callback stored in screenInputCallbacks is not removed if
callback(data.data) throws, leaving a stale entry; update the IPC handler around
the retrieval of callback (using screenInputCallbacks.get(data.id)) so you
always remove the entry (screenInputCallbacks.delete(data.id)) in a finally-like
guarantee: get the callback, if present run it inside a try/catch but ensure
screenInputCallbacks.delete(data.id) is executed regardless of success or error,
and rethrow or handle the error after deletion so behavior is preserved.

Comment thread application/src/electron/manager/manager.addon.ts Outdated
Comment thread application/src/electron/manager/manager.addon.ts Outdated
const port = 7654;
import http from 'http';
import { WebSocketServer } from 'ws';
import { AddonServer } from '@ogi-sdk/addon-server';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the package is properly configured in the workspace
cat package.json 2>/dev/null | jq '.workspaces' || echo "No root package.json found"

# Check if the addon-server package exists and has build output
fd -t d "addon-server" packages/
ls -la packages/addon-server/build/ 2>/dev/null || echo "Build directory not found"

# Check tsconfig paths configuration
cat application/tsconfig.json 2>/dev/null | jq '.compilerOptions.paths' || echo "No paths config"

Repository: Nat3z/OpenGameInstaller

Length of output: 190


🏁 Script executed:

# Check the package.json in packages/addon-server
cat packages/addon-server/package.json 2>/dev/null | jq '.name, .main, .exports, .type' || echo "No package.json in addon-server"

# Check application's package.json dependencies
cat application/package.json 2>/dev/null | jq '.dependencies, .workspaces' || echo "No package.json in application"

# Check tsconfig configurations
echo "=== application/tsconfig.json ==="
cat application/tsconfig.json 2>/dev/null | jq '.compilerOptions.baseUrl, .compilerOptions.paths, .extends' || echo "No config"

echo "=== packages/addon-server/tsconfig.json ==="
cat packages/addon-server/tsconfig.json 2>/dev/null | jq '.compilerOptions.baseUrl, .compilerOptions.paths, .name' || echo "No config"

# Verify the actual import in addon-server.ts
echo "=== Checking import in the file ==="
head -10 application/src/electron/server/addon-server.ts | cat -n

Repository: Nat3z/OpenGameInstaller

Length of output: 1686


🏁 Script executed:

# Check build scripts in addon-server package
cat packages/addon-server/package.json | jq '.scripts'

# List the actual contents of addon-server directory
echo "=== Contents of packages/addon-server/ ==="
ls -la packages/addon-server/ | head -20

# Check if there's a source directory
echo "=== Source structure ==="
find packages/addon-server -type f -name "*.ts" -o -name "*.js" | head -10

Repository: Nat3z/OpenGameInstaller

Length of output: 1002


🏁 Script executed:

# Check tsdown configuration
echo "=== packages/addon-server/tsdown.config.js ==="
cat packages/addon-server/tsdown.config.js

# Check tsconfig
echo "=== packages/addon-server/tsconfig.json ==="
cat packages/addon-server/tsconfig.json

# Check the main source file
echo "=== packages/addon-server/lib/index.ts ==="
cat packages/addon-server/lib/index.ts

Repository: Nat3z/OpenGameInstaller

Length of output: 1315


🏁 Script executed:

# Check if build is gitignored
echo "=== packages/addon-server/.gitignore ==="
cat packages/addon-server/.gitignore

# Check root .gitignore
echo "=== Root .gitignore (if build patterns exist) ==="
grep -i "build" .gitignore 2>/dev/null || echo "No build patterns in root .gitignore"

Repository: Nat3z/OpenGameInstaller

Length of output: 683


🏁 Script executed:

cd packages/addon-server && npm run build

Repository: Nat3z/OpenGameInstaller

Length of output: 504


🏁 Script executed:

# Check if tsdown is a dev dependency
echo "=== packages/addon-server/package.json devDependencies ==="
cat packages/addon-server/package.json | jq '.devDependencies'

# Check root package.json for tsdown
echo "=== Root package.json devDependencies (tsdown) ==="
cat package.json | jq '.devDependencies' | grep -A2 -B2 "tsdown"

# Check if node_modules exists in addon-server
ls -la packages/addon-server/node_modules 2>/dev/null | head -5 || echo "No node_modules in addon-server"

# Check if tsdown is in root node_modules
ls -la node_modules/.bin/tsdown 2>/dev/null || echo "tsdown not in root node_modules"

Repository: Nat3z/OpenGameInstaller

Length of output: 321


🏁 Script executed:

# Check root package.json devDependencies completely
echo "=== Root package.json ==="
cat package.json | jq '.devDependencies' | head -30

# Check if node_modules exists at root
ls -la node_modules 2>/dev/null | head -10 || echo "No node_modules at root"

# Check what package manager is being used
echo "=== Package manager check ==="
ls -la | grep -E "package-lock|yarn.lock|bun.lockb|pnpm-lock"

# Check if there's a built version somewhere else
echo "=== Search for build outputs ==="
find . -path ./node_modules -prune -o -name "index.cjs" -o -name "index.mjs" | grep -v node_modules

Repository: Nat3z/OpenGameInstaller

Length of output: 272


🏁 Script executed:

# Check root package.json completely
cat package.json | jq .

# Check for lock files more broadly
echo "=== Lock files ==="
ls -la | grep -E "lock|bun"

# Check if there's a build script at root
echo "=== Root build script ==="
cat package.json | jq '.scripts'

# List what's in application directory
echo "=== application package.json scripts ==="
cat application/package.json | jq '.scripts' | head -20

Repository: Nat3z/OpenGameInstaller

Length of output: 4333


🏁 Script executed:

# Check which packages are built in the dependency build script
echo "=== Checking which packages are actually built ==="
grep -A 5 "build:typecheck-deps\|build:ogiaddon" package.json application/package.json

# Check addon-server package.json again to confirm it has build script
cat packages/addon-server/package.json | jq '.scripts'

# List all packages to see what should be built
echo "=== All packages ==="
ls -d packages/*/package.json | xargs -I {} sh -c 'echo "{}:"; cat {} | jq ".name"'

Repository: Nat3z/OpenGameInstaller

Length of output: 2845


🏁 Script executed:

# Verify that addon-server is NOT in any build scripts
echo "=== Checking all build-related scripts ==="
cat package.json application/package.json | jq '.scripts | keys[] | select(contains("build"))'

# Confirm the dependency chain
echo "=== application dependency on addon-server ==="
cat application/package.json | jq '.dependencies | keys[] | select(contains("addon"))'

# Check if there's any mention of addon-server in build docs
find . -maxdepth 2 -name "*.md" -exec grep -l "addon-server\|build" {} \; | head -5

Repository: Nat3z/OpenGameInstaller

Length of output: 279


🏁 Script executed:

# Check the README files for build instructions
echo "=== README.md ==="
head -50 README.md

echo "=== packages/addon-server/README.md ==="
cat packages/addon-server/README.md

Repository: Nat3z/OpenGameInstaller

Length of output: 2702


Critical: @ogi-sdk/addon-server is missing from the build pipeline.

The application depends on @ogi-sdk/addon-server but the package is not included in any build scripts. The root build:typecheck-deps and application build:ogiaddon scripts only build ogi-addon, real-debrid, and all-debrid—addon-server is excluded.

Add packages/addon-server to the build pipeline by including it in the build scripts:

// In root package.json
"build:typecheck-deps": "cd packages/ogi-addon && bun run build && cd ../real-debrid && bun run build && cd ../all-debrid && bun run build && cd ../addon-server && bun run build"

// In application/package.json
"build:ogiaddon": "cd ../packages/ogi-addon/ && bun x tsdown && cd ../real-debrid/ && bun x tsdown && cd ../all-debrid/ && bun x tsdown && cd ../addon-server/ && bun x tsdown"
🧰 Tools
🪛 GitHub Actions: Typecheck

[error] 4-4: svelte-check: Cannot find module '@ogi-sdk/addon-server' or its corresponding type declarations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@application/src/electron/server/addon-server.ts` at line 4, The build
pipeline is missing packages/addon-server so the imported AddonServer
(reference: AddonServer import in
application/src/electron/server/addon-server.ts) may not be built; update the
root build:typecheck-deps script to include cd packages/addon-server && bun run
build (add it after all-debrid) and update the application package.json
build:ogiaddon script to include cd ../addon-server/ && bun x tsdown (add it
after all-debrid) so packages/addon-server is built and typechecked along with
ogi-addon, real-debrid, and all-debrid.

Comment on lines +295 to 301
exec('command -v nixos-rebuild', (error, _stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
resolve(false);
return;
}
if (stderr.includes('nixos-rebuild')) {
resolve(true);
return;
}
resolve(false);
resolve(stderr.includes('nixos-rebuild'));
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current implementation checks stderr and demonstrate command output channel behavior.

set -euo pipefail

echo "1) Inspect detectNixOS implementation"
fd -i "startup.ts" | xargs -I{} sed -n '292,306p' {}

echo
echo "2) Demonstrate where command -v writes output"
{ command -v sh; } > /tmp/cmdv.stdout 2>/tmp/cmdv.stderr || true
echo "stdout bytes: $(wc -c < /tmp/cmdv.stdout)"
echo "stderr bytes: $(wc -c < /tmp/cmdv.stderr)"
echo "stdout content:"
cat /tmp/cmdv.stdout

Repository: Nat3z/OpenGameInstaller

Length of output: 566


Fix NixOS detection to check stdout instead of stderr

Line 300 checks stderr, but command -v nixos-rebuild writes the path to stdout when found and leaves stderr empty. This causes IS_NIXOS to always resolve to false even on valid NixOS systems.

Proposed fix
 function detectNixOS(): Promise<boolean> {
   return new Promise<boolean>((resolve) => {
     try {
       exec('command -v nixos-rebuild', (error, _stdout, stderr) => {
         if (error) {
           resolve(false);
           return;
         }
-        resolve(stderr.includes('nixos-rebuild'));
+        resolve(_stdout.trim().length > 0);
       });
     } catch {
       resolve(false);
     }
   });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@application/src/electron/startup.ts` around lines 295 - 301, The NixOS
detection callback for exec('command -v nixos-rebuild', ...) currently inspects
stderr which is empty on success; update the callback used to set IS_NIXOS to
check stdout (e.g., use stdout.trim() or stdout.includes('nixos-rebuild'))
instead of stderr, so resolve(true) when stdout contains the command path and
resolve(false) on error or empty stdout; keep the existing error handling and
resolution flow in the same callback.


# logs
logs
_.log
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the log file pattern.

Line 15 uses _.log which matches only a file literally named _.log (underscore is a literal character in .gitignore, not a wildcard). This should be *.log to properly ignore all log files.

🔧 Proposed fix
-_.log
+*.log
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_.log
*.log
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/addon-server/.gitignore` at line 15, Replace the literal _.log entry
in .gitignore with a wildcard pattern so all log files are ignored: locate the
"_.log" pattern and change it to "*.log" so any filename ending in .log is
matched.

Comment thread packages/addon-server/lib/addon-connection.ts Outdated
Comment on lines +89 to +91
public getSecret(): string {
return this.config.secret!;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

getSecret() may return undefined at runtime when security is disabled.

When securityCheck is false and no secret is provided, config.secret remains undefined. The non-null assertion (!) will compile but return undefined at runtime, violating the string return type.

🛡️ Proposed fix to handle undefined case
   public getSecret(): string {
-    return this.config.secret!;
+    return this.config.secret ?? '';
   }

Or throw an error if caller requires a valid secret:

   public getSecret(): string {
+    if (!this.config.secret) {
+      throw new Error('Secret not configured - securityCheck is disabled');
+    }
     return this.config.secret;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public getSecret(): string {
return this.config.secret!;
}
public getSecret(): string {
return this.config.secret ?? '';
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/addon-server/lib/addon.ts` around lines 89 - 91, getSecret()
currently uses a non-null assertion on this.config.secret which can be undefined
at runtime; update getSecret to explicitly handle the missing-secret case:
either change its signature to return string | undefined and return
this.config.secret, or (preferred) keep returning string but validate and throw
a descriptive Error when this.config.secret is undefined (e.g., "Missing secret
in config") so callers of getSecret() never receive undefined; modify the method
body in the getSecret implementation and any callers that assume a string
accordingly.

Comment on lines +93 to +103
public stop(): void {
this.connections.forEach((connection) => {
connection.ws.close();
});
this.clients.forEach((client) => {
client.ws.close();
});
this.server.close();
this.connections.clear();
this.clients.clear();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

stop() may close the same WebSocket twice.

this.connections and this.clients can contain overlapping AddonConnection instances (a connection is added to connections on connect and to clients after authentication). Closing the same WebSocket twice may cause issues or log errors.

♻️ Proposed fix to avoid double-close
   public stop(): void {
-    this.connections.forEach((connection) => {
-      connection.ws.close();
-    });
-    this.clients.forEach((client) => {
-      client.ws.close();
-    });
+    // Close all connections (clients are a subset of connections)
+    for (const connection of this.connections) {
+      connection.ws.close();
+    }
     this.server.close();
     this.connections.clear();
     this.clients.clear();
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/addon-server/lib/addon.ts` around lines 93 - 103, The stop() method
may close the same WebSocket twice because AddonConnection instances appear in
both this.connections and this.clients; update stop() to deduplicate WebSocket
closes by tracking already-closed sockets (e.g., a Set of ws instances) and only
call ws.close() if the ws is not already in the set. Instruct changes in the
stop() method to iterate this.connections and this.clients, add each
connection.ws to the seen set after closing (or skip if already seen), then call
this.server.close() and clear both collections as before.

- Added support for the new '@ogi-sdk/executor' package in the project.
- Updated build scripts to include the executor build process.
- Refactored addon management to utilize the new Addon class from the executor, improving addon loading and execution consistency.
- Implemented logging for setup scripts and improved error handling during addon installation.
- Removed deprecated process management in favor of the new executor methods.
@Nat3z
Copy link
Copy Markdown
Owner Author

Nat3z commented May 2, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Nat3z
Copy link
Copy Markdown
Owner Author

Nat3z commented May 2, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Nat3z Nat3z merged commit 9cb1d56 into main May 5, 2026
4 of 6 checks passed
@Nat3z Nat3z deleted the feat/addon-server-package branch May 5, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant