@openspecui/server 1.1.2 → 1.4.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.
Files changed (2) hide show
  1. package/dist/index.mjs +56 -17
  2. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
+ import { createServer as createServer$1 } from "node:net";
1
2
  import { serve } from "@hono/node-server";
2
- import { CliExecutor, ConfigManager, OpenSpecAdapter, OpenSpecWatcher, OpsxKernel, PtyClientMessageSchema, ReactiveContext, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, initWatcherPool, isWatcherPoolInitialized, sniffGlobalCli } from "@openspecui/core";
3
+ import { CliExecutor, ConfigManager, OpenSpecAdapter, OpenSpecWatcher, OpsxKernel, PtyClientMessageSchema, ReactiveContext, TerminalConfigSchema, TerminalRendererEngineSchema, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getWatcherRuntimeStatus, initWatcherPool, isWatcherPoolInitialized, sniffGlobalCli } from "@openspecui/core";
3
4
  import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
4
5
  import { applyWSSHandler } from "@trpc/server/adapters/ws";
5
6
  import { Hono } from "hono";
6
7
  import { cors } from "hono/cors";
7
8
  import { WebSocketServer } from "ws";
8
- import { createServer as createServer$1 } from "node:net";
9
9
  import * as pty from "@lydell/node-pty";
10
10
  import { EventEmitter } from "events";
11
11
  import { SearchQuerySchema } from "@openspecui/search";
