anycodex 0.0.18 → 0.0.19

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.
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
6
6
  <title>AnyCode Playground</title>
7
- <script type="module" crossorigin src="/assets/index-BoNXRcFD.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-Dh2tvIsD.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-DU8KNBjo.css">
9
9
  </head>
10
10
  <body>
package/dist/bin.js CHANGED
@@ -22,8 +22,9 @@ import fs5 from "fs";
22
22
  import readline from "readline";
23
23
  import { fileURLToPath as fileURLToPath2 } from "url";
24
24
 
25
- // ../server/dist/chunk-55FJSWGH.js
25
+ // ../server/dist/chunk-ZLQT6VM3.js
26
26
  import http from "http";
27
+ import https from "https";
27
28
  import { fileURLToPath } from "url";
28
29
  import path3 from "path";
29
30
  import os from "os";
@@ -481,7 +482,13 @@ function loadConfig() {
481
482
  process.exit(1);
482
483
  }
483
484
  const appDist = resolveAppDist();
484
- return { provider, model, apiKey, baseUrl, port, previewPort, appDist, userSettings };
485
+ const tlsCert = process.env.TLS_CERT ?? userSettings.TLS_CERT ?? void 0;
486
+ const tlsKey = process.env.TLS_KEY ?? userSettings.TLS_KEY ?? void 0;
487
+ if (tlsCert && !tlsKey || !tlsCert && tlsKey) {
488
+ console.error("\u274C Both TLS_CERT and TLS_KEY must be set together");
489
+ process.exit(1);
490
+ }
491
+ return { provider, model, apiKey, baseUrl, port, previewPort, appDist, userSettings, tlsCert, tlsKey };
485
492
  }
