@openspecui/server 2.0.0 → 2.0.2

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 +36 -28
  2. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createServer as createServer$1 } from "node:net";
2
2
  import { serve } from "@hono/node-server";
3
- import { CliExecutor, CodeEditorThemeSchema, ConfigManager, DASHBOARD_METRIC_KEYS, DashboardConfigSchema, OpenSpecAdapter, OpenSpecWatcher, OpsxKernel, PtyClientMessageSchema, ReactiveContext, TerminalConfigSchema, TerminalRendererEngineSchema, contextStorage, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getWatcherRuntimeStatus, initWatcherPool, isWatcherPoolInitialized, reactiveExists, reactiveReadDir, reactiveReadFile, reactiveStat, sniffGlobalCli } from "@openspecui/core";
3
+ import { CliExecutor, CodeEditorThemeSchema, ConfigManager, DASHBOARD_METRIC_KEYS, DashboardConfigSchema, OpenSpecAdapter, OpenSpecWatcher, OpsxKernel, PtyClientMessageSchema, ReactiveContext, TerminalConfigSchema, TerminalRendererEngineSchema, contextStorage, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getWatcherRuntimeStatus, initWatcherPool, isWatcherPoolInitialized, reactiveReadDir, reactiveReadFile, reactiveStat, sniffGlobalCli } from "@openspecui/core";
4
4
  import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
5
5
  import { applyWSSHandler } from "@trpc/server/adapters/ws";
6
6
  import { Hono } from "hono";
@@ -13,7 +13,7 @@ import { initTRPC } from "@trpc/server";
13
13
  import { observable } from "@trpc/server/observable";
14
14
  import { execFile } from "node:child_process";
15
15
  import { EventEmitter as EventEmitter$1 } from "node:events";
16
- import { mkdir, rm, writeFile } from "node:fs/promises";
16
+ import { mkdir, rm, stat, writeFile } from "node:fs/promises";
17
17
  import { dirname, join, relative, resolve, sep } from "node:path";
18
18
  import { promisify } from "node:util";
19
19
  import { z } from "zod";
@@ -999,43 +999,51 @@ function endDashboardGitTask(error) {
999
999
  if (error) dashboardGitTaskStatus.lastError = error instanceof Error ? error.message : String(error);
1000
1000
  emitDashboardGitTaskStatus();
1001
1001
  }
1002
- function parseGitDirFromDotGitFile(content) {
1003
- const line = content.split(/\r?\n/).map((item) => item.trim()).find((item) => item.startsWith("gitdir:"));
1004
- if (!line) return null;
1005
- const rawPath = line.slice(7).trim();
1006
- return rawPath.length > 0 ? rawPath : null;
1002
+ const DASHBOARD_GIT_REFRESH_STAMP_NAME = "openspecui-dashboard-git-refresh.stamp";
1003
+ async function resolveGitMetadataDir(projectDir) {
1004
+ try {
1005
+ const { stdout } = await execFileAsync("git", ["rev-parse", "--git-dir"], {
1006
+ cwd: projectDir,
1007
+ maxBuffer: 1024 * 1024,
1008
+ encoding: "utf8"
1009
+ });
1010
+ const gitDirRaw = stdout.trim();
1011
+ if (!gitDirRaw) return null;
1012
+ const gitDirPath = resolve(projectDir, gitDirRaw);
1013
+ if (!(await stat(gitDirPath)).isDirectory()) return null;
1014
+ return gitDirPath;
1015
+ } catch {
1016
+ return null;
1017
+ }
1007
1018
  }
1008
- function getDashboardGitRefreshStampPath(projectDir) {
1009
- return join(projectDir, "openspec", ".openspecui-dashboard-git-refresh.stamp");
1019
+ async function resolveGitMetadataDirReactive(projectDir) {
1020
+ const gitMetadataDir = await resolveGitMetadataDir(projectDir);
1021
+ if (!gitMetadataDir) return null;
1022
+ await reactiveReadDir(gitMetadataDir, { includeHidden: true });
1023
+ return gitMetadataDir;
1024
+ }
1025
+ function getDashboardGitRefreshStampPath(gitMetadataDir) {
1026
+ return join(gitMetadataDir, DASHBOARD_GIT_REFRESH_STAMP_NAME);
1010
1027
  }
1011
1028
  async function touchDashboardGitRefreshStamp(projectDir, reason) {
1012
- const stampPath = getDashboardGitRefreshStampPath(projectDir);
1029
+ const gitMetadataDir = await resolveGitMetadataDir(projectDir);
1030
+ if (!gitMetadataDir) return { skipped: true };
1031
+ const stampPath = getDashboardGitRefreshStampPath(gitMetadataDir);
1013
1032
  await mkdir(dirname(stampPath), { recursive: true });
1014
1033
  await writeFile(stampPath, `${Date.now()} ${reason}\n`, "utf8");
1034
+ return { skipped: false };
1015
1035
  }
1016
1036
  async function registerDashboardGitReactiveDeps(projectDir) {
1017
1037
  await reactiveReadDir(projectDir, {
1018
1038
  includeHidden: true,
1019
1039
  exclude: ["node_modules"]
1020
1040
  });
1021
- await reactiveReadFile(getDashboardGitRefreshStampPath(projectDir));
1022
- const dotGitPath = join(projectDir, ".git");
1023
- if (!await reactiveExists(dotGitPath)) return;
1024
- const dotGitFileContent = await reactiveReadFile(dotGitPath);
1025
- if (dotGitFileContent !== null) {
1026
- const gitDirRaw = parseGitDirFromDotGitFile(dotGitFileContent);
1027
- if (!gitDirRaw) return;
1028
- const gitDirPath = resolve(projectDir, gitDirRaw);
1029
- await reactiveReadDir(gitDirPath, { includeHidden: true });
1030
- await reactiveReadFile(join(gitDirPath, "HEAD"));
1031
- await reactiveReadFile(join(gitDirPath, "index"));
1032
- await reactiveReadFile(join(gitDirPath, "packed-refs"));
1033
- return;
1034
- }
1035
- await reactiveReadDir(dotGitPath, { includeHidden: true });
1036
- await reactiveReadFile(join(dotGitPath, "HEAD"));
1037
- await reactiveReadFile(join(dotGitPath, "index"));
1038
- await reactiveReadFile(join(dotGitPath, "packed-refs"));
1041
+ const gitMetadataDir = await resolveGitMetadataDirReactive(projectDir);
1042
+ if (!gitMetadataDir) return;
1043
+ await reactiveReadFile(getDashboardGitRefreshStampPath(gitMetadataDir));
1044
+ await reactiveReadFile(join(gitMetadataDir, "HEAD"));
1045
+ await reactiveReadFile(join(gitMetadataDir, "index"));
1046
+ await reactiveReadFile(join(gitMetadataDir, "packed-refs"));
1039
1047
  }
1040
1048
  function requireChangeId(changeId) {
1041
1049
  if (!changeId) throw new Error("change is required");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openspecui/server",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.mjs",
6
6
  "exports": {
@@ -20,8 +20,8 @@
20
20
  "yaml": "^2.8.0",
21
21
  "yargs": "^18.0.0",
22
22
  "zod": "^3.24.1",
23
- "@openspecui/search": "1.1.0",
24
- "@openspecui/core": "2.0.0"
23
+ "@openspecui/core": "2.0.0",
24
+ "@openspecui/search": "1.1.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/node": "^22.10.2",