@chittyos/core
Version:
ChittyOS Core - Essential package with ID, auth, verification, beacon tracking, and brand components for all ChittyOS applications
1,722 lines (1,694 loc) • 49.2 kB
JavaScript
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/beacon/index.ts
var beacon_exports = {};
__export(beacon_exports, {
configure: () => configure,
detectApp: () => detectApp,
init: () => init,
sendBeacon: () => sendBeacon,
stop: () => stop
});
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}`);
}
}
function stop() {
if (heartbeatInterval) {
clearInterval(heartbeatInterval);
heartbeatInterval = null;
}
sendBeacon("stopped");
}
if (process.env.NODE_ENV !== "test") {
init();
}
// src/id/index.ts
var id_exports = {};
__export(id_exports, {
configure: () => configure2,
default: () => id_default,
generate: () => generate,
getSessionContext: () => getSessionContext,
isValidChittyID: () => isValidChittyID,
parseChittyID: () => parseChittyID,
requestChittyID: () => requestChittyID,
setSessionContext: () => setSessionContext,
signData: () => signData,
validateRemote: () => validateRemote,
verifySignature: () => verifySignature
});
import * as crypto from "crypto";
var DEFAULT_CONFIG2 = {
endpoint: process.env.CHITTY_ID_ENDPOINT || "https://id.chitty.cc",
apiKey: process.env.CHITTY_ID_API_KEY,
generateKeys: true
};
var config2 = { ...DEFAULT_CONFIG2 };
function configure2(customConfig) {
config2 = { ...config2, ...customConfig };
}
async function requestChittyID(metadata) {
if (!config2.apiKey) {
throw new Error("ChittyID request requires API key authentication to access id.chitty.cc service");
}
try {
const response = await fetch(`${config2.endpoint}/api/pipeline/generate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${config2.apiKey}`
},
body: JSON.stringify({
metadata,
// Include session context for distributed sync
sessionId: globalThis.chittySessionId || void 0
})
});
if (!response.ok) {
if (response.status === 401) {
throw new Error("ChittyID request failed: Invalid or expired API key for id.chitty.cc");
}
if (response.status === 403) {
throw new Error("ChittyID request failed: Insufficient permissions for id.chitty.cc service");
}
throw new Error(`ChittyID service error: ${response.status} - ${response.statusText}`);
}
const result = await response.json();
if (result.metadata?.sessionId) {
globalThis.chittySessionId = result.metadata.sessionId;
}
return result;
} catch (error) {
throw error;
}
}
async function generate(metadata) {
if (!config2.endpoint) {
throw new Error("ChittyID service endpoint not configured - set CHITTY_ID_ENDPOINT to id.chitty.cc");
}
return await requestChittyID(metadata);
}
function verifySignature(chittyId, signature, data, publicKey) {
try {
const verify = crypto.createVerify("SHA256");
verify.update(data);
return verify.verify(publicKey, signature, "base64");
} catch (error) {
return false;
}
}
function signData(data, privateKey) {
const sign = crypto.createSign("SHA256");
sign.update(data);
return sign.sign(privateKey, "base64");
}
function isValidChittyID(id) {
return /^CID_[A-Za-z0-9_-]{21}$/.test(id);
}
function parseChittyID(input) {
if (isValidChittyID(input)) return input;
const cidMatch = input.match(/CID_[A-Za-z0-9_-]{21}/);
if (cidMatch) return cidMatch[0];
return null;
}
async function validateRemote(chittyId) {
try {
const response = await fetch(`${config2.endpoint}/api/validate/${chittyId}`, {
method: "GET",
headers: {
...config2.apiKey && { "Authorization": `Bearer ${config2.apiKey}` }
}
});
if (response.ok) {
const result = await response.json();
return result.valid === true;
}
return false;
} catch (error) {
console.warn("[ChittyID] Validation service unavailable, using local validation");
return isValidChittyID(chittyId);
}
}
function getSessionContext() {
return globalThis.chittySessionId;
}
function setSessionContext(sessionId) {
globalThis.chittySessionId = sessionId;
}
var id_default = {
configure: configure2,
generate,
requestChittyID,
validateRemote,
verifySignature,
signData,
isValidChittyID,
parseChittyID,
getSessionContext,
setSessionContext
};
// src/auth/index.ts
var auth_exports = {};
__export(auth_exports, {
cleanupSessions: () => cleanupSessions,
configure: () => configure3,
createToken: () => createToken,
default: () => auth_default,
hasPermissions: () => hasPermissions,
hasRoles: () => hasRoles,
hashPassword: () => hashPassword,
refreshToken: () => refreshToken,
revokeSession: () => revokeSession,
verifyPassword: () => verifyPassword,
verifyToken: () => verifyToken
});
import { SignJWT, jwtVerify } from "jose";
import { nanoid as nanoid2 } from "nanoid";
import * as crypto2 from "crypto";
var DEFAULT_CONFIG3 = {
jwtSecret: process.env.CHITTY_JWT_SECRET || crypto2.randomBytes(32).toString("base64"),
issuer: "chittyos",
audience: "chittyos-apps",
expiresIn: "24h"
};
var config3 = { ...DEFAULT_CONFIG3 };
var sessions = /* @__PURE__ */ new Map();
function configure3(customConfig) {
config3 = { ...config3, ...customConfig };
}
async function createToken(user) {
const secret = new TextEncoder().encode(config3.jwtSecret);
const expiresAt = /* @__PURE__ */ new Date();
const hours = parseInt(config3.expiresIn?.replace("h", "") || "24");
expiresAt.setHours(expiresAt.getHours() + hours);
const token = await new SignJWT({
sub: user.id,
chittyId: user.chittyId,
email: user.email,
roles: user.roles || [],
permissions: user.permissions || [],
metadata: user.metadata || {}
}).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setIssuer(config3.issuer).setAudience(config3.audience).setExpirationTime(config3.expiresIn).setJti(nanoid2()).sign(secret);
const refreshToken2 = nanoid2(32);
const session = {
id: nanoid2(),
userId: user.id,
token,
refreshToken: refreshToken2,
expiresAt,
createdAt: /* @__PURE__ */ new Date()
};
sessions.set(session.id, session);
sessions.set(refreshToken2, session);
return {
token,
expiresAt,
refreshToken: refreshToken2
};
}
async function verifyToken(token) {
try {
const secret = new TextEncoder().encode(config3.jwtSecret);
const { payload } = await jwtVerify(token, secret, {
issuer: config3.issuer,
audience: config3.audience
});
return {
...payload,
id: payload.sub,
chittyId: payload.chittyId,
email: payload.email,
roles: payload.roles,
permissions: payload.permissions,
metadata: payload.metadata
};
} catch (error) {
throw new Error("Invalid or expired token");
}
}
async function refreshToken(refreshToken2) {
const session = sessions.get(refreshToken2);
if (!session) {
throw new Error("Invalid refresh token");
}
if (session.expiresAt < /* @__PURE__ */ new Date()) {
sessions.delete(session.id);
sessions.delete(session.refreshToken);
throw new Error("Session expired");
}
const user = await verifyToken(session.token).catch(() => null);
if (!user) {
throw new Error("Cannot refresh token");
}
return createToken({
id: user.id,
chittyId: user.chittyId,
email: user.email,
roles: user.roles,
permissions: user.permissions,
metadata: user.metadata
});
}
function revokeSession(sessionId) {
const session = sessions.get(sessionId);
if (session) {
sessions.delete(session.id);
sessions.delete(session.refreshToken);
return true;
}
return false;
}
function hasRoles(user, requiredRoles) {
if (!user.roles) return false;
return requiredRoles.every((role) => user.roles.includes(role));
}
function hasPermissions(user, requiredPermissions) {
if (!user.permissions) return false;
return requiredPermissions.every((perm) => user.permissions.includes(perm));
}
async function hashPassword(password) {
const salt = crypto2.randomBytes(16).toString("hex");
const hash = crypto2.pbkdf2Sync(password, salt, 1e5, 64, "sha512").toString("hex");
return `${salt}:${hash}`;
}
async function verifyPassword(password, hashedPassword) {
const [salt, hash] = hashedPassword.split(":");
const verifyHash = crypto2.pbkdf2Sync(password, salt, 1e5, 64, "sha512").toString("hex");
return hash === verifyHash;
}
function cleanupSessions() {
const now = /* @__PURE__ */ new Date();
for (const [key, session] of sessions) {
if (session.expiresAt < now) {
sessions.delete(key);
}
}
}
setInterval(cleanupSessions, 36e5).unref();
var auth_default = {
configure: configure3,
createToken,
verifyToken,
refreshToken,
revokeSession,
hasRoles,
hasPermissions,
hashPassword,
verifyPassword,
cleanupSessions
};
// src/verify/index.ts
var verify_exports = {};
__export(verify_exports, {
configure: () => configure4,
default: () => verify_default,
hashData: () => hashData,
sanitizeInput: () => sanitizeInput,
schemas: () => schemas,
signData: () => signData2,
validateChecksum: () => validateChecksum,
validateJSON: () => validateJSON,
validateSchema: () => validateSchema,
verifyIntegrity: () => verifyIntegrity,
verifySignedData: () => verifySignedData
});
import { z } from "zod";
import * as crypto3 from "crypto";
var DEFAULT_CONFIG4 = {
strictMode: false,
hashAlgorithm: "sha256"
};
var config4 = { ...DEFAULT_CONFIG4 };
function configure4(customConfig) {
config4 = { ...config4, ...customConfig };
}
function validateSchema(data, schema) {
try {
const validated = schema.parse(data);
return {
valid: true,
data: validated
};
} catch (error) {
if (error instanceof z.ZodError) {
return {
valid: false,
errors: error.errors.map((e) => `${e.path.join(".")}: ${e.message}`)
};
}
return {
valid: false,
errors: ["Validation failed"]
};
}
}
var schemas = {
email: z.string().email(),
chittyId: z.string().regex(/^CID_[A-Za-z0-9_-]{21}$/),
uuid: z.string().uuid(),
url: z.string().url(),
phoneNumber: z.string().regex(/^\+?[1-9]\d{1,14}$/),
dateTime: z.string().datetime(),
ipAddress: z.string().ip(),
semver: z.string().regex(/^\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?$/),
strongPassword: z.string().min(8).regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/),
jwt: z.string().regex(/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/),
base64: z.string().regex(/^[A-Za-z0-9+/]*={0,2}$/),
hexColor: z.string().regex(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/),
creditCard: z.string().regex(/^\d{13,19}$/).refine(luhnCheck, {
message: "Invalid credit card number"
})
};
function luhnCheck(cardNumber) {
const digits = cardNumber.replace(/\D/g, "");
let sum = 0;
let isEven = false;
for (let i = digits.length - 1; i >= 0; i--) {
let digit = parseInt(digits[i], 10);
if (isEven) {
digit *= 2;
if (digit > 9) {
digit -= 9;
}
}
sum += digit;
isEven = !isEven;
}
return sum % 10 === 0;
}
function hashData(data, algorithm = config4.hashAlgorithm) {
const stringData = typeof data === "string" ? data : JSON.stringify(data);
return crypto3.createHash(algorithm).update(stringData).digest("hex");
}
function verifyIntegrity(data, expectedHash, algorithm = config4.hashAlgorithm) {
const actualHash = hashData(data, algorithm);
return actualHash === expectedHash;
}
function signData2(data, privateKey, chittyId) {
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
const dataToSign = JSON.stringify({ data, timestamp });
const sign = crypto3.createSign("SHA256");
sign.update(dataToSign);
const signature = sign.sign(privateKey, "base64");
return {
data,
signature,
timestamp,
chittyId
};
}
function verifySignedData(signedData, publicKey) {
try {
const dataToVerify = JSON.stringify({
data: signedData.data,
timestamp: signedData.timestamp
});
const verify = crypto3.createVerify("SHA256");
verify.update(dataToVerify);
const isValid = verify.verify(publicKey, signedData.signature, "base64");
return {
valid: isValid,
errors: isValid ? void 0 : ["Invalid signature"]
};
} catch (error) {
return {
valid: false,
errors: ["Signature verification failed"]
};
}
}
async function validateChecksum(filePath, expectedChecksum, algorithm = "sha256") {
const fs2 = await import("fs");
const stream = fs2.createReadStream(filePath);
const hash = crypto3.createHash(algorithm);
return new Promise((resolve, reject) => {
stream.on("data", (data) => hash.update(data));
stream.on("end", () => {
const actualChecksum = hash.digest("hex");
resolve(actualChecksum === expectedChecksum);
});
stream.on("error", reject);
});
}
function sanitizeInput(input) {
let sanitized = input.replace(/[\x00-\x1F\x7F]/g, "");
sanitized = sanitized.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/");
return sanitized.trim();
}
function validateJSON(jsonString) {
try {
const parsed = JSON.parse(jsonString);
return {
valid: true,
data: parsed
};
} catch (error) {
return {
valid: false,
errors: ["Invalid JSON: " + error.message]
};
}
}
var verify_default = {
configure: configure4,
validateSchema,
schemas,
hashData,
verifyIntegrity,
signData: signData2,
verifySignedData,
validateChecksum,
sanitizeInput,
validateJSON
};
// src/brand/index.ts
var brand_exports = {};
__export(brand_exports, {
ASCII_LOGO: () => ASCII_LOGO,
BRAND_CONFIG: () => BRAND_CONFIG,
CHITTY_COLORS: () => CHITTY_COLORS,
CHITTY_THEME: () => CHITTY_THEME,
default: () => brand_default,
generateStyleTag: () => generateStyleTag,
generateTailwindConfig: () => generateTailwindConfig,
generateThemeProvider: () => generateThemeProvider,
getCSSVariables: () => getCSSVariables
});
var CHITTY_COLORS = {
light: {
primary: "#0F172A",
secondary: "#64748B",
accent: "#3B82F6",
background: "#FFFFFF",
foreground: "#0F172A",
muted: "#F1F5F9",
mutedForeground: "#64748B",
border: "#E2E8F0",
destructive: "#EF4444",
success: "#10B981",
warning: "#F59E0B",
info: "#3B82F6"
},
dark: {
primary: "#F8FAFC",
secondary: "#94A3B8",
accent: "#60A5FA",
background: "#0F172A",
foreground: "#F8FAFC",
muted: "#1E293B",
mutedForeground: "#94A3B8",
border: "#334155",
destructive: "#F87171",
success: "#34D399",
warning: "#FBBF24",
info: "#60A5FA"
}
};
var CHITTY_THEME = {
name: "ChittyOS Default",
colors: CHITTY_COLORS,
fonts: {
sans: 'system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',
serif: 'Georgia, Cambria, "Times New Roman", Times, serif',
mono: 'ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", monospace'
},
radius: "0.5rem",
spacing: {
xs: "0.25rem",
sm: "0.5rem",
md: "1rem",
lg: "1.5rem",
xl: "2rem"
}
};
var BRAND_CONFIG = {
name: "ChittyOS",
tagline: "Intelligent Business Operating System",
description: "Enterprise-grade distributed system for legal technology and business automation",
logo: {
text: "ChittyOS",
icon: "\u26A1",
svg: null
},
copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} ChittyOS. All rights reserved.`,
social: {
github: "https://github.com/chittyos",
twitter: null,
linkedin: null,
discord: null
},
support: {
email: "support@chitty.cc",
docs: "https://docs.chitty.cc",
status: "https://status.chitty.cc"
}
};
function getCSSVariables(theme = "light") {
const colors = CHITTY_COLORS[theme];
const vars = [];
for (const [key, value] of Object.entries(colors)) {
const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
vars.push(`--chitty-${cssKey}: ${value};`);
}
vars.push(`--chitty-font-sans: ${CHITTY_THEME.fonts.sans};`);
vars.push(`--chitty-font-serif: ${CHITTY_THEME.fonts.serif};`);
vars.push(`--chitty-font-mono: ${CHITTY_THEME.fonts.mono};`);
for (const [key, value] of Object.entries(CHITTY_THEME.spacing)) {
vars.push(`--chitty-spacing-${key}: ${value};`);
}
vars.push(`--chitty-radius: ${CHITTY_THEME.radius};`);
return vars.join("\n ");
}
function generateStyleTag(theme = "light") {
return `
<style id="chittyos-theme">
:root {
${getCSSVariables(theme)}
}
.chitty-theme {
color: var(--chitty-foreground);
background-color: var(--chitty-background);
font-family: var(--chitty-font-sans);
}
.chitty-primary {
color: var(--chitty-primary);
}
.chitty-secondary {
color: var(--chitty-secondary);
}
.chitty-accent {
color: var(--chitty-accent);
}
.chitty-muted {
color: var(--chitty-muted-foreground);
background-color: var(--chitty-muted);
}
.chitty-border {
border-color: var(--chitty-border);
}
.chitty-btn {
padding: var(--chitty-spacing-sm) var(--chitty-spacing-md);
border-radius: var(--chitty-radius);
background-color: var(--chitty-primary);
color: var(--chitty-background);
border: none;
cursor: pointer;
font-family: var(--chitty-font-sans);
}
.chitty-btn:hover {
opacity: 0.9;
}
.chitty-card {
padding: var(--chitty-spacing-md);
border-radius: var(--chitty-radius);
background-color: var(--chitty-background);
border: 1px solid var(--chitty-border);
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
}
.chitty-input {
padding: var(--chitty-spacing-sm);
border-radius: var(--chitty-radius);
background-color: var(--chitty-background);
color: var(--chitty-foreground);
border: 1px solid var(--chitty-border);
font-family: var(--chitty-font-sans);
}
.chitty-input:focus {
outline: none;
border-color: var(--chitty-accent);
box-shadow: 0 0 0 2px rgb(59 130 246 / 0.1);
}
.chitty-badge {
padding: var(--chitty-spacing-xs) var(--chitty-spacing-sm);
border-radius: calc(var(--chitty-radius) * 0.5);
background-color: var(--chitty-muted);
color: var(--chitty-muted-foreground);
font-size: 0.875rem;
font-weight: 500;
}
.chitty-code {
padding: var(--chitty-spacing-xs);
border-radius: calc(var(--chitty-radius) * 0.5);
background-color: var(--chitty-muted);
color: var(--chitty-foreground);
font-family: var(--chitty-font-mono);
font-size: 0.875rem;
}
</style>`;
}
function generateThemeProvider() {
return `
import React, { createContext, useContext, useState } from 'react'
const ThemeContext = createContext({
theme: 'light',
toggleTheme: () => {},
colors: ${JSON.stringify(CHITTY_COLORS.light, null, 2)}
})
export function ChittyThemeProvider({ children }) {
const [theme, setTheme] = useState('light')
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light')
}
const colors = theme === 'light'
? ${JSON.stringify(CHITTY_COLORS.light, null, 2)}
: ${JSON.stringify(CHITTY_COLORS.dark, null, 2)}
return (
<ThemeContext.Provider value={{ theme, toggleTheme, colors }}>
{children}
</ThemeContext.Provider>
)
}
export const useChittyTheme = () => useContext(ThemeContext)
`;
}
function generateTailwindConfig() {
return {
theme: {
extend: {
colors: {
chitty: {
primary: "var(--chitty-primary)",
secondary: "var(--chitty-secondary)",
accent: "var(--chitty-accent)",
background: "var(--chitty-background)",
foreground: "var(--chitty-foreground)",
muted: "var(--chitty-muted)",
"muted-foreground": "var(--chitty-muted-foreground)",
border: "var(--chitty-border)",
destructive: "var(--chitty-destructive)",
success: "var(--chitty-success)",
warning: "var(--chitty-warning)",
info: "var(--chitty-info)"
}
},
fontFamily: {
"chitty-sans": CHITTY_THEME.fonts.sans.split(","),
"chitty-serif": CHITTY_THEME.fonts.serif.split(","),
"chitty-mono": CHITTY_THEME.fonts.mono.split(",")
},
borderRadius: {
"chitty": CHITTY_THEME.radius
},
spacing: {
"chitty-xs": CHITTY_THEME.spacing.xs,
"chitty-sm": CHITTY_THEME.spacing.sm,
"chitty-md": CHITTY_THEME.spacing.md,
"chitty-lg": CHITTY_THEME.spacing.lg,
"chitty-xl": CHITTY_THEME.spacing.xl
}
}
}
};
}
var ASCII_LOGO = `
_____ _ _ _ _ ____ _____
/ ____| | (_) | | | / __ \\ / ____|
| | | |__ _| |_| |_ _ _| | | | (___
| | | '_ \\| | __| __| | | | | | |\\___ \\
| |____| | | | | |_| |_| |_| | |__| |____) |
\\_____|_| |_|_|\\__|\\__|\\__, |\\____/|_____/
__/ |
|___/
`;
var brand_default = {
CHITTY_COLORS,
CHITTY_THEME,
BRAND_CONFIG,
getCSSVariables,
generateStyleTag,
generateThemeProvider,
generateTailwindConfig,
ASCII_LOGO
};
// src/canon/index.ts
var canon_exports = {};
__export(canon_exports, {
clearCanonCache: () => clearCanonCache,
configure: () => configure5,
createCanonical: () => createCanonical,
default: () => canon_default,
getCanonStats: () => getCanonStats,
getCanonical: () => getCanonical,
getCanonicalHistory: () => getCanonicalHistory,
mergeCanonical: () => mergeCanonical,
queryCanonical: () => queryCanonical,
signCanonical: () => signCanonical,
updateCanonical: () => updateCanonical,
validateCanonical: () => validateCanonical,
verifyCanonicalSignature: () => verifyCanonicalSignature
});
import { nanoid as nanoid3 } from "nanoid";
import * as crypto4 from "crypto";
var DEFAULT_CONFIG5 = {
endpoint: process.env.CHITTY_CANON_ENDPOINT || "https://canon.chitty.cc",
enableChain: true,
enableSignatures: true
};
var config5 = { ...DEFAULT_CONFIG5 };
var canonCache = /* @__PURE__ */ new Map();
var chainIndex = /* @__PURE__ */ new Map();
function configure5(customConfig) {
config5 = { ...config5, ...customConfig };
}
function createCanonical(data, chittyId, metadata) {
const canonId = `CANON_${nanoid3(21)}`;
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
const hash = crypto4.createHash("sha256").update(JSON.stringify({ data, chittyId, timestamp })).digest("hex");
const record = {
id: nanoid3(),
canonId,
version: 1,
data,
hash,
chittyId,
timestamp,
metadata: {
source: metadata?.source || "chittyos-core",
tags: metadata?.tags || [],
ttl: metadata?.ttl,
immutable: metadata?.immutable || false
}
};
canonCache.set(canonId, record);
if (config5.enableChain) {
chainIndex.set(canonId, [record]);
}
return record;
}
function updateCanonical(canonId, data, chittyId) {
const existing = canonCache.get(canonId);
if (!existing) {
return null;
}
if (existing.metadata?.immutable) {
throw new Error("Cannot update immutable canonical record");
}
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
const previousHash = existing.hash;
const hash = crypto4.createHash("sha256").update(JSON.stringify({ data, chittyId, timestamp, previousHash })).digest("hex");
const record = {
...existing,
id: nanoid3(),
version: existing.version + 1,
data,
hash,
previousHash,
chittyId,
timestamp
};
canonCache.set(canonId, record);
if (config5.enableChain) {
const chain = chainIndex.get(canonId) || [];
chain.push(record);
chainIndex.set(canonId, chain);
}
return record;
}
async function getCanonical(canonId) {
if (canonCache.has(canonId)) {
return canonCache.get(canonId);
}
if (config5.storageAdapter) {
const record = await config5.storageAdapter.get(canonId);
if (record) {
canonCache.set(canonId, record);
return record;
}
}
if (config5.endpoint) {
try {
const response = await fetch(`${config5.endpoint}/canon/${canonId}`);
if (response.ok) {
const record = await response.json();
canonCache.set(canonId, record);
return record;
}
} catch (error) {
console.error("[Canon] Failed to fetch from endpoint:", error);
}
}
return null;
}
function getCanonicalHistory(canonId) {
return chainIndex.get(canonId) || [];
}
function validateCanonical(record) {
const errors = [];
const warnings = [];
if (!record.canonId || !record.canonId.startsWith("CANON_")) {
errors.push("Invalid canon ID format");
}
if (!record.hash) {
errors.push("Missing hash");
}
if (!record.chittyId) {
errors.push("Missing ChittyID");
}
const expectedHash = crypto4.createHash("sha256").update(JSON.stringify({
data: record.data,
chittyId: record.chittyId,
timestamp: record.timestamp,
...record.previousHash && { previousHash: record.previousHash }
})).digest("hex");
if (record.hash !== expectedHash) {
errors.push("Hash mismatch - data integrity compromised");
}
if (record.previousHash && record.version > 1) {
const history = getCanonicalHistory(record.canonId);
const previousRecord = history[record.version - 2];
if (previousRecord && previousRecord.hash !== record.previousHash) {
errors.push("Chain integrity violation - previous hash mismatch");
}
}
if (record.metadata?.ttl) {
const age = Date.now() - new Date(record.timestamp).getTime();
const ttlMs = record.metadata.ttl * 1e3;
if (age > ttlMs) {
warnings.push("Record has exceeded TTL");
}
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : void 0,
warnings: warnings.length > 0 ? warnings : void 0
};
}
function signCanonical(record, privateKey) {
if (!config5.enableSignatures) {
return record;
}
const sign = crypto4.createSign("SHA256");
sign.update(record.hash);
const signature = sign.sign(privateKey, "base64");
return {
...record,
signature
};
}
function verifyCanonicalSignature(record, publicKey) {
if (!record.signature) {
return false;
}
try {
const verify = crypto4.createVerify("SHA256");
verify.update(record.hash);
return verify.verify(publicKey, record.signature, "base64");
} catch (error) {
return false;
}
}
function mergeCanonical(records, strategy = "latest", customMerge) {
if (records.length === 0) {
throw new Error("No records to merge");
}
if (records.length === 1) {
return records[0];
}
let winner;
switch (strategy) {
case "latest":
winner = records.reduce(
(latest, record) => new Date(record.timestamp) > new Date(latest.timestamp) ? record : latest
);
break;
case "highest-version":
winner = records.reduce(
(highest, record) => record.version > highest.version ? record : highest
);
break;
case "custom":
if (!customMerge) {
throw new Error("Custom merge function required");
}
const mergedData = customMerge(records);
winner = createCanonical(
mergedData,
records[0].chittyId,
{ source: "merge", tags: ["merged"] }
);
break;
default:
winner = records[0];
}
return {
...winner,
metadata: {
...winner.metadata,
source: "merge",
tags: [...winner.metadata?.tags || [], "merged", `from-${records.length}-records`]
}
};
}
async function queryCanonical(filter) {
let results = [];
for (const record of canonCache.values()) {
let matches = true;
if (filter.chittyId && record.chittyId !== filter.chittyId) {
matches = false;
}
if (filter.tags && filter.tags.length > 0) {
const recordTags = record.metadata?.tags || [];
if (!filter.tags.every((tag) => recordTags.includes(tag))) {
matches = false;
}
}
if (filter.source && record.metadata?.source !== filter.source) {
matches = false;
}
if (filter.afterTimestamp && record.timestamp <= filter.afterTimestamp) {
matches = false;
}
if (filter.beforeTimestamp && record.timestamp >= filter.beforeTimestamp) {
matches = false;
}
if (matches) {
results.push(record);
}
}
if (config5.storageAdapter) {
const storedRecords = await config5.storageAdapter.list(filter);
results = [...results, ...storedRecords];
}
const seen = /* @__PURE__ */ new Set();
results = results.filter((record) => {
if (seen.has(record.canonId)) {
return false;
}
seen.add(record.canonId);
return true;
});
return results;
}
function clearCanonCache() {
canonCache.clear();
chainIndex.clear();
}
function getCanonStats() {
let oldest;
let newest;
for (const record of canonCache.values()) {
if (!oldest || record.timestamp < oldest) {
oldest = record.timestamp;
}
if (!newest || record.timestamp > newest) {
newest = record.timestamp;
}
}
return {
totalRecords: canonCache.size,
totalChains: chainIndex.size,
cacheSize: JSON.stringify([...canonCache.values()]).length,
oldestRecord: oldest,
newestRecord: newest
};
}
var canon_default = {
configure: configure5,
createCanonical,
updateCanonical,
getCanonical,
getCanonicalHistory,
validateCanonical,
signCanonical,
verifyCanonicalSignature,
mergeCanonical,
queryCanonical,
clearCanonCache,
getCanonStats
};
// src/registry/index.ts
var registry_exports = {};
__export(registry_exports, {
connectToService: () => connectToService,
default: () => registry_default,
getAllServices: () => getAllServices,
getRegistry: () => getRegistry,
getService: () => getService,
registerService: () => registerService
});
import { EventEmitter } from "eventemitter3";
import { nanoid as nanoid4 } from "nanoid";
var ServiceRegistry = class extends EventEmitter {
config;
services = /* @__PURE__ */ new Map();
connections = /* @__PURE__ */ new Map();
healthStatus = /* @__PURE__ */ new Map();
healthCheckTimers = /* @__PURE__ */ new Map();
discoveryTimer = null;
constructor(config6 = {}) {
super();
this.config = {
discoveryEndpoint: config6.discoveryEndpoint || process.env.CHITTY_REGISTRY_ENDPOINT || "https://registry.chitty.cc",
healthCheckInterval: config6.healthCheckInterval || 3e4,
connectionTimeout: config6.connectionTimeout || 1e4,
maxRetries: config6.maxRetries || 3,
enableAutoDiscovery: config6.enableAutoDiscovery ?? true
};
if (this.config.enableAutoDiscovery) {
this.startAutoDiscovery();
}
}
/**
* Register a service endpoint
*/
registerService(service) {
const registeredService = {
...service,
id: service.name + "_" + nanoid4(8)
};
try {
const url = new URL(service.url);
registeredService.protocol = url.protocol.replace(":", "");
registeredService.host = url.hostname;
registeredService.port = url.port ? parseInt(url.port) : void 0;
registeredService.path = url.pathname !== "/" ? url.pathname : void 0;
} catch (error) {
console.warn("[Registry] Invalid URL for service:", service.name);
}
this.services.set(registeredService.id, registeredService);
this.emit("service:registered", registeredService);
this.startHealthCheck(registeredService.id);
sendBeacon("registry_service_registered", {
serviceId: registeredService.id,
name: registeredService.name,
type: registeredService.type
});
return registeredService;
}
/**
* Unregister a service
*/
unregisterService(serviceId) {
const service = this.services.get(serviceId);
if (!service) {
return false;
}
this.stopHealthCheck(serviceId);
for (const [connId, conn] of this.connections) {
if (conn.serviceId === serviceId) {
this.disconnectConnection(connId);
}
}
this.services.delete(serviceId);
this.healthStatus.delete(serviceId);
this.emit("service:unregistered", serviceId);
return true;
}
/**
* Get service by ID or name
*/
getService(idOrName) {
if (this.services.has(idOrName)) {
return this.services.get(idOrName);
}
for (const service of this.services.values()) {
if (service.name === idOrName) {
return service;
}
}
return void 0;
}
/**
* Get all services of a specific type
*/
getServicesByType(type2) {
return Array.from(this.services.values()).filter((s) => s.type === type2);
}
/**
* Establish connection to a service
*/
async connectToService(serviceId, chittyId, metadata) {
const service = this.services.get(serviceId);
if (!service) {
throw new Error(`Service ${serviceId} not found`);
}
const connection = {
id: `conn_${nanoid4()}`,
serviceId,
chittyId,
status: "connecting",
metadata
};
this.connections.set(connection.id, connection);
try {
const startTime = Date.now();
await this.testConnection(service);
const latency = Date.now() - startTime;
connection.status = "connected";
connection.establishedAt = (/* @__PURE__ */ new Date()).toISOString();
connection.latency = latency;
this.connections.set(connection.id, connection);
this.emit("connection:established", connection);
sendBeacon("registry_connection_established", {
serviceId,
chittyId,
latency
});
return connection;
} catch (error) {
connection.status = "error";
connection.error = error.message;
this.connections.set(connection.id, connection);
throw error;
}
}
/**
* Disconnect a connection
*/
disconnectConnection(connectionId) {
const connection = this.connections.get(connectionId);
if (!connection) {
return false;
}
connection.status = "disconnected";
this.emit("connection:lost", connection);
this.connections.delete(connectionId);
return true;
}
/**
* Get connection status
*/
getConnection(connectionId) {
return this.connections.get(connectionId);
}
/**
* Get all connections for a ChittyID
*/
getConnectionsByChittyId(chittyId) {
return Array.from(this.connections.values()).filter((c) => c.chittyId === chittyId);
}
/**
* Test connection to a service
*/
async testConnection(service) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), this.config.connectionTimeout);
try {
const response = await fetch(service.url, {
method: "HEAD",
signal: controller.signal
});
if (!response.ok && response.status !== 405) {
throw new Error(`Service returned ${response.status}`);
}
} catch (error) {
if (error.name === "AbortError") {
throw new Error("Connection timeout");
}
throw error;
} finally {
clearTimeout(timeout);
}
}
/**
* Perform health check on a service
*/
async performHealthCheck(serviceId) {
const service = this.services.get(serviceId);
if (!service) {
return;
}
const health = {
serviceId,
status: "unknown",
lastCheckAt: (/* @__PURE__ */ new Date()).toISOString(),
checks: []
};
try {
const startTime = Date.now();
await this.testConnection(service);
const responseTime = Date.now() - startTime;
health.responseTime = responseTime;
health.status = responseTime < 1e3 ? "healthy" : "degraded";
health.checks.push({
name: "connectivity",
status: "pass",
message: `Response time: ${responseTime}ms`
});
try {
const healthUrl = new URL(service.url);
healthUrl.pathname = "/health";
const healthResponse = await fetch(healthUrl.toString(), {
signal: AbortSignal.timeout(5e3)
});
if (healthResponse.ok) {
const healthData = await healthResponse.json();
if (healthData.status) {
health.status = healthData.status;
}
if (healthData.checks) {
health.checks.push(...healthData.checks);
}
}
} catch (error) {
}
this.healthStatus.set(serviceId, health);
if (health.status === "healthy") {
this.emit("service:healthy", serviceId);
} else if (health.status === "unhealthy") {
this.emit("service:unhealthy", serviceId, "Health check failed");
}
} catch (error) {
health.status = "unhealthy";
health.checks.push({
name: "connectivity",
status: "fail",
message: error.message
});
this.healthStatus.set(serviceId, health);
this.emit("service:unhealthy", serviceId, error.message);
}
}
/**
* Start health checks for a service
*/
startHealthCheck(serviceId) {
this.performHealthCheck(serviceId);
const timer = setInterval(() => {
this.performHealthCheck(serviceId);
}, this.config.healthCheckInterval);
this.healthCheckTimers.set(serviceId, timer);
}
/**
* Stop health checks for a service
*/
stopHealthCheck(serviceId) {
const timer = this.healthCheckTimers.get(serviceId);
if (timer) {
clearInterval(timer);
this.healthCheckTimers.delete(serviceId);
}
}
/**
* Auto-discover services from registry endpoint
*/
async discoverServices() {
if (!this.config.discoveryEndpoint) {
return;
}
try {
const response = await fetch(`${this.config.discoveryEndpoint}/discover`);
if (response.ok) {
const services = await response.json();
for (const service of services) {
if (!this.getService(service.id)) {
this.registerService(service);
}
}
this.emit("discovery:update", services);
}
} catch (error) {
console.error("[Registry] Discovery failed:", error);
}
}
/**
* Start auto-discovery
*/
startAutoDiscovery() {
this.discoverServices();
this.discoveryTimer = setInterval(() => {
this.discoverServices();
}, 6e4);
}
/**
* Stop auto-discovery
*/
stopAutoDiscovery() {
if (this.discoveryTimer) {
clearInterval(this.discoveryTimer);
this.discoveryTimer = null;
}
}
/**
* Get service health status
*/
getHealth(serviceId) {
return this.healthStatus.get(serviceId);
}
/**
* Get all registered services
*/
getAllServices() {
return Array.from(this.services.values());
}
/**
* Get all active connections
*/
getAllConnections() {
return Array.from(this.connections.values());
}
/**
* Get registry statistics
*/
getStats() {
const healthyServices = Array.from(this.healthStatus.values()).filter((h) => h.status === "healthy").length;
const unhealthyServices = Array.from(this.healthStatus.values()).filter((h) => h.status === "unhealthy").length;
const activeConnections = Array.from(this.connections.values()).filter((c) => c.status === "connected").length;
return {
totalServices: this.services.size,
healthyServices,
unhealthyServices,
totalConnections: this.connections.size,
activeConnections
};
}
/**
* Cleanup and shutdown
*/
shutdown() {
for (const serviceId of this.healthCheckTimers.keys()) {
this.stopHealthCheck(serviceId);
}
this.stopAutoDiscovery();
this.services.clear();
this.connections.clear();
this.healthStatus.clear();
}
};
var registryInstance = null;
function getRegistry(config6) {
if (!registryInstance) {
registryInstance = new ServiceRegistry(config6);
}
return registryInstance;
}
function registerService(service) {
return getRegistry().registerService(service);
}
function connectToService(serviceId, chittyId, metadata) {
return getRegistry().connectToService(serviceId, chittyId, metadata);
}
function getService(idOrName) {
return getRegistry().getService(idOrName);
}
function getAllServices() {
return getRegistry().getAllServices();
}
var registry_default = {
getRegistry,
registerService,
connectToService,
getService,
getAllServices,
ServiceRegistry
};
// src/chittychat/index.ts
var chittychat_exports = {};
__export(chittychat_exports, {
default: () => chittychat_default,
getChittyChat: () => getChittyChat
});
import { EventEmitter as EventEmitter2 } from "eventemitter3";
var ChittyChatClient = class extends EventEmitter2 {
config;
ws = null;
constructor(config6 = {}) {
super();
this.config = {
endpoint: config6.endpoint || process.env.CHITTY_CHAT_ENDPOINT || "https://chat.chitty.cc",
wsEndpoint: config6.wsEndpoint || process.env.CHITTY_CHAT_WS || "wss://ws.chitty.cc",
apiKey: config6.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(config6) {
if (!clientInstance) {
clientInstance = new ChittyChatClient(config6);
}
return clientInstance;
}
var chittychat_default = {
getChittyChat,
ChittyChatClient
};
// src/index.ts
var index_default = {
beacon: beacon_exports,
id: id_exports,
auth: auth_exports,
verify: verify_exports,
brand: brand_exports,
canon: canon_exports,
registry: registry_exports,
chittychat: chittychat_exports
};
if (typeof process !== "undefined" && process.env.CHITTY_BEACON_DISABLED !== "true") {
init();
}
var VERSION = "1.0.0";
if (typeof process !== "undefined" && process.env.NODE_ENV === "development") {
console.log(ASCII_LOGO);
console.log(`ChittyOS Core v${VERSION} initialized`);
}
export {
ASCII_LOGO,
BRAND_CONFIG,
CHITTY_COLORS,
CHITTY_THEME,
VERSION,
auth_exports as auth,
beacon_exports as beacon,
brand_exports as brand,
canon_exports as canon,
chittychat_exports as chittychat,
configure as configureBeacon,
connectToService,
createCanonical,
createToken,
index_default as default,
detectApp,
generate as generateChittyID,
generateStyleTag,
generateTailwindConfig,
getAllServices,
getCSSVariables,
getCanonical,
getChittyChat,
getRegistry,
getService,
getSessionContext,
hasPermissions,
hasRoles,
hashData,
hashPassword,
id_exports as id,
init as initBeacon,
isValidChittyID,
mergeCanonical,
parseChittyID,
queryCanonical,
refreshToken,
registerService,
registry_exports as registry,
requestChittyID,
revokeSession,
sanitizeInput,
sendBeacon,
setSessionContext,
signData2 as signData,
signData as signWithChittyID,
updateCanonical,
validateCanonical,
validateRemote as validateChittyID,
validateJSON,
validateSchema,
schemas as validationSchemas,
verify_exports as verify,
verifySignature as verifyChittySignature,
verifyIntegrity,
verifyPassword,
verifySignedData,
verifyToken
};
//# sourceMappingURL=index.mjs.map