Publish curated chimera source from 95e6b4be8a9669686a6241fda6f22034fd8d0b5c

This commit is contained in:
Public Source Publisher committed 2026-10-01 01:07:36 +00:00
1 parent c737a37f71
commit 3ceefb175f
7 files changed
+1361 -1001

No files matched your search

+1
View File
@@ -4,6 +4,7 @@ ENV NODE_ENV=production CHIMERA_DATA_DIR=/data
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force
COPY --chown=node:node src ./src COPY --chown=node:node src ./src
COPY --chown=node:node PSNotifyModule ./PSNotifyModule
COPY --chown=node:node renderer ./renderer COPY --chown=node:node renderer ./renderer
COPY --chown=node:node build ./build COPY --chown=node:node build ./build
COPY --chown=node:node server.js ./server.js COPY --chown=node:node server.js ./server.js
+148
View File
@@ -0,0 +1,148 @@
# PSNotifyModule
Drop-in Node.js / Electron module for sending toast notifications to a jailbroken PS5 running `customPSNotify.js`.
No npm dependencies — uses Node's built-in `net` module only.
---
## Setup
1. Copy the `PSNotifyModule/` folder into your project.
2. Make sure `customPSNotify.js` is loaded and running on your PS5.
3. `require` the module by path — done.
```js
const { PS5Notifier, notify } = require('./PSNotifyModule');
```
---
## API
### `notify(host, message, [opts])` — one-shot function
Connects, sends, waits for ACK, disconnects. No instance needed.
```js
const { notify } = require('./PSNotifyModule');
await notify('192.168.1.100', 'Build finished!');
await notify('192.168.1.100', 'Deploy complete', {
subMessage : 'v2.1.0 is live',
port : 6969, // default
timeout : 5000, // ms, default
});
```
| Parameter | Type | Required | Description |
|---|---|---|---|
| `host` | string | yes | PS5 IP address |
| `message` | string | yes | Main toast body |
| `opts.subMessage` | string | no | Smaller text below body |
| `opts.port` | number | no | Port (default `6969`) |
| `opts.timeout` | number | no | Timeout in ms (default `5000`) |
**Returns:** `Promise<{ ok: boolean }>` — resolves with the ACK from the PS5, rejects on connection error / timeout.
---
### `PS5Notifier` — stateful class
Instantiate once, reuse throughout your app. Remembers the host, port, and timeout. Keeps a history of sent notifications.
```js
const { PS5Notifier } = require('./PSNotifyModule');
const ps5 = new PS5Notifier('192.168.1.100');
// send(message, [opts])
await ps5.send('App started');
await ps5.send('Build complete', { subMessage: 'v2.1.0 — 0 errors' });
// history([n]) — last n sent notifications (default 50)
const log = ps5.history();
// [{ ts, message, subMessage, ok }, ...]
// setHost(host) — update IP at runtime
ps5.setHost('192.168.1.105');
```
#### Constructor
```js
new PS5Notifier(host, [defaults])
```
| Parameter | Type | Required | Description |
|---|---|---|---|
| `host` | string | yes | PS5 IP address |
| `defaults.port` | number | no | Default port (6969) |
| `defaults.timeout` | number | no | Default timeout ms (5000) |
#### Methods
| Method | Returns | Description |
|---|---|---|
| `send(message, [opts])` | `Promise<{ok}>` | Send a notification |
| `history([n])` | `Array` | Last `n` sent entries |
| `setHost(host)` | `void` | Change the target PS5 IP |
---
## Electron example
```js
// main.js
const { PS5Notifier } = require('./PSNotifyModule');
const ps5 = new PS5Notifier(
'192.168.1.100',
{ timeout: 3000 }
);
// Call from anywhere in your app:
ipcMain.on('build-complete', async (_, version) => {
await ps5.send('Build complete', { subMessage: version }).catch(() => {});
});
```
---
## Test
```bash
node test.js <ps5-ip>
node test.js <ps5-ip> "Custom message" "Sub text"
```
Or on Windows, double-click **`test.bat`** and enter your PS5 IP when prompted.
---
## Files
| File | Purpose |
|---|---|
| `index.js` | Module — `notify()` + `PS5Notifier` class |
| `test.js` | Standalone test runner |
| `test.bat` | Windows batch launcher for test.js |
| `package.json` | Module metadata |
| `README.md` | This file |
---
## Wire protocol (for reference)
The module sends a UTF-8 JSON line to the PS5 over TCP:
```
{"message":"Hello!","subMessage":"optional"}\n
```
The PS5 responds:
```
{"ok":true}\n
```
+188
View File
@@ -0,0 +1,188 @@
'use strict';
/**
* PSNotifyModule
* ──────────────
* Drop this folder into any Node.js / Electron project.
* Sends toast notifications to a PS5 running customPSNotify.js.
*
* QUICK START
* ───────────
* const { PS5Notifier } = require('./PSNotifyModule');
*
* const ps5 = new PS5Notifier('192.168.1.100');
* await ps5.send('Build finished!');
* await ps5.send('Deploy done', { subMessage: 'v2.1.0 is live' });
*
* ONE-SHOT (no instance needed)
* ─────────────────────────────
* const { notify } = require('./PSNotifyModule');
* await notify('192.168.1.100', 'Hello PS5!');
*/
const net = require('net');
const DEFAULT_PORT = 6969;
const DEFAULT_TIMEOUT = 5000; // ms
// ─── Low-level send ──────────────────────────────────────────────────────────
/**
* Send a single notification to a PS5.
*
* @param {string} host PS5 IP address or hostname
* @param {string} message Main toast body text
* @param {object} [opts]
* @param {string} [opts.subMessage] Smaller line below the body
* @param {number} [opts.port] TCP port (default 6969)
* @param {number} [opts.timeout] Timeout in ms (default 5000)
* @returns {Promise<{ok: boolean}>} Resolves with the ACK from the PS5
*/
function notify(host, message, opts = {}) {
const port = opts.port ?? DEFAULT_PORT;
const timeout = opts.timeout ?? DEFAULT_TIMEOUT;
const subMessage = opts.subMessage ?? '';
if (!host) return Promise.reject(new TypeError('host is required'));
if (!message) return Promise.reject(new TypeError('message is required'));
// Encode the JSON packet as explicit UTF-8 bytes so that emoji and other
// multi-byte Unicode characters survive the trip to the PS5 intact.
const packetBuf = Buffer.from(JSON.stringify({ message, subMessage }) + '\n', 'utf8');
return new Promise((resolve, reject) => {
const sock = net.createConnection({ host, port });
let raw = '';
let done = false;
// Hard timeout — fires if the server never responds.
const timer = setTimeout(() => {
if (done) return;
done = true;
sock.destroy();
reject(new Error(`Timed out connecting to ${host}:${port} after ${timeout}ms`));
}, timeout);
const finish = (err) => {
if (done) return;
done = true;
clearTimeout(timer);
sock.destroy();
if (err) return reject(err);
try { resolve(JSON.parse(raw.trim())); }
catch { resolve({ ok: true }); }
};
sock.once('connect', () => {
sock.write(packetBuf, (err) => {
if (err) finish(err);
// Don't close — wait for the {"ok":true} response from the PS5 server.
});
});
sock.on('data', (chunk) => {
raw += chunk.toString();
// The PS5 server responds with {"ok":true} then keeps the socket open.
// As soon as we have a complete JSON response, resolve and close.
if (raw.includes('}')) finish(null);
});
// If the server does close its side, honour it.
// If the server closes its side gracefully, honour it.
sock.once('end', () => finish(null));
sock.once('error', (err) => {
// ECONNRESET means the server RST'd after receiving our packet — the
// notification was delivered. A genuine connection failure (wrong IP /
// port not open) produces ECONNREFUSED or a timeout, never a reset.
// Use setImmediate so any buffered 'data' events get one more tick to
// fire and populate `raw` before we resolve.
if (err.code === 'ECONNRESET') {
setImmediate(() => finish(null));
} else {
finish(err);
}
});
});
}
// ─── PS5Notifier class ───────────────────────────────────────────────────────
/**
* Stateful client that remembers the PS5 host and default options.
* Designed to be instantiated once per app and reused.
*
* @example
* const ps5 = new PS5Notifier('192.168.1.100');
* await ps5.send('Hello!');
* await ps5.send('Status', { subMessage: 'All good' });
*/
class PS5Notifier {
/**
* @param {string} host PS5 IP address
* @param {object} [defaults]
* @param {number} [defaults.port] Default port (6969)
* @param {number} [defaults.timeout] Default timeout ms (5000)
*/
constructor(host, defaults = {}) {
if (!host) throw new TypeError('PS5Notifier: host is required');
this.host = host;
this.port = defaults.port ?? DEFAULT_PORT;
this.timeout = defaults.timeout ?? DEFAULT_TIMEOUT;
this._history = [];
}
/**
* Send a notification to the PS5.
*
* @param {string} message
* @param {object} [opts]
* @param {string} [opts.subMessage]
* @param {number} [opts.port] Override port for this call
* @param {number} [opts.timeout] Override timeout for this call
* @returns {Promise<{ok: boolean}>}
*/
async send(message, opts = {}) {
const result = await notify(this.host, message, {
subMessage: opts.subMessage ?? '',
port: opts.port ?? this.port,
timeout: opts.timeout ?? this.timeout,
});
this._history.push({
ts: new Date().toISOString(),
message,
subMessage: opts.subMessage ?? '',
ok: result.ok ?? true,
});
return result;
}
/**
* Returns the last N notifications sent (default 50).
* @param {number} [n]
*/
history(n = 50) {
return this._history.slice(-n);
}
/** Update the PS5 host at runtime (e.g. if IP changes). */
setHost(host) {
this.host = host;
}
toString() {
return `PS5Notifier(${this.host}:${this.port})`;
}
}
// ─── Exports ─────────────────────────────────────────────────────────────────
module.exports = {
/** One-shot function — no instance needed */
notify,
/** Stateful class — instantiate once and reuse */
PS5Notifier,
DEFAULT_PORT,
DEFAULT_TIMEOUT,
};
+8
View File
@@ -0,0 +1,8 @@
{
"name": "ps-notify-module",
"version": "1.0.0",
"description": "Send toast notifications to a jailbroken PS5 from Node.js or Electron",
"main": "index.js",
"keywords": ["ps5", "notify", "toast", "electron", "jailbreak"],
"license": "MIT"
}
+1 -1
View File
@@ -1,3 +1,3 @@
# Public source export # Public source export
This source snapshot was generated from the private canonical repository at revision `a8ae5b1db07fb49926c94585e2718e5130330974`. It contains no private Git history or operational evidence. Changes are published from the canonical repository. This source snapshot was generated from the private canonical repository at revision `95e6b4be8a9669686a6241fda6f22034fd8d0b5c`. It contains no private Git history or operational evidence. Changes are published from the canonical repository.
+1014 -999
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1,6 +1,6 @@
# Third-party notices # Third-party notices
The Apache-2.0 license applies to original Chimera source. Dependencies retain their own license and copyright notices; versions are pinned in `package-lock.json`. The Apache-2.0 license applies to original Chimera source. The bundled `PSNotifyModule` retains its existing MIT package license declaration. Dependencies retain their own license and copyright notices; versions are pinned in `package-lock.json`.
Historical bundled tools and payloads whose provenance or redistribution rights were not established are excluded from this public source and public releases, including ELF/BIN console payloads, native EXE/DLL/PDB helpers, JAR archives, firmware and package assets. No license grant is made for those components. Obtain optional prerequisites separately from their authorized publishers and comply with their terms. Historical bundled tools and payloads whose provenance or redistribution rights were not established are excluded from this public source and public releases, including ELF/BIN console payloads, native EXE/DLL/PDB helpers, JAR archives, firmware and package assets. No license grant is made for those components. Obtain optional prerequisites separately from their authorized publishers and comply with their terms.