lovelyai 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,117 @@
1
+ LOVELY PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2026 Lovely AI. All rights reserved.
4
+
5
+ IMPORTANT — READ CAREFULLY BEFORE USING THIS SOFTWARE.
6
+
7
+ This software and all associated documentation, source code, binaries, and
8
+ materials (collectively, the "Software") are the proprietary and confidential
9
+ property of Lovely AI ("Licensor"). By accessing, downloading, installing, or
10
+ using the Software in any form, you ("Licensee") agree to be bound by the
11
+ terms of this License. If you do not agree, do not access or use the Software.
12
+
13
+ -------------------------------------------------------------------------------
14
+ 1. GRANT OF LICENSE
15
+
16
+ Subject to the terms of a separately executed commercial agreement between
17
+ Licensor and Licensee, Licensor grants Licensee a limited, non-exclusive,
18
+ non-transferable, non-sublicensable license to install and use the Software
19
+ solely for Licensee's internal business operations.
20
+
21
+ No license is granted by this file alone. Use of the Software requires a valid
22
+ commercial license obtained directly from Lovely AI.
23
+
24
+ -------------------------------------------------------------------------------
25
+ 2. RESTRICTIONS
26
+
27
+ Licensee may NOT, without the prior written consent of Licensor:
28
+
29
+ a. Copy, reproduce, or duplicate the Software or any portion thereof;
30
+ b. Distribute, sell, resell, sublicense, rent, lease, or otherwise transfer
31
+ the Software or any rights therein to any third party;
32
+ c. Modify, adapt, translate, reverse engineer, decompile, disassemble, or
33
+ create derivative works based on the Software;
34
+ d. Use the Software to build a product or service that competes with the
35
+ Software or with any product or service offered by Licensor;
36
+ e. Remove, alter, or obscure any proprietary notices, labels, or marks on
37
+ the Software;
38
+ f. Use the Software for any unlawful purpose or in violation of any
39
+ applicable law or regulation;
40
+ g. Make the Software available to any third party as a hosted or managed
41
+ service (SaaS, PaaS, or otherwise).
42
+
43
+ -------------------------------------------------------------------------------
44
+ 3. OWNERSHIP
45
+
46
+ The Software is licensed, not sold. Licensor retains all right, title, and
47
+ interest in and to the Software, including all intellectual property rights
48
+ therein. Licensee acquires no ownership interest in the Software.
49
+
50
+ -------------------------------------------------------------------------------
51
+ 4. SOURCE CODE VISIBILITY
52
+
53
+ The source code of the Software is made available for reference, audit, and
54
+ transparency purposes only. Visibility of source code does not constitute a
55
+ grant of any rights beyond those expressly stated in this License.
56
+
57
+ -------------------------------------------------------------------------------
58
+ 5. CONFIDENTIALITY
59
+
60
+ Licensee acknowledges that the Software contains trade secrets and proprietary
61
+ information of Licensor. Licensee agrees to maintain the confidentiality of
62
+ the Software using at least the same degree of care it uses for its own
63
+ confidential information, but in no event less than reasonable care.
64
+
65
+ -------------------------------------------------------------------------------
66
+ 6. NO WARRANTY
67
+
68
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
69
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
70
+ FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. LICENSOR DOES
71
+ NOT WARRANT THAT THE SOFTWARE WILL BE ERROR-FREE OR OPERATE WITHOUT
72
+ INTERRUPTION.
73
+
74
+ -------------------------------------------------------------------------------
75
+ 7. LIMITATION OF LIABILITY
76
+
77
+ TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL LICENSOR
78
+ BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, CONSEQUENTIAL, OR
79
+ PUNITIVE DAMAGES, INCLUDING LOSS OF PROFITS, DATA, BUSINESS, OR GOODWILL,
80
+ ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THIS LICENSE, EVEN IF
81
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
82
+
83
+ LICENSOR'S TOTAL CUMULATIVE LIABILITY TO LICENSEE FOR ANY CLAIMS ARISING OUT
84
+ OF OR RELATED TO THE SOFTWARE SHALL NOT EXCEED THE AMOUNTS PAID BY LICENSEE
85
+ TO LICENSOR FOR THE SOFTWARE IN THE TWELVE (12) MONTHS PRECEDING THE CLAIM.
86
+
87
+ -------------------------------------------------------------------------------
88
+ 8. TERMINATION
89
+
90
+ This License is effective until terminated. It will terminate automatically
91
+ if Licensee breaches any term of this License. Upon termination, Licensee
92
+ must immediately cease all use of the Software and destroy all copies in its
93
+ possession or control.
94
+
95
+ -------------------------------------------------------------------------------
96
+ 9. GOVERNING LAW
97
+
98
+ This License shall be governed by and construed in accordance with the laws
99
+ of the State of California, United States, without regard to its conflict of
100
+ law provisions. Any dispute arising under this License shall be subject to the
101
+ exclusive jurisdiction of the courts located in San Francisco County, California.
102
+
103
+ -------------------------------------------------------------------------------
104
+ 10. CONTACT
105
+
106
+ To obtain a commercial license, report a licensing issue, or request
107
+ permissions beyond the scope of this License, contact:
108
+
109
+ Lovely AI
110
+ licensing@lovely.ai
111
+ https://lovely.ai
112
+
113
+ -------------------------------------------------------------------------------
114
+
115
+ Unauthorized use, reproduction, or distribution of this Software, or any
116
+ portion of it, may result in severe civil and criminal penalties, and will be
117
+ prosecuted to the maximum extent possible under applicable law.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import "../src/index.js";
3
+
4
+ export { };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,381 @@
1
+ import { createRequire } from "node:module";
2
+ import { Command } from "commander";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import { z } from "zod";
6
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { homedir } from "node:os";
9
+ import { createServer } from "node:http";
10
+ import { WebSocketServer } from "ws";
11
+ import { confirm, input, select } from "@inquirer/prompts";
12
+ import { execFileSync } from "node:child_process";
13
+
14
+ //#region ../core/dist/index.js
15
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
16
+ const GatewayConfigSchema = z.object({
17
+ port: z.number().int().min(1024).max(65535).default(18900),
18
+ host: z.string().default("127.0.0.1"),
19
+ auth: z.enum([
20
+ "none",
21
+ "token",
22
+ "password"
23
+ ]).default("none"),
24
+ token: z.string().optional()
25
+ });
26
+ const PrivacyConfigSchema = z.object({
27
+ default: z.enum([
28
+ "local-first",
29
+ "cloud-allowed",
30
+ "local-only"
31
+ ]).default("local-first"),
32
+ cloudAllowed: z.array(z.string()).default([]),
33
+ auditLog: z.boolean().default(true),
34
+ piiDetection: z.boolean().default(true),
35
+ perConversation: z.record(z.string(), z.enum([
36
+ "local-only",
37
+ "cloud-allowed",
38
+ "local-first"
39
+ ])).default({})
40
+ });
41
+ const HitlConfigSchema = z.object({
42
+ enabled: z.boolean().default(true),
43
+ disambiguationThreshold: z.number().min(0).max(1).default(.7),
44
+ approvalMemoryCount: z.number().int().min(1).default(2),
45
+ approvalDecayDays: z.number().int().min(1).default(30),
46
+ riskThresholds: z.record(z.string(), z.enum([
47
+ "none",
48
+ "fyi",
49
+ "approval"
50
+ ])).default({
51
+ sendMessage: "fyi",
52
+ sendEmail: "approval",
53
+ deleteFile: "approval",
54
+ executeCode: "approval",
55
+ webSearch: "fyi",
56
+ readFile: "none"
57
+ })
58
+ });
59
+ const LLMPrimarySchema = z.object({
60
+ provider: z.string().default("anthropic"),
61
+ model: z.string().default("claude-sonnet-4-6")
62
+ }).default({});
63
+ const LLMConfigSchema = z.object({
64
+ primary: LLMPrimarySchema,
65
+ fallbacks: z.array(z.object({
66
+ provider: z.string(),
67
+ model: z.string()
68
+ })).default([]),
69
+ providers: z.record(z.string(), z.object({
70
+ baseUrl: z.string().optional(),
71
+ apiKey: z.string().optional(),
72
+ type: z.enum([
73
+ "anthropic",
74
+ "openai",
75
+ "ollama",
76
+ "custom"
77
+ ]).default("custom")
78
+ })).default({})
79
+ });
80
+ const LovelyConfigSchema = z.object({
81
+ gateway: GatewayConfigSchema.default({}),
82
+ privacy: PrivacyConfigSchema.default({}),
83
+ hitl: HitlConfigSchema.default({}),
84
+ llm: LLMConfigSchema.default({})
85
+ });
86
+ function resolveConfigDir(opts = {}) {
87
+ return opts.configDir ?? join(homedir(), ".lovely");
88
+ }
89
+ function loadConfig(opts = {}) {
90
+ const configDir = resolveConfigDir(opts);
91
+ const configFile = opts.configFile ?? join(configDir, "lovely.json");
92
+ let raw = {};
93
+ if (existsSync(configFile)) {
94
+ const content = readFileSync(configFile, "utf8");
95
+ try {
96
+ raw = JSON.parse(content);
97
+ } catch (err) {
98
+ throw new Error(`Failed to parse config file ${configFile}: ${err.message}`);
99
+ }
100
+ }
101
+ return LovelyConfigSchema.parse(raw);
102
+ }
103
+ function createEventBus() {
104
+ const handlers = /* @__PURE__ */ new Map();
105
+ const anyHandlers = /* @__PURE__ */ new Set();
106
+ return {
107
+ on(event, handler) {
108
+ if (!handlers.has(event)) handlers.set(event, /* @__PURE__ */ new Set());
109
+ handlers.get(event).add(handler);
110
+ return () => {
111
+ handlers.get(event)?.delete(handler);
112
+ };
113
+ },
114
+ onAny(handler) {
115
+ anyHandlers.add(handler);
116
+ return () => {
117
+ anyHandlers.delete(handler);
118
+ };
119
+ },
120
+ emit(event, payload) {
121
+ handlers.get(event)?.forEach((h) => h(payload));
122
+ anyHandlers.forEach((h) => h({
123
+ event,
124
+ payload
125
+ }));
126
+ }
127
+ };
128
+ }
129
+ function serializeFrame(frame) {
130
+ return JSON.stringify(frame);
131
+ }
132
+ function parseFrame(raw) {
133
+ try {
134
+ const parsed = JSON.parse(raw);
135
+ if (typeof parsed !== "object" || parsed === null) return null;
136
+ const obj = parsed;
137
+ if (obj["type"] !== "req" && obj["type"] !== "res" && obj["type"] !== "event") return null;
138
+ return parsed;
139
+ } catch {
140
+ return null;
141
+ }
142
+ }
143
+ const express = __require("express");
144
+ async function createGatewayServer(opts) {
145
+ const { port, host = "127.0.0.1" } = opts;
146
+ const bus = opts.bus ?? createEventBus();
147
+ const app = express();
148
+ app.use(express.json());
149
+ app.get("/health", (_req, res) => {
150
+ res.json({
151
+ ok: true,
152
+ version: "0.0.1"
153
+ });
154
+ });
155
+ const httpServer = createServer(app);
156
+ const wss = new WebSocketServer({ server: httpServer });
157
+ let seq = 0;
158
+ wss.on("connection", (ws) => {
159
+ ws.on("message", (data) => {
160
+ const frame = parseFrame(data.toString());
161
+ if (!frame || frame.type !== "req") return;
162
+ ws.send(serializeFrame({
163
+ type: "res",
164
+ id: frame.id,
165
+ ok: true
166
+ }));
167
+ });
168
+ });
169
+ function broadcast(event, payload) {
170
+ const frame = serializeFrame({
171
+ type: "event",
172
+ event,
173
+ payload,
174
+ seq: seq++
175
+ });
176
+ for (const client of wss.clients) if (client.readyState === client.OPEN) client.send(frame);
177
+ }
178
+ await new Promise((resolve, reject) => {
179
+ httpServer.once("error", reject);
180
+ httpServer.listen(port, host, () => {
181
+ httpServer.off("error", reject);
182
+ resolve();
183
+ });
184
+ });
185
+ return {
186
+ port,
187
+ bus,
188
+ broadcast,
189
+ stop: () => new Promise((resolve, reject) => {
190
+ wss.close((wsErr) => {
191
+ if (wsErr) {
192
+ reject(wsErr);
193
+ return;
194
+ }
195
+ httpServer.close((err) => err ? reject(err) : resolve());
196
+ });
197
+ })
198
+ };
199
+ }
200
+
201
+ //#endregion
202
+ //#region src/commands/gateway.ts
203
+ function gatewayCommand() {
204
+ return new Command("gateway").description("Start the Lovely gateway daemon").option("-p, --port <port>", "Port to listen on", "18900").option("--verbose", "Enable verbose logging").action(async (opts) => {
205
+ const config = loadConfig();
206
+ const port = parseInt(opts.port, 10);
207
+ if (Number.isNaN(port) || port < 1 || port > 65535) {
208
+ console.error(chalk.red(`Invalid port: ${String(opts.port)}`));
209
+ process.exit(1);
210
+ }
211
+ const spinner = ora(`Starting Lovely gateway on port ${port}...`).start();
212
+ try {
213
+ const server = await createGatewayServer({
214
+ port,
215
+ host: config.gateway.host
216
+ });
217
+ spinner.succeed(chalk.green(`Lovely gateway running on ${chalk.bold(`http://127.0.0.1:${port}`)}`));
218
+ console.log(chalk.dim(" Press Ctrl+C to stop"));
219
+ const shutdown = async () => {
220
+ console.log("\n" + chalk.yellow("Shutting down..."));
221
+ await server.stop();
222
+ process.exit(0);
223
+ };
224
+ process.on("SIGINT", () => {
225
+ shutdown();
226
+ });
227
+ process.on("SIGTERM", () => {
228
+ shutdown();
229
+ });
230
+ } catch (err) {
231
+ spinner.fail(chalk.red(`Failed to start gateway: ${err}`));
232
+ process.exit(1);
233
+ }
234
+ });
235
+ }
236
+
237
+ //#endregion
238
+ //#region src/commands/onboard.ts
239
+ function escapeXml(str) {
240
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
241
+ }
242
+ function onboardCommand() {
243
+ return new Command("onboard").description("Interactive setup wizard for Lovely").option("--install-daemon", "Install launchd daemon after setup").action(async (opts) => {
244
+ console.log(chalk.bold.magenta("\nWelcome to Lovely setup\n"));
245
+ const configDir = join(homedir(), ".lovely");
246
+ mkdirSync(configDir, { recursive: true });
247
+ const provider = await select({
248
+ message: "Which AI provider do you want to use?",
249
+ choices: [
250
+ {
251
+ name: "Anthropic (Claude) — recommended",
252
+ value: "anthropic"
253
+ },
254
+ {
255
+ name: "Ollama (local, privacy-first)",
256
+ value: "ollama"
257
+ },
258
+ {
259
+ name: "OpenAI",
260
+ value: "openai"
261
+ },
262
+ {
263
+ name: "Skip for now",
264
+ value: "skip"
265
+ }
266
+ ]
267
+ });
268
+ let apiKey = "";
269
+ let model = "";
270
+ if (provider === "anthropic") {
271
+ apiKey = await input({
272
+ message: "Anthropic API key:",
273
+ validate: (v) => v.startsWith("sk-") || "Must start with sk-"
274
+ });
275
+ model = "claude-sonnet-4-6";
276
+ } else if (provider === "openai") {
277
+ apiKey = await input({
278
+ message: "OpenAI API key:",
279
+ validate: (v) => v.startsWith("sk-") || "Must start with sk-"
280
+ });
281
+ model = "gpt-4o";
282
+ } else if (provider === "ollama") model = await input({
283
+ message: "Ollama model name:",
284
+ default: "llama3.2"
285
+ });
286
+ const privacy = await select({
287
+ message: "Default privacy policy:",
288
+ choices: [
289
+ {
290
+ name: "Local-first (cloud only if explicitly allowed)",
291
+ value: "local-first"
292
+ },
293
+ {
294
+ name: "Local-only (never send to cloud)",
295
+ value: "local-only"
296
+ },
297
+ {
298
+ name: "Cloud-allowed (use cloud freely)",
299
+ value: "cloud-allowed"
300
+ }
301
+ ]
302
+ });
303
+ const enableIMessage = await confirm({
304
+ message: "Enable iMessage channel?",
305
+ default: true
306
+ });
307
+ const config = {
308
+ gateway: { port: 18900 },
309
+ privacy: {
310
+ default: privacy,
311
+ cloudAllowed: privacy !== "local-only" && provider !== "skip" ? [provider] : []
312
+ },
313
+ hitl: { enabled: true },
314
+ llm: {
315
+ primary: {
316
+ provider,
317
+ model
318
+ },
319
+ providers: provider !== "ollama" && provider !== "skip" ? { [provider]: {
320
+ apiKey,
321
+ type: provider
322
+ } } : {}
323
+ },
324
+ channels: { imessage: { enabled: enableIMessage } }
325
+ };
326
+ const configFilePath = join(configDir, "lovely.json");
327
+ writeFileSync(configFilePath, JSON.stringify(config, null, 2), { mode: 384 });
328
+ chmodSync(configFilePath, 384);
329
+ console.log(chalk.green(`\n✓ Config written to ${configDir}/lovely.json (permissions: 600)`));
330
+ if (opts.installDaemon === true) installLaunchdDaemon();
331
+ console.log(chalk.bold("\nSetup complete! Run: ") + chalk.cyan("lovely gateway") + "\n");
332
+ });
333
+ }
334
+ function installLaunchdDaemon() {
335
+ if (process.platform !== "darwin") {
336
+ console.error(chalk.red("--install-daemon is only supported on macOS"));
337
+ process.exit(1);
338
+ }
339
+ const binPath = process.argv[1] ?? "lovely";
340
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
341
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
342
+ <plist version="1.0">
343
+ <dict>
344
+ <key>Label</key>
345
+ <string>ai.lovely.gateway</string>
346
+ <key>ProgramArguments</key>
347
+ <array>
348
+ <string>${escapeXml(process.execPath)}</string>
349
+ <string>${escapeXml(binPath)}</string>
350
+ <string>gateway</string>
351
+ </array>
352
+ <key>RunAtLoad</key>
353
+ <true/>
354
+ <key>KeepAlive</key>
355
+ <true/>
356
+ <key>StandardOutPath</key>
357
+ <string>${homedir()}/.lovely/logs/gateway.log</string>
358
+ <key>StandardErrorPath</key>
359
+ <string>${homedir()}/.lovely/logs/gateway.error.log</string>
360
+ </dict>
361
+ </plist>`;
362
+ const launchAgentsDir = join(homedir(), "Library", "LaunchAgents");
363
+ mkdirSync(launchAgentsDir, { recursive: true });
364
+ mkdirSync(join(homedir(), ".lovely", "logs"), { recursive: true });
365
+ const plistPath = join(launchAgentsDir, "ai.lovely.gateway.plist");
366
+ writeFileSync(plistPath, plist);
367
+ execFileSync("launchctl", ["load", plistPath]);
368
+ console.log(chalk.green("Launchd daemon installed — Lovely will start automatically on login"));
369
+ }
370
+
371
+ //#endregion
372
+ //#region src/index.ts
373
+ const program = new Command();
374
+ program.name("lovely").description("Lovely — your personal AGI. Runs on your hardware.").version(process.env["npm_package_version"] ?? "0.0.1");
375
+ program.addCommand(gatewayCommand());
376
+ program.addCommand(onboardCommand());
377
+ program.parse(process.argv);
378
+
379
+ //#endregion
380
+ export { };
381
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../core/dist/index.js","../../src/commands/gateway.ts","../../src/commands/onboard.ts","../../src/index.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { z } from \"zod\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { createServer } from \"node:http\";\nimport { WebSocketServer } from \"ws\";\nimport { createPrivacyGate } from \"@lovely/privacy\";\nimport { createHITLEngine } from \"@lovely/hitl\";\nimport { createAgentRunner } from \"@lovely/agent\";\n\n//#region \\0rolldown/runtime.js\nvar __require = /* @__PURE__ */ createRequire(import.meta.url);\n\n//#endregion\n//#region src/types.ts\nconst defaultRuntime = {\n\tlog: (msg) => console.log(`[lovely] ${msg}`),\n\terror: (msg) => console.error(`[lovely:error] ${msg}`),\n\tdebug: (msg) => {\n\t\tif (process.env.LOVELY_DEBUG) console.debug(`[lovely:debug] ${msg}`);\n\t}\n};\n\n//#endregion\n//#region src/config/types.ts\nconst GatewayConfigSchema = z.object({\n\tport: z.number().int().min(1024).max(65535).default(18900),\n\thost: z.string().default(\"127.0.0.1\"),\n\tauth: z.enum([\n\t\t\"none\",\n\t\t\"token\",\n\t\t\"password\"\n\t]).default(\"none\"),\n\ttoken: z.string().optional()\n});\nconst PrivacyConfigSchema = z.object({\n\tdefault: z.enum([\n\t\t\"local-first\",\n\t\t\"cloud-allowed\",\n\t\t\"local-only\"\n\t]).default(\"local-first\"),\n\tcloudAllowed: z.array(z.string()).default([]),\n\tauditLog: z.boolean().default(true),\n\tpiiDetection: z.boolean().default(true),\n\tperConversation: z.record(z.string(), z.enum([\n\t\t\"local-only\",\n\t\t\"cloud-allowed\",\n\t\t\"local-first\"\n\t])).default({})\n});\nconst HitlConfigSchema = z.object({\n\tenabled: z.boolean().default(true),\n\tdisambiguationThreshold: z.number().min(0).max(1).default(.7),\n\tapprovalMemoryCount: z.number().int().min(1).default(2),\n\tapprovalDecayDays: z.number().int().min(1).default(30),\n\triskThresholds: z.record(z.string(), z.enum([\n\t\t\"none\",\n\t\t\"fyi\",\n\t\t\"approval\"\n\t])).default({\n\t\tsendMessage: \"fyi\",\n\t\tsendEmail: \"approval\",\n\t\tdeleteFile: \"approval\",\n\t\texecuteCode: \"approval\",\n\t\twebSearch: \"fyi\",\n\t\treadFile: \"none\"\n\t})\n});\nconst LLMPrimarySchema = z.object({\n\tprovider: z.string().default(\"anthropic\"),\n\tmodel: z.string().default(\"claude-sonnet-4-6\")\n}).default({});\nconst LLMConfigSchema = z.object({\n\tprimary: LLMPrimarySchema,\n\tfallbacks: z.array(z.object({\n\t\tprovider: z.string(),\n\t\tmodel: z.string()\n\t})).default([]),\n\tproviders: z.record(z.string(), z.object({\n\t\tbaseUrl: z.string().optional(),\n\t\tapiKey: z.string().optional(),\n\t\ttype: z.enum([\n\t\t\t\"anthropic\",\n\t\t\t\"openai\",\n\t\t\t\"ollama\",\n\t\t\t\"custom\"\n\t\t]).default(\"custom\")\n\t})).default({})\n});\nconst LovelyConfigSchema = z.object({\n\tgateway: GatewayConfigSchema.default({}),\n\tprivacy: PrivacyConfigSchema.default({}),\n\thitl: HitlConfigSchema.default({}),\n\tllm: LLMConfigSchema.default({})\n});\n\n//#endregion\n//#region src/config/load.ts\nfunction resolveConfigDir(opts = {}) {\n\treturn opts.configDir ?? join(homedir(), \".lovely\");\n}\nfunction loadConfig(opts = {}) {\n\tconst configDir = resolveConfigDir(opts);\n\tconst configFile = opts.configFile ?? join(configDir, \"lovely.json\");\n\tlet raw = {};\n\tif (existsSync(configFile)) {\n\t\tconst content = readFileSync(configFile, \"utf8\");\n\t\ttry {\n\t\t\traw = JSON.parse(content);\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Failed to parse config file ${configFile}: ${err.message}`);\n\t\t}\n\t}\n\treturn LovelyConfigSchema.parse(raw);\n}\n\n//#endregion\n//#region src/events/bus.ts\nfunction createEventBus() {\n\tconst handlers = /* @__PURE__ */ new Map();\n\tconst anyHandlers = /* @__PURE__ */ new Set();\n\treturn {\n\t\ton(event, handler) {\n\t\t\tif (!handlers.has(event)) handlers.set(event, /* @__PURE__ */ new Set());\n\t\t\thandlers.get(event).add(handler);\n\t\t\treturn () => {\n\t\t\t\thandlers.get(event)?.delete(handler);\n\t\t\t};\n\t\t},\n\t\tonAny(handler) {\n\t\t\tanyHandlers.add(handler);\n\t\t\treturn () => {\n\t\t\t\tanyHandlers.delete(handler);\n\t\t\t};\n\t\t},\n\t\temit(event, payload) {\n\t\t\thandlers.get(event)?.forEach((h) => h(payload));\n\t\t\tanyHandlers.forEach((h) => h({\n\t\t\t\tevent,\n\t\t\t\tpayload\n\t\t\t}));\n\t\t}\n\t};\n}\n\n//#endregion\n//#region src/protocol/frames.ts\nfunction serializeFrame(frame) {\n\treturn JSON.stringify(frame);\n}\nfunction parseFrame(raw) {\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (typeof parsed !== \"object\" || parsed === null) return null;\n\t\tconst obj = parsed;\n\t\tif (obj[\"type\"] !== \"req\" && obj[\"type\"] !== \"res\" && obj[\"type\"] !== \"event\") return null;\n\t\treturn parsed;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n//#endregion\n//#region src/gateway/server.ts\nconst express = __require(\"express\");\nasync function createGatewayServer(opts) {\n\tconst { port, host = \"127.0.0.1\" } = opts;\n\tconst bus = opts.bus ?? createEventBus();\n\tconst app = express();\n\tapp.use(express.json());\n\tapp.get(\"/health\", (_req, res) => {\n\t\tres.json({\n\t\t\tok: true,\n\t\t\tversion: \"0.0.1\"\n\t\t});\n\t});\n\tconst httpServer = createServer(app);\n\tconst wss = new WebSocketServer({ server: httpServer });\n\tlet seq = 0;\n\twss.on(\"connection\", (ws) => {\n\t\tws.on(\"message\", (data) => {\n\t\t\tconst frame = parseFrame(data.toString());\n\t\t\tif (!frame || frame.type !== \"req\") return;\n\t\t\tws.send(serializeFrame({\n\t\t\t\ttype: \"res\",\n\t\t\t\tid: frame.id,\n\t\t\t\tok: true\n\t\t\t}));\n\t\t});\n\t});\n\tfunction broadcast(event, payload) {\n\t\tconst frame = serializeFrame({\n\t\t\ttype: \"event\",\n\t\t\tevent,\n\t\t\tpayload,\n\t\t\tseq: seq++\n\t\t});\n\t\tfor (const client of wss.clients) if (client.readyState === client.OPEN) client.send(frame);\n\t}\n\tawait new Promise((resolve, reject) => {\n\t\thttpServer.once(\"error\", reject);\n\t\thttpServer.listen(port, host, () => {\n\t\t\thttpServer.off(\"error\", reject);\n\t\t\tresolve();\n\t\t});\n\t});\n\treturn {\n\t\tport,\n\t\tbus,\n\t\tbroadcast,\n\t\tstop: () => new Promise((resolve, reject) => {\n\t\t\twss.close((wsErr) => {\n\t\t\t\tif (wsErr) {\n\t\t\t\t\treject(wsErr);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\thttpServer.close((err) => err ? reject(err) : resolve());\n\t\t\t});\n\t\t})\n\t};\n}\n\n//#endregion\n//#region src/dispatch.ts\nfunction createDispatcher(opts) {\n\tconst gate = createPrivacyGate(opts.privacy);\n\tcreateHITLEngine(opts.hitl);\n\tconst runner = createAgentRunner({\n\t\tllm: opts.llm,\n\t\tsessionStoreDir: opts.sessionStoreDir,\n\t\tsystemPrompt: opts.systemPrompt ?? \"You are Lovely, a helpful personal AI assistant.\"\n\t});\n\treturn { async dispatch(ctx) {\n\t\tconst providerName = opts.llm.provider ?? opts.llm.id.split(\":\")[0] ?? \"local\";\n\t\tconst decision = gate.enforce(ctx, {\n\t\t\tprovider: providerName,\n\t\t\tmodel: opts.llm.id\n\t\t});\n\t\tif (!decision.allow) {\n\t\t\tawait opts.onReply({\n\t\t\t\tto: ctx.from,\n\t\t\t\tchannel: ctx.channel,\n\t\t\t\ttext: `Message blocked by privacy policy: ${decision.reason ?? \"unknown reason\"}`\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst sessionKey = `${ctx.channel}:${ctx.from}`;\n\t\tlet fullResponse = \"\";\n\t\ttry {\n\t\t\tawait runner.run({\n\t\t\t\tsessionKey,\n\t\t\t\tuserMessage: ctx.text,\n\t\t\t\tonDelta: (delta) => {\n\t\t\t\t\tfullResponse += delta;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tawait opts.onReply({\n\t\t\t\tto: ctx.from,\n\t\t\t\tchannel: ctx.channel,\n\t\t\t\ttext: \"Sorry, something went wrong. Please try again.\"\n\t\t\t});\n\t\t\tthrow err;\n\t\t}\n\t\tawait opts.onReply({\n\t\t\tto: ctx.from,\n\t\t\tchannel: ctx.channel,\n\t\t\ttext: fullResponse\n\t\t});\n\t} };\n}\n\n//#endregion\n//#region src/plugins/loader.ts\nfunction createPluginRegistry() {\n\tconst plugins = [];\n\treturn {\n\t\tregister: (plugin) => plugins.push(plugin),\n\t\tgetAll: () => [...plugins],\n\t\tgetChannels: () => plugins.flatMap((p) => p.channels ?? [])\n\t};\n}\n\n//#endregion\nexport { GatewayConfigSchema, HitlConfigSchema, LLMConfigSchema, LovelyConfigSchema, PrivacyConfigSchema, createDispatcher, createEventBus, createGatewayServer, createPluginRegistry, defaultRuntime, loadConfig, parseFrame, resolveConfigDir, serializeFrame };\n//# sourceMappingURL=index.js.map","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { createGatewayServer, loadConfig } from '@lovely/core';\n\nexport function gatewayCommand(): Command {\n return new Command('gateway')\n .description('Start the Lovely gateway daemon')\n .option('-p, --port <port>', 'Port to listen on', '18900')\n .option('--verbose', 'Enable verbose logging')\n .action(async (opts: { port: string; verbose?: boolean }) => {\n const config = loadConfig();\n const port = parseInt(opts.port, 10);\n\n if (Number.isNaN(port) || port < 1 || port > 65535) {\n console.error(chalk.red(`Invalid port: ${String(opts.port)}`));\n process.exit(1);\n }\n\n const spinner = ora(`Starting Lovely gateway on port ${port}...`).start();\n\n try {\n const server = await createGatewayServer({ port, host: config.gateway.host });\n spinner.succeed(\n chalk.green(`Lovely gateway running on ${chalk.bold(`http://127.0.0.1:${port}`)}`),\n );\n console.log(chalk.dim(' Press Ctrl+C to stop'));\n\n const shutdown = async (): Promise<void> => {\n console.log('\\n' + chalk.yellow('Shutting down...'));\n await server.stop();\n process.exit(0);\n };\n\n process.on('SIGINT', () => { void shutdown(); });\n process.on('SIGTERM', () => { void shutdown(); });\n } catch (err) {\n spinner.fail(chalk.red(`Failed to start gateway: ${err}`));\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { confirm, input, select } from '@inquirer/prompts';\nimport { writeFileSync, mkdirSync, chmodSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { execFileSync } from 'node:child_process';\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\nexport function onboardCommand(): Command {\n return new Command('onboard')\n .description('Interactive setup wizard for Lovely')\n .option('--install-daemon', 'Install launchd daemon after setup')\n .action(async (opts: { installDaemon?: boolean }) => {\n console.log(chalk.bold.magenta('\\nWelcome to Lovely setup\\n'));\n\n const configDir = join(homedir(), '.lovely');\n mkdirSync(configDir, { recursive: true });\n\n // Step 1: LLM provider\n const provider = await select({\n message: 'Which AI provider do you want to use?',\n choices: [\n { name: 'Anthropic (Claude) — recommended', value: 'anthropic' },\n { name: 'Ollama (local, privacy-first)', value: 'ollama' },\n { name: 'OpenAI', value: 'openai' },\n { name: 'Skip for now', value: 'skip' },\n ],\n });\n\n let apiKey = '';\n let model = '';\n\n if (provider === 'anthropic') {\n apiKey = await input({\n message: 'Anthropic API key:',\n validate: (v) => v.startsWith('sk-') || 'Must start with sk-',\n });\n model = 'claude-sonnet-4-6';\n } else if (provider === 'openai') {\n apiKey = await input({\n message: 'OpenAI API key:',\n validate: (v) => v.startsWith('sk-') || 'Must start with sk-',\n });\n model = 'gpt-4o';\n } else if (provider === 'ollama') {\n model = await input({ message: 'Ollama model name:', default: 'llama3.2' });\n }\n\n // Step 2: Privacy policy\n const privacy = await select({\n message: 'Default privacy policy:',\n choices: [\n { name: 'Local-first (cloud only if explicitly allowed)', value: 'local-first' },\n { name: 'Local-only (never send to cloud)', value: 'local-only' },\n { name: 'Cloud-allowed (use cloud freely)', value: 'cloud-allowed' },\n ],\n });\n\n // Step 3: iMessage\n const enableIMessage = await confirm({ message: 'Enable iMessage channel?', default: true });\n\n // Write config\n const config = {\n gateway: { port: 18900 },\n privacy: {\n default: privacy,\n cloudAllowed: privacy !== 'local-only' && provider !== 'skip' ? [provider] : [],\n },\n hitl: { enabled: true },\n llm: {\n primary: { provider, model },\n providers:\n provider !== 'ollama' && provider !== 'skip'\n ? { [provider]: { apiKey, type: provider } }\n : {},\n },\n channels: {\n imessage: { enabled: enableIMessage },\n },\n };\n\n const configFilePath = join(configDir, 'lovely.json');\n writeFileSync(configFilePath, JSON.stringify(config, null, 2), { mode: 0o600 });\n chmodSync(configFilePath, 0o600);\n console.log(chalk.green(`\\n✓ Config written to ${configDir}/lovely.json (permissions: 600)`));\n\n if (opts.installDaemon === true) {\n installLaunchdDaemon();\n }\n\n console.log(chalk.bold('\\nSetup complete! Run: ') + chalk.cyan('lovely gateway') + '\\n');\n });\n}\n\nfunction installLaunchdDaemon(): void {\n if (process.platform !== 'darwin') {\n console.error(chalk.red('--install-daemon is only supported on macOS'));\n process.exit(1);\n }\n\n const binPath = process.argv[1] ?? 'lovely';\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>ai.lovely.gateway</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escapeXml(process.execPath)}</string>\n <string>${escapeXml(binPath)}</string>\n <string>gateway</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${homedir()}/.lovely/logs/gateway.log</string>\n <key>StandardErrorPath</key>\n <string>${homedir()}/.lovely/logs/gateway.error.log</string>\n</dict>\n</plist>`;\n\n const launchAgentsDir = join(homedir(), 'Library', 'LaunchAgents');\n mkdirSync(launchAgentsDir, { recursive: true });\n mkdirSync(join(homedir(), '.lovely', 'logs'), { recursive: true });\n\n const plistPath = join(launchAgentsDir, 'ai.lovely.gateway.plist');\n writeFileSync(plistPath, plist);\n\n execFileSync('launchctl', ['load', plistPath]);\n console.log(chalk.green('Launchd daemon installed — Lovely will start automatically on login'));\n}\n","import { Command } from 'commander';\nimport { gatewayCommand } from './commands/gateway.js';\nimport { onboardCommand } from './commands/onboard.js';\n\nconst program = new Command();\n\nprogram\n .name('lovely')\n .description('Lovely — your personal AGI. Runs on your hardware.')\n .version(process.env['npm_package_version'] ?? '0.0.1');\n\nprogram.addCommand(gatewayCommand());\nprogram.addCommand(onboardCommand());\n\nprogram.parse(process.argv);\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "lovelyai",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "bin": {
6
+ "lovely": "./dist/bin/lovely.js",
7
+ "lovelyai": "./dist/bin/lovely.js"
8
+ },
9
+ "main": "./dist/src/index.js",
10
+ "exports": {
11
+ ".": "./dist/src/index.js"
12
+ },
13
+ "files": [
14
+ "dist/",
15
+ "LICENSE"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public",
19
+ "registry": "https://registry.npmjs.org"
20
+ },
21
+ "dependencies": {
22
+ "@anthropic-ai/sdk": "^0.78.0",
23
+ "@grammyjs/runner": "^2.0.3",
24
+ "@inquirer/prompts": "^7.10.1",
25
+ "@sinclair/typebox": "^0.33.0",
26
+ "@whiskeysockets/baileys": "^6.17.16",
27
+ "better-sqlite3": "^12.0.0",
28
+ "chalk": "^5.6.2",
29
+ "commander": "^12.1.0",
30
+ "express": "^5.0.0",
31
+ "grammy": "^1.40.0",
32
+ "openai": "^6.22.0",
33
+ "ora": "^8.2.0",
34
+ "sqlite-vec": "^0.1.6",
35
+ "ws": "^8.18.0",
36
+ "zod": "^3.22.0"
37
+ },
38
+ "license": "SEE LICENSE IN LICENSE",
39
+ "scripts": {
40
+ "build": "tsdown --config tsdown.config.ts",
41
+ "test": "vitest run",
42
+ "typecheck": "tsc --noEmit"
43
+ }
44
+ }