chatroom-cli 1.16.4 → 1.16.6

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.
Files changed (2) hide show
  1. package/dist/index.js +206 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -15948,6 +15948,194 @@ var init_state_recovery = __esm(() => {
15948
15948
  init_api3();
15949
15949
  });
15950
15950
 
15951
+ // src/infrastructure/local-api/routes/identity.ts
15952
+ async function handleIdentity(_req, ctx) {
15953
+ const identity = {
15954
+ machineId: ctx.machineId,
15955
+ hostname: ctx.config?.hostname ?? "unknown",
15956
+ os: ctx.config?.os ?? "unknown",
15957
+ version: getVersion()
15958
+ };
15959
+ return {
15960
+ status: 200,
15961
+ headers: { "Content-Type": "application/json" },
15962
+ body: JSON.stringify(identity)
15963
+ };
15964
+ }
15965
+ var identityRoute;
15966
+ var init_identity = __esm(() => {
15967
+ init_version();
15968
+ identityRoute = {
15969
+ method: "GET",
15970
+ path: "/api/identity",
15971
+ handler: handleIdentity
15972
+ };
15973
+ });
15974
+
15975
+ // src/infrastructure/local-api/cors.ts
15976
+ function applyCorsHeaders(response) {
15977
+ return {
15978
+ ...response,
15979
+ headers: {
15980
+ ...CORS_HEADERS,
15981
+ ...response.headers ?? {}
15982
+ }
15983
+ };
15984
+ }
15985
+ function buildPreflightResponse() {
15986
+ return {
15987
+ status: 204,
15988
+ headers: CORS_HEADERS,
15989
+ body: ""
15990
+ };
15991
+ }
15992
+ var CORS_HEADERS;
15993
+ var init_cors = __esm(() => {
15994
+ CORS_HEADERS = {
15995
+ "Access-Control-Allow-Origin": "*",
15996
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
15997
+ "Access-Control-Allow-Headers": "Content-Type"
15998
+ };
15999
+ });
16000
+
16001
+ // src/infrastructure/local-api/router.ts
16002
+ class LocalApiRouter {
16003
+ routes = [];
16004
+ registerRoute(route) {
16005
+ this.routes.push(route);
16006
+ }
16007
+ async handleRequest(req, ctx) {
16008
+ if (req.method === "OPTIONS") {
16009
+ return buildPreflightResponse();
16010
+ }
16011
+ const pathname = req.url.split("?")[0] ?? req.url;
16012
+ const route = this.routes.find((r) => r.method === req.method && r.path === pathname);
16013
+ let response;
16014
+ if (route) {
16015
+ try {
16016
+ response = await route.handler(req, ctx);
16017
+ } catch (error) {
16018
+ response = {
16019
+ status: 500,
16020
+ headers: { "Content-Type": "application/json" },
16021
+ body: JSON.stringify({ error: "Internal server error" })
16022
+ };
16023
+ }
16024
+ } else {
16025
+ response = {
16026
+ status: 404,
16027
+ headers: { "Content-Type": "application/json" },
16028
+ body: JSON.stringify({ error: "Not found" })
16029
+ };
16030
+ }
16031
+ return applyCorsHeaders(response);
16032
+ }
16033
+ }
16034
+ var init_router = __esm(() => {
16035
+ init_cors();
16036
+ });
16037
+
16038
+ // src/infrastructure/local-api/server.ts
16039
+ import { createServer } from "node:http";
16040
+ function readBody(req) {
16041
+ return new Promise((resolve2, reject) => {
16042
+ const chunks = [];
16043
+ req.on("data", (chunk) => chunks.push(chunk));
16044
+ req.on("end", () => resolve2(Buffer.concat(chunks).toString("utf-8")));
16045
+ req.on("error", reject);
16046
+ });
16047
+ }
16048
+ async function normalizeRequest(req) {
16049
+ const body = await readBody(req);
16050
+ const headers = {};
16051
+ for (const [key, value] of Object.entries(req.headers)) {
16052
+ if (typeof value === "string") {
16053
+ headers[key] = value;
16054
+ } else if (Array.isArray(value)) {
16055
+ headers[key] = value.join(", ");
16056
+ }
16057
+ }
16058
+ return {
16059
+ method: (req.method ?? "GET").toUpperCase(),
16060
+ url: req.url ?? "/",
16061
+ headers,
16062
+ body: body || undefined
16063
+ };
16064
+ }
16065
+ function writeResponse(res, status, headers, body) {
16066
+ res.writeHead(status, headers);
16067
+ res.end(body);
16068
+ }
16069
+ function createRouter() {
16070
+ const router = new LocalApiRouter;
16071
+ router.registerRoute(identityRoute);
16072
+ return router;
16073
+ }
16074
+ function resolvePort() {
16075
+ const envPort = process.env.CHATROOM_LOCAL_API_PORT;
16076
+ if (envPort) {
16077
+ const parsed = parseInt(envPort, 10);
16078
+ if (!isNaN(parsed) && parsed > 0 && parsed < 65536) {
16079
+ return parsed;
16080
+ }
16081
+ }
16082
+ return LOCAL_API_PORT;
16083
+ }
16084
+ function ts() {
16085
+ return new Date().toISOString().replace("T", " ").slice(0, 19);
16086
+ }
16087
+ async function startLocalApi(ctx, port = resolvePort()) {
16088
+ const router = createRouter();
16089
+ const server = createServer(async (req, res) => {
16090
+ try {
16091
+ const localReq = await normalizeRequest(req);
16092
+ const localRes = await router.handleRequest(localReq, ctx);
16093
+ writeResponse(res, localRes.status, { "Content-Type": "application/json", ...localRes.headers ?? {} }, localRes.body);
16094
+ } catch {
16095
+ writeResponse(res, 500, { "Content-Type": "application/json" }, JSON.stringify({ error: "Internal server error" }));
16096
+ }
16097
+ });
16098
+ await new Promise((resolve2) => {
16099
+ server.listen(port, "127.0.0.1", () => {
16100
+ console.log(`[${ts()}] \uD83C\uDF10 Local API started on http://localhost:${port}`);
16101
+ resolve2();
16102
+ });
16103
+ server.on("error", (err) => {
16104
+ if (err.code === "EADDRINUSE") {
16105
+ console.warn(`[${ts()}] ⚠️ Local API port ${port} already in use — skipping local API`);
16106
+ } else {
16107
+ console.warn(`[${ts()}] ⚠️ Local API failed to start: ${err.message}`);
16108
+ }
16109
+ resolve2();
16110
+ });
16111
+ });
16112
+ const stop = () => new Promise((resolve2, reject) => {
16113
+ if (!server.listening) {
16114
+ resolve2();
16115
+ return;
16116
+ }
16117
+ server.close((err) => {
16118
+ if (err) {
16119
+ reject(err);
16120
+ } else {
16121
+ console.log(`[${ts()}] \uD83C\uDF10 Local API stopped`);
16122
+ resolve2();
16123
+ }
16124
+ });
16125
+ });
16126
+ return { stop };
16127
+ }
16128
+ var LOCAL_API_PORT = 19847;
16129
+ var init_server2 = __esm(() => {
16130
+ init_identity();
16131
+ init_router();
16132
+ });
16133
+
16134
+ // src/infrastructure/local-api/index.ts
16135
+ var init_local_api = __esm(() => {
16136
+ init_server2();
16137
+ });
16138
+
15951
16139
  // src/events/daemon/event-bus.ts