@@ -80,6 +80,8 @@ var PtySession = class extends EventEmitter {
80
80
  command;
81
81
  args;
82
82
  platform;
83
+ closeTip;
84
+ closeCallbackUrl;
83
85
  createdAt;
84
86
  process;
85
87
  titleInterval = null;
@@ -103,6 +105,8 @@ var PtySession = class extends EventEmitter {
103
105
  this.command = resolvedCommand.command;
104
106
  this.args = resolvedCommand.args;
105
107
  this.platform = opts.platform;
108
+ this.closeTip = opts.closeTip;
109
+ this.closeCallbackUrl = opts.closeCallbackUrl;
106
110
  this.maxBufferLines = opts.scrollback ?? DEFAULT_SCROLLBACK;
107
111
  this.maxBufferBytes = opts.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES;
108
112
  this.process = pty.spawn(this.command, this.args, {
@@ -183,6 +187,8 @@ var PtySession = class extends EventEmitter {
183
187
  platform: this.platform,
184
188
  isExited: this.isExited,
185
189
  exitCode: this.exitCode,
190
+ closeTip: this.closeTip,
191
+ closeCallbackUrl: this.closeCallbackUrl,
186
192
  createdAt: this.createdAt
187
193
  };
188
194
  }
@@ -202,6 +208,8 @@ var PtyManager = class {
202
208
  rows: opts.rows,
203
209
  command: opts.command,
204
210
  args: opts.args,
211
+ closeTip: opts.closeTip,
212
+ closeCallbackUrl: opts.closeCallbackUrl,
205
213
  cwd: this.defaultCwd,
206
214
  scrollback: opts.scrollback,
207
215
  maxBufferBytes: opts.maxBufferBytes,
@@ -306,11 +314,14 @@ function createPtyWebSocketHandler(ptyManager) {
306
314
  switch (msg.type) {
307
315
  case "create":
308
316
  try {
317
+ const createMessage = msg;
309
318
  const session = ptyManager.create({
310
319
  cols: msg.cols,
311
320
  rows: msg.rows,
312
321
  command: msg.command,
313
- args: msg.args
322
+ args: msg.args,
323
+ closeTip: createMessage.closeTip,
324
+ closeCallbackUrl: createMessage.closeCallbackUrl
314
325
  });
315
326
  send({
316
327
  type: "created",
@@ -366,7 +377,9 @@ function createPtyWebSocketHandler(ptyManager) {
366
377
  args: s.args,
367
378
  platform: s.platform,
368
379
  isExited: s.isExited,
369
- exitCode: s.exitCode
380
+ exitCode: s.exitCode,
381
+ closeTip: s.closeTip,
382
+ closeCallbackUrl: s.closeCallbackUrl
370
383
  }))
371
384
  });
372
385
  break;
@@ -655,6 +668,16 @@ async function fetchOpsxTemplateContents(ctx, schema) {
655
668
  await ctx.kernel.ensureTemplateContents(schema);
656
669
  return ctx.kernel.getTemplateContents(schema);
657
670
  }
671
+ function buildSystemStatus(ctx) {
672
+ const runtime = getWatcherRuntimeStatus();
673
+ return {
674
+ projectDir: ctx.projectDir,
675
+ watcherEnabled: runtime?.initialized ?? false,
676
+ watcherGeneration: runtime?.generation ?? 0,
677
+ watcherReinitializeCount: runtime?.reinitializeCount ?? 0,
678
+ watcherLastReinitializeReason: runtime?.lastReinitializeReason ?? null
679
+ };
680
+ }
658
681
  /**
659
682
  * Spec router - spec CRUD operations
660
683
  */
@@ -862,17 +885,7 @@ const configRouter = router({
862
885
  "dark",
863
886
  "system"
864
887
  ]).optional(),
865
- terminal: z.object({
866
- fontSize: z.number().min(8).max(32).optional(),
867
- fontFamily: z.string().optional(),
868
- cursorBlink: z.boolean().optional(),
869
- cursorStyle: z.enum([
870
- "block",
871
- "underline",
872
- "bar"
873
- ]).optional(),
874
- scrollback: z.number().min(0).max(1e5).optional()
875
- }).optional()
888
+ terminal: TerminalConfigSchema.omit({ rendererEngine: true }).partial().extend({ rendererEngine: TerminalRendererEngineSchema.optional() }).optional()
876
889
  })).mutation(async ({ ctx, input }) => {
877
890
  const hasCliCommand = input.cli !== void 0 && Object.prototype.hasOwnProperty.call(input.cli, "command");
878
891
  const hasCliArgs = input.cli !== void 0 && Object.prototype.hasOwnProperty.call(input.cli, "args");
@@ -1317,6 +1330,26 @@ const searchRouter = router({
1317
1330
  })
1318
1331
  });
1319
1332
  /**
1333
+ * System router - runtime status and heartbeat-friendly subscription
1334
+ */
1335
+ const systemRouter = router({
1336
+ status: publicProcedure.query(({ ctx }) => {
1337
+ return buildSystemStatus(ctx);
1338
+ }),
1339
+ subscribe: publicProcedure.subscription(({ ctx }) => {
1340
+ return observable((emit) => {
1341
+ emit.next(buildSystemStatus(ctx));
1342
+ const timer = setInterval(() => {
1343
+ emit.next(buildSystemStatus(ctx));
1344
+ }, 3e3);
1345
+ timer.unref();
1346
+ return () => {
1347
+ clearInterval(timer);
1348
+ };
1349
+ });
1350
+ })
1351
+ });
1352
+ /**
1320
1353
  * Main app router
1321
1354
  */
1322
1355
  const appRouter = router({
@@ -1329,7 +1362,8 @@ const appRouter = router({
1329
1362
  cli: cliRouter,
1330
1363
  opsx: opsxRouter,
1331
1364
  kv: kvRouter,
1332
- search: searchRouter
1365
+ search: searchRouter,
1366
+ system: systemRouter
1333
1367
  });
1334
1368
 
1335
1369
  //#endregion
@@ -1548,7 +1582,12 @@ async function createWebSocketServer(server, httpServer, config) {
1548
1582
  const handler = applyWSSHandler({
1549
1583
  wss,
1550
1584
  router: appRouter,
1551
- createContext: server.createContext
1585
+ createContext: server.createContext,
1586
+ keepAlive: {
1587
+ enabled: true,
1588
+ pingMs: 3e4,
1589
+ pongWaitMs: 5e3
1590
+ }
1552
1591
  });
1553
1592
  const ptyManager = new PtyManager(config.projectDir);
1554
1593
  const ptyWss = new WebSocketServer({ noServer: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openspecui/server",
3
- "version": "1.1.2",
3
+ "version": "1.4.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.mjs",
6
6
  "exports": {
@@ -20,7 +20,7 @@
20
20
  "yaml": "^2.8.0",
21
21
  "yargs": "^18.0.0",
22
22
  "zod": "^3.24.1",
23
- "@openspecui/core": "1.1.2",
23
+ "@openspecui/core": "1.2.0",
24
24
  "@openspecui/search": "1.1.0"
25
25
  },
26
26
  "devDependencies": {
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsdown src/index.ts --format esm --no-dts",
37
- "typecheck": "tsc --noEmit",
37
+ "typecheck": "tsc -p tsconfig.check.json --noEmit",
38
38
  "dev": "tsx watch --include '../core/dist/**' --include '../search/dist/**' src/standalone.ts",
39
39
  "test": "vitest run",
40
40
  "test:watch": "vitest"