@openspecui/server 4.0.2 → 5.0.0

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 +108 -1
  2. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as resolveCt2ModelDownloadPlanFromRepositoryFiles } from "./src-Dh_UAz5C.mjs";
2
2
  import { t as resolveGgufModelDownloadPlanFromRepositoryFiles } from "./src-CZfiVL_-.mjs";
3
- import { BatchTranslateInputSchema, CliExecutor, CodeEditorThemeSchema, ConfigManager, CustomSoundHashSchema, DASHBOARD_METRIC_KEYS, DashboardConfigSchema, DocumentTranslationConfigUpdateSchema, GitConfigSchema, GlobalSettingsManager, LocalModelAssetStateSchema, LocalModelLifecycleFileStateSchema, LocalModelLifecycleGroupStateSchema, LocalModelProfileManifestSchema, MarkdownParser, NotificationPublishInputSchema, NotificationSettingsSchema, OPENSPECUI_HOOKS_VERSION, OpenSpecAdapter, OpenSpecUIGlobalSettingsUpdateSchema, OpenSpecWatcher, OpsxConfigSchema, OpsxKernel, PtyClientMessageSchema, ReactiveContext, ServiceTranslationEngineIdSchema, TRANSLATION_ENGINE_MANIFESTS, TerminalConfigSchema, TerminalControlParser, TerminalRendererEngineSchema, TranslationCacheReadInputSchema, TranslationCacheWriteInputSchema, TranslationEngineIdSchema, TranslationEngineLifecycleStatusSchema, buildBackendHealthPayload, buildLocalDownloadPlanFromRepositoryFiles, buildRuntimePackageInstallCommand, checkLocalDirectionalModelLanguagePair, clearCache, createCleanCliEnv, createTranslationEngineLifecycleStatus, detectRuntimePackageManager, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getDetectedProjectTools, getManagedLocalTranslationEngineManifest, getOpsxEntityRootRelativePath, getToolInitStates, getTranslationEngineLifecycleMessage, getWatcherRuntimeStatus, inferFileMime, inferFilePreviewKind, initWatcherPool, isDirectionalManagedLocalTranslationEngineId, isManagedLocalTranslationEngineId, isTranslationEngineDependencyReady, isTranslationEngineRuntimeReady, isWatcherPoolInitialized, normalizeBatchTranslationError, normalizeOpsxEntityPath, parseOpsxEntityMetadata, parseOpsxSchemaDetail, resolveRuntimePackageInstallStrategy, resolveTerminalShellDefaults, selectLocalDownloadGroup, shouldShowTranslationEngineInstallGate, sniffGlobalCli, subscribeWatcherRuntimeStatus, terminalNotificationEventToPublishInput } from "@openspecui/core";
3
+ import { BatchTranslateInputSchema, CliExecutor, CodeEditorThemeSchema, ConfigManager, CustomSoundHashSchema, DASHBOARD_METRIC_KEYS, DashboardConfigSchema, DocumentTranslationConfigUpdateSchema, GitConfigSchema, GlobalSettingsManager, LocalModelAssetStateSchema, LocalModelLifecycleFileStateSchema, LocalModelLifecycleGroupStateSchema, LocalModelProfileManifestSchema, MarkdownParser, NotificationPublishInputSchema, NotificationSettingsSchema, OPENSPECUI_HOOKS_VERSION, OpenSpecAdapter, OpenSpecUIGlobalSettingsUpdateSchema, OpenSpecWatcher, OpsxConfigSchema, OpsxKernel, PtyClientMessageSchema, ReactiveContext, ServiceTranslationEngineIdSchema, StoreDoctorResultSchema, StoreListResultSchema, TRANSLATION_ENGINE_MANIFESTS, TerminalConfigSchema, TerminalControlParser, TerminalRendererEngineSchema, TranslationCacheReadInputSchema, TranslationCacheWriteInputSchema, TranslationEngineIdSchema, TranslationEngineLifecycleStatusSchema, buildBackendHealthPayload, buildLocalDownloadPlanFromRepositoryFiles, buildRuntimePackageInstallCommand, checkLocalDirectionalModelLanguagePair, classifyStoreCliOutput, clearCache, createCleanCliEnv, createTranslationEngineLifecycleStatus, detectRuntimePackageManager, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getDetectedProjectTools, getManagedLocalTranslationEngineManifest, getOpsxEntityRootRelativePath, getToolInitStates, getTranslationEngineLifecycleMessage, getWatcherRuntimeStatus, inferFileMime, inferFilePreviewKind, initWatcherPool, isDirectionalManagedLocalTranslationEngineId, isManagedLocalTranslationEngineId, isTranslationEngineDependencyReady, isTranslationEngineRuntimeReady, isWatcherPoolInitialized, normalizeBatchTranslationError, normalizeOpsxEntityPath, parseOpsxEntityMetadata, parseOpsxSchemaDetail, resolveRuntimePackageInstallStrategy, resolveTerminalShellDefaults, selectLocalDownloadGroup, shouldShowTranslationEngineInstallGate, sniffGlobalCli, subscribeWatcherRuntimeStatus, terminalNotificationEventToPublishInput, toStoreFeatureResult } from "@openspecui/core";
4
4
  import { basename, dirname, extname, join, matchesGlob, relative, resolve, sep } from "node:path";