15952
16140
  class DaemonEventBus {
15953
16141
  listeners = new Map;
@@ -15990,15 +16178,15 @@ function onAgentExited(ctx, payload) {
15990
16178
 
15991
16179
  // src/events/daemon/agent/on-agent-started.ts
15992
16180
  function onAgentStarted(ctx, payload) {
15993
- const ts = formatTimestamp();
15994
- console.log(`[${ts}] \uD83D\uDFE2 Agent started: ${payload.role} (PID: ${payload.pid}, harness: ${payload.harness})`);
16181
+ const ts2 = formatTimestamp();
16182
+ console.log(`[${ts2}] \uD83D\uDFE2 Agent started: ${payload.role} (PID: ${payload.pid}, harness: ${payload.harness})`);
15995
16183
  }
15996
16184
  var init_on_agent_started = () => {};
15997
16185
 
15998
16186
  // src/events/daemon/agent/on-agent-stopped.ts
15999
16187
  function onAgentStopped(ctx, payload) {
16000
- const ts = formatTimestamp();
16001
- console.log(`[${ts}] \uD83D\uDD34 Agent stopped: ${payload.role} (PID: ${payload.pid})`);
16188
+ const ts2 = formatTimestamp();
16189
+ console.log(`[${ts2}] \uD83D\uDD34 Agent stopped: ${payload.role} (PID: ${payload.pid})`);
16002
16190
  }
16003
16191
  var init_on_agent_stopped = () => {};
16004
16192
 
@@ -16127,7 +16315,7 @@ class CrashLoopTracker {
16127
16315
  const key = `${chatroomId}:${role.toLowerCase()}`;
16128
16316
  const windowStart = now - CRASH_LOOP_WINDOW_MS;
16129
16317
  const raw = this.history.get(key) ?? [];
16130
- const recent = raw.filter((ts) => ts >= windowStart);
16318
+ const recent = raw.filter((ts2) => ts2 >= windowStart);
16131
16319
  recent.push(now);
16132
16320
  this.history.set(key, recent);
16133
16321
  const restartCount = recent.length;
@@ -16142,7 +16330,7 @@ class CrashLoopTracker {
16142
16330
  const key = `${chatroomId}:${role.toLowerCase()}`;
16143
16331
  const windowStart = now - CRASH_LOOP_WINDOW_MS;
16144
16332
  const raw = this.history.get(key) ?? [];
16145
- return raw.filter((ts) => ts >= windowStart).length;
16333
+ return raw.filter((ts2) => ts2 >= windowStart).length;
16146
16334
  }
16147
16335
  }
16148
16336
  var CRASH_LOOP_MAX_RESTARTS = 3, CRASH_LOOP_WINDOW_MS;
@@ -16785,6 +16973,8 @@ async function initDaemon() {
16785
16973
  registerEventListeners(ctx);
16786
16974
  logStartup(ctx, availableModels);
16787
16975
  await recoverState(ctx);
16976
+ const localApiHandle = await startLocalApi(ctx);
16977
+ ctx.stopLocalApi = localApiHandle.stop;
16788
16978
  return ctx;
16789
16979
  } catch (error) {
16790
16980
  if (isNetworkError(error)) {
@@ -16802,6 +16992,7 @@ var CONNECTION_RETRY_INTERVAL_MS = 1000;
16802
16992
  var init_init2 = __esm(() => {
16803
16993
  init_state_recovery();
16804
16994
  init_api3();
16995
+ init_local_api();
16805
16996
  init_register_listeners();
16806
16997
  init_storage();
16807
16998
  init_client2();
@@ -16872,16 +17063,16 @@ async function refreshModels(ctx) {
16872
17063
  }
16873
17064
  function evictStaleDedupEntries(processedCommandIds, processedPingIds, processedGitRefreshIds) {
16874
17065
  const evictBefore = Date.now() - AGENT_REQUEST_DEADLINE_MS;
16875
- for (const [id, ts] of processedCommandIds) {
16876
- if (ts < evictBefore)
17066
+ for (const [id, ts2] of processedCommandIds) {
17067
+ if (ts2 < evictBefore)
16877
17068
  processedCommandIds.delete(id);
16878
17069
  }
16879
- for (const [id, ts] of processedPingIds) {
16880
- if (ts < evictBefore)
17070
+ for (const [id, ts2] of processedPingIds) {
17071
+ if (ts2 < evictBefore)
16881
17072
  processedPingIds.delete(id);
16882
17073
  }
16883
- for (const [id, ts] of processedGitRefreshIds) {
16884
- if (ts < evictBefore)
17074
+ for (const [id, ts2] of processedGitRefreshIds) {
17075
+ if (ts2 < evictBefore)
16885
17076
  processedGitRefreshIds.delete(id);
16886
17077
  }
16887
17078
  }
@@ -16943,6 +17134,9 @@ async function startCommandLoop(ctx) {
16943
17134
  if (gitSubscriptionHandle)
16944
17135
  gitSubscriptionHandle.stop();
16945
17136
  await onDaemonShutdown(ctx);
17137
+ if (ctx.stopLocalApi) {
17138
+ await ctx.stopLocalApi().catch(() => {});
17139
+ }
16946
17140
  releaseLock();
16947
17141
  process.exit(0);
16948
17142
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatroom-cli",
3
- "version": "1.16.4",
3
+ "version": "1.16.6",
4
4
  "description": "CLI for multi-agent chatroom collaboration",
5
5
  "type": "module",
6
6
  "bin": {