486
493
  function makePaths() {
487
494
  const dataPath = path3.join(ANYCODE_DIR, "data");
@@ -631,7 +638,7 @@ async function resumeSession(cfg, row) {
631
638
  console.log(`\u267B\uFE0F Session ${sessionId} resumed`);
632
639
  return entry;
633
640
  }
634
- async function createNewWindow(cfg, userId, isDefault = false) {
641
+ async function createNewWindow(cfg, isDefault = false) {
635
642
  const tempId = `temp-${Date.now()}`;
636
643
  const tp = getOrCreateTerminalProvider(tempId);
637
644
  const pp = getOrCreatePreviewProvider(cfg, tempId);
@@ -647,17 +654,16 @@ async function createNewWindow(cfg, userId, isDefault = false) {
647
654
  pp.sessionId = sessionId;
648
655
  const entry = registerSession(cfg, sessionId, agent, "", now);
649
656
  db.insert("user_session", {
650
- user_id: userId,
651
657
  session_id: sessionId,
652
658
  directory: "",
653
659
  time_created: now,
654
660
  is_default: isDefault ? 1 : 0
655
661
  });
656
- console.log(`\u2705 Window ${sessionId} created for user ${userId}${isDefault ? " (default)" : ""}`);
662
+ console.log(`\u2705 Window ${sessionId} created${isDefault ? " (default)" : ""}`);
657
663
  return entry;
658
664
  }
659
- async function getOrCreateSession(cfg, userId) {
660
- const rows = db.findMany("user_session", { filter: { op: "eq", field: "user_id", value: userId } });
665
+ async function getOrCreateSession(cfg) {
666
+ const rows = db.findMany("user_session", {});
661
667
  const defaultRow = rows.find((r) => r.is_default === 1) || rows[0];
662
668
  if (defaultRow) {
663
669
  if (defaultRow.is_default !== 1) {
@@ -665,10 +671,10 @@ async function getOrCreateSession(cfg, userId) {
665
671
  }
666
672
  return resumeSession(cfg, defaultRow);
667
673
  }
668
- return createNewWindow(cfg, userId, true);
674
+ return createNewWindow(cfg, true);
669
675
  }
670
- async function getAllWindows(cfg, userId) {
671
- const rows = db.findMany("user_session", { filter: { op: "eq", field: "user_id", value: userId } });
676
+ async function getAllWindows(cfg) {
677
+ const rows = db.findMany("user_session", {});
672
678
  const entries = [];
673
679
  for (const row of rows) {
674
680
  entries.push(await resumeSession(cfg, row));
@@ -766,78 +772,6 @@ function broadcast(sessionId, data) {
766
772
  if (c2.readyState === WS.OPEN) c2.send(json);
767
773
  }
768
774
  }
769
- var PollingClient = class {
770
- readyState = 1;
771
- // OPEN
772
- id;
773
- sessionId;
774
- lastActivity;
775
- queue = [];
776
- pendingRes = null;
777
- pollTimer = null;
778
- constructor(id, sessionId) {
779
- this.id = id;
780
- this.sessionId = sessionId;
781
- this.lastActivity = Date.now();
782
- }
783
- /** Called by broadcast — queues a JSON string for the next poll */
784
- send(data) {
785
- this.queue.push(data);
786
- this.tryFlush();
787
- }
788
- /** Attach a long-poll response. Flushes immediately if messages are queued. */
789
- hold(res, timeoutMs = 3e4) {
790
- this.lastActivity = Date.now();
791
- this.abortPoll();
792
- this.pendingRes = res;
793
- this.pollTimer = setTimeout(() => {
794
- this.pollTimer = null;
795
- this.flush();
796
- }, timeoutMs);
797
- res.on("close", () => {
798
- if (this.pendingRes === res) {
799
- if (this.pollTimer) {
800
- clearTimeout(this.pollTimer);
801
- this.pollTimer = null;
802
- }
803
- this.pendingRes = null;
804
- }
805
- });
806
- this.tryFlush();
807
- }
808
- close() {
809
- this.readyState = 3;
810
- this.abortPoll();
811
- this.queue = [];
812
- }
813
- tryFlush() {
814
- if (!this.pendingRes || this.queue.length === 0) return;
815
- this.flush();
816
- }
817
- flush() {
818
- if (!this.pendingRes) return;
819
- if (this.pollTimer) {
820
- clearTimeout(this.pollTimer);
821
- this.pollTimer = null;
822
- }
823
- const messages = this.queue.splice(0);
824
- this.pendingRes.writeHead(200, { "Content-Type": "application/json" });
825
- this.pendingRes.end(`[${messages.join(",")}]`);
826
- this.pendingRes = null;
827
- }
828
- abortPoll() {
829
- if (this.pollTimer) {
830
- clearTimeout(this.pollTimer);
831
- this.pollTimer = null;
832
- }
833
- if (this.pendingRes) {
834
- this.pendingRes.writeHead(200, { "Content-Type": "application/json" });
835
- this.pendingRes.end("[]");
836
- this.pendingRes = null;
837
- }
838
- }
839
- };
840
- var pollingClients = /* @__PURE__ */ new Map();
841
775
  async function handleClientMessage(sessionId, client, msg) {
842
776
  if (msg.type === "ls") {
843
777
  const session = getSession(sessionId);
@@ -1180,7 +1114,7 @@ function getOrCreatePreviewProvider(cfg, sessionId) {
1180
1114
  return pp;
1181
1115
  }
1182
1116
  function createPreviewServer(cfg) {
1183
- const previewServer = http.createServer((req, res) => {
1117
+ const previewServer = createServer(cfg, (req, res) => {
1184
1118
  res.setHeader("Access-Control-Allow-Origin", "*");
1185
1119
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
1186
1120
  res.setHeader("Access-Control-Allow-Headers", "*");
@@ -1386,18 +1320,24 @@ function serveStatic(cfg, req, res) {
1386
1320
  function serveAppIndex(cfg, res) {
1387
1321
  const indexPath = path3.join(cfg.appDist, "index.html");
1388
1322
  if (fs4.existsSync(indexPath)) {
1389
- const webSocket = cfg.userSettings.webSocket === true;
1390
- const configScript = `<script>window.__ANYCODE_CONFIG__=${JSON.stringify({ webSocket })}</script>`;
1391
- let html = fs4.readFileSync(indexPath, "utf-8");
1392
- html = html.replace("</head>", `${configScript}</head>`);
1323
+ const html = fs4.readFileSync(indexPath, "utf-8");
1393
1324
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
1394
1325
  res.end(html);
1395
1326
  return true;
1396
1327
  }
1397
1328
  return false;
1398
1329
  }
1330
+ function createServer(cfg, handler) {
1331
+ if (cfg.tlsCert && cfg.tlsKey) {
1332
+ return https.createServer({
1333
+ cert: fs4.readFileSync(cfg.tlsCert),
1334
+ key: fs4.readFileSync(cfg.tlsKey)
1335
+ }, handler);
1336
+ }
1337
+ return http.createServer(handler);
1338
+ }
1399
1339
  function createMainServer(cfg) {
1400
- const server = http.createServer(async (req, res) => {
1340
+ const server = createServer(cfg, async (req, res) => {
1401
1341
  res.setHeader("Access-Control-Allow-Origin", "*");
1402
1342
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
1403
1343
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");
@@ -1406,88 +1346,14 @@ function createMainServer(cfg) {
1406
1346
  res.end();
1407
1347
  return;
1408
1348
  }
1409
- if (req.method === "POST" && req.url === "/api/poll/connect") {
1410
- let body = "";
1411
- for await (const chunk of req) body += chunk;
1412
- const { sessionId } = body ? JSON.parse(body) : {};
1413
- const session = sessionId ? getSession(sessionId) : void 0;
1414
- if (!session) {
1415
- res.writeHead(404, { "Content-Type": "application/json" });
1416
- res.end(JSON.stringify({ error: "Session not found" }));
1417
- return;
1418
- }
1419
- const channelId = Math.random().toString(36).slice(2) + Date.now().toString(36);
1420
- const client = new PollingClient(channelId, sessionId);
1421
- pollingClients.set(channelId, client);
1422
- getSessionClients(sessionId).add(client);
1423
- console.log(`\u{1F50C} Poll client connected to session ${sessionId} (channel=${channelId})`);
1424
- sendStateTo(cfg, sessionId, client);
1425
- res.writeHead(200, { "Content-Type": "application/json" });
1426
- res.end(JSON.stringify({ channelId }));
1427
- return;
1428
- }
1429
- if (req.method === "GET" && req.url?.startsWith("/api/poll?")) {
1430
- const url = new URL(req.url, `http://localhost:${cfg.port}`);
1431
- const channelId = url.searchParams.get("channelId");
1432
- const client = channelId ? pollingClients.get(channelId) : void 0;
1433
- if (!client || client.readyState !== 1) {
1434
- res.writeHead(404, { "Content-Type": "application/json" });
1435
- res.end(JSON.stringify({ error: "Channel not found" }));
1436
- return;
1437
- }
1438
- client.hold(res);
1439
- return;
1440
- }
1441
- if (req.method === "POST" && req.url === "/api/poll/send") {
1442
- let body = "";
1443
- for await (const chunk of req) body += chunk;
1444
- const { channelId, data } = body ? JSON.parse(body) : {};
1445
- const client = channelId ? pollingClients.get(channelId) : void 0;
1446
- if (!client || client.readyState !== 1) {
1447
- res.writeHead(404, { "Content-Type": "application/json" });
1448
- res.end(JSON.stringify({ error: "Channel not found" }));
1449
- return;
1450
- }
1451
- client.lastActivity = Date.now();
1452
- handleClientMessage(client.sessionId, client, data).catch(() => {
1453
- });
1454
- res.writeHead(200, { "Content-Type": "application/json" });
1455
- res.end(JSON.stringify({ ok: true }));
1456
- return;
1457
- }
1458
- if (req.method === "POST" && req.url === "/api/poll/close") {
1459
- let body = "";
1460
- for await (const chunk of req) body += chunk;
1461
- const { channelId } = body ? JSON.parse(body) : {};
1462
- const client = channelId ? pollingClients.get(channelId) : void 0;
1463
- if (client) {
1464
- client.close();
1465
- removeClient(client.sessionId, client);
1466
- pollingClients.delete(channelId);
1467
- console.log(`\u{1F50C} Poll client disconnected (channel=${channelId})`);
1468
- }
1469
- res.writeHead(200, { "Content-Type": "application/json" });
1470
- res.end(JSON.stringify({ ok: true }));
1471
- return;
1472
- }
1473
1349
  if (req.method === "POST" && req.url === "/api/sessions") {
1474
- (async () => {
1475
- let body = "";
1476
- for await (const chunk of req) body += chunk;
1477
- const { userId } = body ? JSON.parse(body) : {};
1478
- if (!userId) {
1479
- res.writeHead(400, { "Content-Type": "application/json" });
1480
- res.end(JSON.stringify({ error: "userId is required" }));
1481
- return;
1482
- }
1483
- getOrCreateSession(cfg, userId).then((entry) => {
1484
- res.writeHead(200, { "Content-Type": "application/json" });
1485
- res.end(JSON.stringify({ id: entry.id, directory: entry.directory }));
1486
- }).catch((err) => {
1487
- res.writeHead(500, { "Content-Type": "application/json" });
1488
- res.end(JSON.stringify({ error: err.message }));
1489
- });
1490
- })();
1350
+ getOrCreateSession(cfg).then((entry) => {
1351
+ res.writeHead(200, { "Content-Type": "application/json" });
1352
+ res.end(JSON.stringify({ id: entry.id, directory: entry.directory }));
1353
+ }).catch((err) => {
1354
+ res.writeHead(500, { "Content-Type": "application/json" });
1355
+ res.end(JSON.stringify({ error: err.message }));
1356
+ });
1491
1357
  return;
1492
1358
  }
1493
1359
  if (req.method === "GET" && req.url === "/api/sessions") {
@@ -1501,15 +1367,8 @@ function createMainServer(cfg) {
1501
1367
  return;
1502
1368
  }
1503
1369
  if (req.method === "GET" && req.url?.startsWith("/api/windows")) {
1504
- const url = new URL(req.url, `http://localhost:${cfg.port}`);
1505
- const userId = url.searchParams.get("userId");
1506
- if (!userId) {
1507
- res.writeHead(400, { "Content-Type": "application/json" });
1508
- res.end(JSON.stringify({ error: "userId is required" }));
1509
- return;
1510
- }
1511
- getAllWindows(cfg, userId).then((entries) => {
1512
- const rows = db.findMany("user_session", { filter: { op: "eq", field: "user_id", value: userId } });
1370
+ getAllWindows(cfg).then((entries) => {
1371
+ const rows = db.findMany("user_session", {});
1513
1372
  const defaultMap = new Map(rows.map((r) => [r.session_id, r.is_default === 1]));
1514
1373
  const list = entries.map((e) => ({
1515
1374
  id: e.id,
@@ -1526,23 +1385,13 @@ function createMainServer(cfg) {
1526
1385
  return;
1527
1386
  }
1528
1387
  if (req.method === "POST" && req.url === "/api/windows") {
1529
- (async () => {
1530
- let body = "";
1531
- for await (const chunk of req) body += chunk;
1532
- const { userId } = body ? JSON.parse(body) : {};
1533
- if (!userId) {
1534
- res.writeHead(400, { "Content-Type": "application/json" });
1535
- res.end(JSON.stringify({ error: "userId is required" }));
1536
- return;
1537
- }
1538
- createNewWindow(cfg, userId, false).then((entry) => {
1539
- res.writeHead(200, { "Content-Type": "application/json" });
1540
- res.end(JSON.stringify({ id: entry.id, directory: entry.directory, isDefault: false }));
1541
- }).catch((err) => {
1542
- res.writeHead(500, { "Content-Type": "application/json" });
1543
- res.end(JSON.stringify({ error: err.message }));
1544
- });
1545
- })();
1388
+ createNewWindow(cfg, false).then((entry) => {
1389
+ res.writeHead(200, { "Content-Type": "application/json" });
1390
+ res.end(JSON.stringify({ id: entry.id, directory: entry.directory, isDefault: false }));
1391
+ }).catch((err) => {
1392
+ res.writeHead(500, { "Content-Type": "application/json" });
1393
+ res.end(JSON.stringify({ error: err.message }));
1394
+ });
1546
1395
  return;
1547
1396
  }
1548
1397
  const windowDeleteMatch = req.url?.match(/^\/api\/windows\/([^/?]+)$/);
@@ -1774,17 +1623,6 @@ async function startServer() {
1774
1623
  `);
1775
1624
  }
1776
1625
  const appDistExists = fs4.existsSync(cfg.appDist);
1777
- setInterval(() => {
1778
- const now = Date.now();
1779
- for (const [id, client] of pollingClients) {
1780
- if (now - client.lastActivity > 6e4) {
1781
- console.log(`\u{1F9F9} Cleaning up stale poll client (channel=${id})`);
1782
- client.close();
1783
- removeClient(client.sessionId, client);
1784
- pollingClients.delete(id);
1785
- }
1786
- }
1787
- }, 3e4);
1788
1626
  const wss = new WebSocketServer({ server });
1789
1627
  wss.on("connection", (ws, req) => {
1790
1628
  const url = new URL(req.url || "/", `http://localhost:${cfg.port}`);
@@ -1814,20 +1652,23 @@ async function startServer() {
1814
1652
  });
1815
1653
  });
1816
1654
  const HOST = process.env.HOST ?? "0.0.0.0";
1655
+ const proto = cfg.tlsCert ? "https" : "http";
1656
+ const wsProto = cfg.tlsCert ? "wss" : "ws";
1817
1657
  previewServer.listen(cfg.previewPort, HOST, () => {
1818
- console.log(`\u{1F441} Preview proxy: http://${HOST}:${cfg.previewPort}`);
1658
+ console.log(`\u{1F441} Preview proxy: ${proto}://${HOST}:${cfg.previewPort}`);
1819
1659
  });
1820
1660
  server.listen(cfg.port, HOST, () => {
1821
- console.log(`\u{1F310} http://${HOST}:${cfg.port}`);
1661
+ console.log(`\u{1F310} ${proto}://${HOST}:${cfg.port}`);
1822
1662
  console.log(`\u{1F916} Provider: ${cfg.provider} / ${cfg.model}`);
1823
- console.log(`\u{1F5A5} Admin: http://${HOST}:${cfg.port}/admin`);
1663
+ console.log(`\u{1F5A5} Admin: ${proto}://${HOST}:${cfg.port}/admin`);
1824
1664
  if (appDistExists) {
1825
- console.log(`\u{1F4F1} App: http://${HOST}:${cfg.port}`);
1665
+ console.log(`\u{1F4F1} App: ${proto}://${HOST}:${cfg.port}`);
1826
1666
  } else {
1827
1667
  console.log(`\u26A0 App dist not found at ${cfg.appDist} \u2014 run 'pnpm --filter @any-code/app build' first`);
1828
1668
  }
1829
1669
  console.log(`\u{1F4CB} Sessions: POST /api/sessions to create`);
1830
- console.log(`\u{1F50C} WebSocket: ws://${HOST}:${cfg.port}?sessionId=xxx`);
1670
+ console.log(`\u{1F50C} WebSocket: ${wsProto}://${HOST}:${cfg.port}?sessionId=xxx`);
1671
+ if (cfg.tlsCert) console.log(`\u{1F512} TLS enabled`);
1831
1672
  });
1832
1673
  }
1833
1674
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,26 +1,27 @@
1
1
  {
2
- "name": "anycodex",
3
- "version": "0.0.18",
4
- "type": "module",
5
- "files": [
6
- "dist"
7
- ],
8
- "bin": {
9
- "anycode": "dist/bin.js",
10
- "anycodex": "dist/bin.js"
11
- },
12
- "dependencies": {
13
- "@lydell/node-pty": "^1.0.1",
14
- "sql.js": "^1.12.0",
15
- "ws": "^8.19.0"
16
- },
17
- "devDependencies": {
18
- "@types/node": "^25.5.0",
19
- "tsup": "^8.4.0",
20
- "typescript": "^5.7.0",
21
- "@any-code/server": "0.0.1"
22
- },
23
- "scripts": {
24
- "build": "tsup"
25
- }
26
- }
2
+ "name": "anycodex",
3
+ "version": "0.0.19",
4
+ "type": "module",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "bin": {
9
+ "anycode": "dist/bin.js",
10
+ "anycodex": "dist/bin.js"
11
+ },
12
+ "scripts": {
13
+ "build": "tsup"
14
+ },
15
+ "dependencies": {
16
+ "@lydell/node-pty": "^1.0.1",
17
+ "sql.js": "^1.12.0",
18
+ "ws": "^8.19.0"
19
+ },
20
+ "devDependencies": {
21
+ "@any-code/app": "workspace:*",
22
+ "@any-code/server": "workspace:*",
23
+ "@types/node": "^25.5.0",
24
+ "tsup": "^8.4.0",
25
+ "typescript": "^5.7.0"
26
+ }
27
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Wyatt
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.