5
5
  import { access, copyFile, lstat, mkdir, open, readFile, readlink, realpath, rename, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -10156,6 +10156,112 @@ const gitRouter = router({
10156
10156
  })
10157
10157
  });
10158
10158
  /**
10159
+ * Stores router — read-only discovery of machine-registered OpenSpec stores (beta).
10160
+ *
10161
+ * 实现 beta 功能容错范式(spec: openspec-cli-integration › Beta Feature Fault Tolerance):
10162
+ * 后端对 `openspec store list/doctor --json` 做宽松解析,把失败归类为两类异常,**永不抛未捕获错误**。
10163
+ * - 异常一(数据不兼容):exit 0 但 zod 宽松验证失败 → available=false + error.kind='data-incompatible'
10164
+ * - 异常二(指令变更/缺失):非零退出 → available=false + error.kind='command-unavailable'
10165
+ * 两种异常都尽力携带 cliVersion(版本信息非常重要)。前端据此决定"显示错误+版本"或"隐藏入口"。
10166
+ */
10167
+ const STORES_LIST_CACHE_TTL_MS = 3e4;
10168
+ let cachedCliVersion = null;
10169
+ async function resolveCliVersion(ctx) {
10170
+ const now = Date.now();
10171
+ if (cachedCliVersion && cachedCliVersion.expiresAt > now) return cachedCliVersion.value;
10172
+ try {
10173
+ const availability = await ctx.cliExecutor.checkAvailability();
10174
+ cachedCliVersion = {
10175
+ value: availability.version,
10176
+ expiresAt: now + STORES_LIST_CACHE_TTL_MS
10177
+ };
10178
+ return availability.version;
10179
+ } catch {
10180
+ cachedCliVersion = {
10181
+ value: void 0,
10182
+ expiresAt: now + STORES_LIST_CACHE_TTL_MS
10183
+ };
10184
+ return;
10185
+ }
10186
+ }
10187
+ async function fetchStoresList(ctx) {
10188
+ const cliVersion = await resolveCliVersion(ctx).catch(() => void 0);
10189
+ try {
10190
+ const result = await ctx.cliExecutor.listStores();
10191
+ return toStoreFeatureResult(classifyStoreCliOutput({
10192
+ success: result.success,
10193
+ stdout: result.stdout,
10194
+ stderr: result.stderr,
10195
+ parse: (stdout) => StoreListResultSchema.parse(JSON.parse(stdout)),
10196
+ cliVersion
10197
+ }), {
10198
+ fromData: (data) => {
10199
+ const parsed = data;
10200
+ return Array.isArray(parsed.stores) ? parsed.stores : [];
10201
+ },
10202
+ fallback: [],
10203
+ cliVersion
10204
+ });
10205
+ } catch (error) {
10206
+ return {
10207
+ available: false,
10208
+ stores: [],
10209
+ error: {
10210
+ kind: "command-unavailable",
10211
+ message: error instanceof Error ? error.message : String(error),
10212
+ ...cliVersion ? { cliVersion } : {}
10213
+ },
10214
+ ...cliVersion ? { cliVersion } : {}
10215
+ };
10216
+ }
10217
+ }
10218
+ async function fetchStoresDoctor(ctx, id) {
10219
+ const cliVersion = await resolveCliVersion(ctx).catch(() => void 0);
10220
+ try {
10221
+ const result = await ctx.cliExecutor.doctorStores(id);
10222
+ return toStoreFeatureResult(classifyStoreCliOutput({
10223
+ success: result.success,
10224
+ stdout: result.stdout,
10225
+ stderr: result.stderr,
10226
+ parse: (stdout) => StoreDoctorResultSchema.parse(JSON.parse(stdout)),
10227
+ cliVersion
10228
+ }), {
10229
+ fromData: (data) => {
10230
+ const parsed = data;
10231
+ return Array.isArray(parsed.stores) ? parsed.stores : [];
10232
+ },
10233
+ fallback: [],
10234
+ cliVersion
10235
+ });
10236
+ } catch (error) {
10237
+ return {
10238
+ available: false,
10239
+ stores: [],
10240
+ error: {
10241
+ kind: "command-unavailable",
10242
+ message: error instanceof Error ? error.message : String(error),
10243
+ ...cliVersion ? { cliVersion } : {}
10244
+ },
10245
+ ...cliVersion ? { cliVersion } : {}
10246
+ };
10247
+ }
10248
+ }
10249
+ const storesRouter = router({
10250
+ list: publicProcedure.query(({ ctx }) => fetchStoresList(ctx)),
10251
+ doctor: publicProcedure.input(z.object({ id: z.string().optional() }).optional()).query(({ ctx, input }) => fetchStoresDoctor(ctx, input?.id)),
10252
+ subscribe: publicProcedure.subscription(({ ctx }) => {
10253
+ return observable((emit) => {
10254
+ const push = () => {
10255
+ fetchStoresList(ctx).then((result) => emit.next(result)).catch(() => {});
10256
+ };
10257
+ push();
10258
+ const timer = setInterval(push, 5e3);
10259
+ timer.unref();
10260
+ return () => clearInterval(timer);
10261
+ });
10262
+ })
10263
+ });
10264
+ /**
10159
10265
  * Main app router
10160
10266
  */
10161
10267
  const appRouter = router({
@@ -10177,6 +10283,7 @@ const appRouter = router({
10177
10283
  sounds: soundsRouter,
10178
10284
  cli: cliRouter,
10179
10285
  opsx: opsxRouter,
10286
+ stores: storesRouter,
10180
10287
  kv: kvRouter,
10181
10288
  search: searchRouter,
10182
10289
  system: systemRouter
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openspecui/server",
3
- "version": "4.0.2",
3
+ "version": "5.0.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.mjs",
6
6
  "exports": {
@@ -24,8 +24,8 @@
24
24
  "@hono/node-server": "^1.14.1",
25
25
  "@huggingface/hub": "^2.12.0",
26
26
  "@lydell/node-pty": "^1.1.0",
27
- "@openspecui/core": "4.0.2",
28
- "@openspecui/search": "4.0.2",
27
+ "@openspecui/core": "5.0.0",
28
+ "@openspecui/search": "5.0.0",
29
29
  "@trpc/server": "^11.0.0",
30
30
  "better-sqlite3": "^12.5.0",
31
31
  "hono": "^4.7.3",