@chittyos/core
Version:
ChittyOS Core - Essential package with ID, auth, verification, beacon tracking, and brand components for all ChittyOS applications
227 lines (225 loc) • 6.94 kB
JavaScript
// src/chittychat/index.ts
import { EventEmitter } from "eventemitter3";
// src/beacon/index.ts
import { nanoid } from "nanoid";
import * as os from "os";
import * as fs from "fs";
import { execSync } from "child_process";
var DEFAULT_CONFIG = {
endpoint: process.env.CHITTY_BEACON_ENDPOINT || "https://beacon.chitty.cc",
interval: parseInt(process.env.CHITTY_BEACON_INTERVAL || "") || 3e5,
enabled: process.env.CHITTY_BEACON_DISABLED !== "true",
silent: process.env.CHITTY_BEACON_VERBOSE !== "true"
};
var config = { ...DEFAULT_CONFIG };
var appInfo = null;
var heartbeatInterval = null;
function configure(customConfig) {
config = { ...config, ...customConfig };
}
function detectApp() {
const app = {
id: generateAppId(),
name: detectAppName(),
version: detectVersion(),
platform: detectPlatform(),
environment: process.env.NODE_ENV || "production",
hostname: os.hostname(),
nodeVersion: process.version,
os: `${os.type()} ${os.release()}`,
hasClaudeCode: detectClaudeCode(),
hasGit: fs.existsSync(".git"),
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
pid: process.pid,
chittyos: {
core: "1.0.0",
modules: detectChittyModules()
}
};
if (app.hasGit) {
try {
app.git = {
branch: execSync("git branch --show-current", { encoding: "utf8" }).trim(),
commit: execSync("git rev-parse --short HEAD", { encoding: "utf8" }).trim(),
remote: execSync("git remote get-url origin", { encoding: "utf8" }).trim()
};
} catch (e) {
}
}
return app;
}
function generateAppId() {
if (config.appId) return config.appId;
if (process.env.REPL_ID) return `replit-${process.env.REPL_ID}`;
if (process.env.GITHUB_REPOSITORY) return `github-${process.env.GITHUB_REPOSITORY.replace("/", "-")}`;
if (process.env.VERCEL_URL) return `vercel-${process.env.VERCEL_URL}`;
if (process.env.HEROKU_APP_NAME) return `heroku-${process.env.HEROKU_APP_NAME}`;
try {
const pkg = JSON.parse(fs.readFileSync("./package.json", "utf8"));
return `npm-${pkg.name}-${nanoid(8)}`;
} catch (e) {
return `chitty-${nanoid()}`;
}
}
function detectAppName() {
if (config.appName) return config.appName;
return process.env.CHITTY_APP_NAME || process.env.REPL_SLUG || process.env.GITHUB_REPOSITORY || process.env.VERCEL_URL || process.env.HEROKU_APP_NAME || process.env.npm_package_name || (() => {
try {
const pkg = JSON.parse(fs.readFileSync("./package.json", "utf8"));
return pkg.name;
} catch (e) {
return "chittyos-app";
}
})();
}
function detectVersion() {
try {
const pkg = JSON.parse(fs.readFileSync("./package.json", "utf8"));
return pkg.version;
} catch (e) {
return "0.0.0";
}
}
function detectPlatform() {
if (process.env.REPL_ID) return "replit";
if (process.env.GITHUB_ACTIONS) return "github-actions";
if (process.env.VERCEL) return "vercel";
if (process.env.NETLIFY) return "netlify";
if (process.env.RENDER) return "render";
if (process.env.HEROKU_APP_NAME) return "heroku";
if (process.env.AWS_LAMBDA_FUNCTION_NAME) return "aws-lambda";
if (process.env.GOOGLE_CLOUD_PROJECT) return "google-cloud";
if (process.env.WEBSITE_INSTANCE_ID) return "azure";
if (process.env.CF_PAGES) return "cloudflare-pages";
if (process.env.CLOUDFLARE_ACCOUNT_ID) return "cloudflare-workers";
return "unknown";
}
function detectClaudeCode() {
return process.env.CLAUDE_CODE === "true" || fs.existsSync(".claude") || fs.existsSync("CLAUDE.md") || fs.existsSync("claude.json");
}
function detectChittyModules() {
const modules = [];
try {
const pkg = JSON.parse(fs.readFileSync("./package.json", "utf8"));
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
for (const dep of Object.keys(deps)) {
if (dep.startsWith("@chittyos/") || dep.startsWith("@chittycorp/")) {
modules.push(dep);
}
}
} catch (e) {
}
return modules;
}
async function sendBeacon(event, data) {
if (!config.enabled) return;
const payload = {
...appInfo,
event,
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
uptime: process.uptime(),
...data
};
try {
const response = await fetch(`${config.endpoint}/track`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "@chittyos/core/1.0.0"
},
body: JSON.stringify(payload)
});
if (!config.silent && !response.ok) {
console.log(`[ChittyBeacon] Response: ${response.status}`);
}
} catch (error) {
if (!config.silent) {
console.log(`[ChittyBeacon] Error: ${error.message}`);
}
}
}
function init(customConfig) {
if (customConfig) {
configure(customConfig);
}
if (!config.enabled) {
if (!config.silent) {
console.log("[ChittyBeacon] Disabled");
}
return;
}
appInfo = detectApp();
sendBeacon("startup");
heartbeatInterval = setInterval(() => {
sendBeacon("heartbeat");
}, config.interval);
heartbeatInterval.unref();
const shutdown = () => {
sendBeacon("shutdown");
};
process.once("exit", shutdown);
process.once("SIGINT", shutdown);
process.once("SIGTERM", shutdown);
if (!config.silent) {
console.log(`[ChittyBeacon] Tracking ${appInfo.name} on ${appInfo.platform}`);
}
}
if (process.env.NODE_ENV !== "test") {
init();
}
// src/chittychat/index.ts
var ChittyChatClient = class extends EventEmitter {
config;
ws = null;
constructor(config2 = {}) {
super();
this.config = {
endpoint: config2.endpoint || process.env.CHITTY_CHAT_ENDPOINT || "https://chat.chitty.cc",
wsEndpoint: config2.wsEndpoint || process.env.CHITTY_CHAT_WS || "wss://ws.chitty.cc",
apiKey: config2.apiKey || process.env.CHITTY_CHAT_API_KEY
};
}
async connect(chittyId) {
const url = `${this.config.wsEndpoint}?chittyId=${chittyId}`;
this.ws = new WebSocket(url);
return new Promise((resolve, reject) => {
this.ws.onopen = () => {
sendBeacon("chittychat_connected", { chittyId });
resolve();
};
this.ws.onerror = (error) => reject(error);
this.ws.onmessage = (event) => {
this.emit("message", JSON.parse(event.data));
};
});
}
async send(message) {
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
throw new Error("Not connected to ChittyChat");
}
this.ws.send(JSON.stringify(message));
sendBeacon("chittychat_message_sent");
}
disconnect() {
if (this.ws) {
this.ws.close();
this.ws = null;
}
}
};
var clientInstance = null;
function getChittyChat(config2) {
if (!clientInstance) {
clientInstance = new ChittyChatClient(config2);
}
return clientInstance;
}
var chittychat_default = {
getChittyChat,
ChittyChatClient
};
export {
chittychat_default as default,
getChittyChat
};
//# sourceMappingURL=index.mjs.map