@openspecui/server 2.1.2 → 2.1.5

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 +49 -13
  2. package/package.json +1 -1
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, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getWatcherRuntimeStatus, initWatcherPool, isWatcherPoolInitialized, sniffGlobalCli } from "@openspecui/core";
3
+ import { CliExecutor, CodeEditorThemeSchema, ConfigManager, DASHBOARD_METRIC_KEYS, DashboardConfigSchema, OpenSpecAdapter, OpenSpecWatcher, OpsxKernel, PtyClientMessageSchema, ReactiveContext, TerminalConfigSchema, TerminalRendererEngineSchema, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getDetectedProjectTools, getToolInitStates, getWatcherRuntimeStatus, initWatcherPool, isWatcherPoolInitialized, 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";
@@ -139,6 +139,19 @@ var DashboardOverviewService = class {
139
139
  }
140
140
  };
141
141
 
142
+ //#endregion
143
+ //#region ../core/src/dashboard-display.ts
144
+ const DASHBOARD_RECENT_LIST_LIMIT = 10;
145
+ function compareDashboardItemsByUpdatedAt(left, right) {
146
+ return right.updatedAt - left.updatedAt || left.id.localeCompare(right.id);
147
+ }
148
+ function sortDashboardItemsByUpdatedAt(items) {
149
+ return [...items].sort(compareDashboardItemsByUpdatedAt);
150
+ }
151
+ function selectRecentDashboardItems(items, limit = DASHBOARD_RECENT_LIST_LIMIT) {
152
+ return sortDashboardItemsByUpdatedAt(items).slice(0, Math.max(0, Math.trunc(limit)));
153
+ }
154
+
142
155
  //#endregion
143
156
  //#region src/dashboard-git-snapshot.ts
144
157
  const execFileAsync$1 = promisify(execFile);
@@ -635,12 +648,13 @@ async function loadDashboardOverview(ctx, reason = "dashboard-refresh") {
635
648
  ctx.adapter.listChangesWithMeta(),
636
649
  ctx.adapter.listArchivedChangesWithMeta()
637
650
  ]);
638
- const activeChanges = changeMetas.map((changeMeta) => ({
651
+ const allActiveChanges = changeMetas.map((changeMeta) => ({
639
652
  id: changeMeta.id,
640
653
  name: changeMeta.name ?? changeMeta.id,
641
654
  progress: changeMeta.progress,
642
655
  updatedAt: changeMeta.updatedAt
643
- })).sort((a, b) => b.updatedAt - a.updatedAt);
656
+ }));
657
+ const activeChanges = selectRecentDashboardItems(allActiveChanges);
644
658
  const archivedChanges = (await Promise.all(archiveMetas.map(async (meta) => {
645
659
  const change = await ctx.adapter.readArchivedChange(meta.id);
646
660
  if (!change) return null;
@@ -651,7 +665,7 @@ async function loadDashboardOverview(ctx, reason = "dashboard-refresh") {
651
665
  tasksCompleted: change.tasks.filter((task) => task.completed).length
652
666
  };
653
667
  }))).filter((item) => item !== null);
654
- const specifications = (await Promise.all(specMetas.map(async (meta) => {
668
+ const allSpecifications = (await Promise.all(specMetas.map(async (meta) => {
655
669
  const spec = await ctx.adapter.readSpec(meta.id);
656
670
  if (!spec) return null;
657
671
  return {
@@ -660,13 +674,14 @@ async function loadDashboardOverview(ctx, reason = "dashboard-refresh") {
660
674
  requirements: spec.requirements.length,
661
675
  updatedAt: meta.updatedAt
662
676
  };
663
- }))).filter((item) => item !== null).sort((a, b) => b.requirements - a.requirements || b.updatedAt - a.updatedAt);
664
- const requirements = specifications.reduce((sum, spec) => sum + spec.requirements, 0);
665
- const tasksTotal = activeChanges.reduce((sum, change) => sum + change.progress.total, 0);
666
- const tasksCompleted = activeChanges.reduce((sum, change) => sum + change.progress.completed, 0);
677
+ }))).filter((item) => item !== null);
678
+ const specifications = selectRecentDashboardItems(allSpecifications);
679
+ const requirements = allSpecifications.reduce((sum, spec) => sum + spec.requirements, 0);
680
+ const tasksTotal = allActiveChanges.reduce((sum, change) => sum + change.progress.total, 0);
681
+ const tasksCompleted = allActiveChanges.reduce((sum, change) => sum + change.progress.completed, 0);
667
682
  const archivedTasksCompleted = archivedChanges.reduce((sum, change) => sum + change.tasksCompleted, 0);
668
683
  const taskCompletionPercent = tasksTotal > 0 ? Math.round(tasksCompleted / tasksTotal * 100) : null;
669
- const inProgressChanges = activeChanges.filter((change) => change.progress.total > 0 && change.progress.completed < change.progress.total).length;
684
+ const inProgressChanges = allActiveChanges.filter((change) => change.progress.total > 0 && change.progress.completed < change.progress.total).length;
670
685
  const specificationTrendEvents = specMetas.flatMap((spec) => {
671
686
  const ts = resolveTrendTimestamp(spec.createdAt, spec.updatedAt);
672
687
  return ts === null ? [] : [{
@@ -682,7 +697,7 @@ async function loadDashboardOverview(ctx, reason = "dashboard-refresh") {
682
697
  }];
683
698
  });
684
699
  const specMetaById = new Map(specMetas.map((meta) => [meta.id, meta]));
685
- const requirementTrendEvents = specifications.flatMap((spec) => {
700
+ const requirementTrendEvents = allSpecifications.flatMap((spec) => {
686
701
  const meta = specMetaById.get(spec.id);
687
702
  const ts = resolveTrendTimestamp(meta?.updatedAt, meta?.createdAt);
688
703
  return ts === null ? [] : [{
@@ -690,7 +705,7 @@ async function loadDashboardOverview(ctx, reason = "dashboard-refresh") {
690
705
  value: spec.requirements
691
706
  }];
692
707
  });
693
- const hasObjectiveSpecificationTrend = specificationTrendEvents.length > 0 || specifications.length === 0;
708
+ const hasObjectiveSpecificationTrend = specificationTrendEvents.length > 0 || allSpecifications.length === 0;
694
709
  const hasObjectiveRequirementTrend = requirementTrendEvents.length > 0 || requirements === 0;
695
710
  const hasObjectiveCompletedTrend = completedTrendEvents.length > 0 || archiveMetas.length === 0;
696
711
  const config = await ctx.configManager.readConfig();
@@ -764,9 +779,9 @@ async function loadDashboardOverview(ctx, reason = "dashboard-refresh") {
764
779
  });
765
780
  return {
766
781
  summary: {
767
- specifications: specifications.length,
782
+ specifications: allSpecifications.length,
768
783
  requirements,
769
- activeChanges: activeChanges.length,
784
+ activeChanges: allActiveChanges.length,
770
785
  inProgressChanges,
771
786
  completedChanges: archiveMetas.length,
772
787
  archivedTasksCompleted,
@@ -1786,9 +1801,30 @@ const cliRouter = router({
1786
1801
  successLabel: tool.successLabel
1787
1802
  }));
1788
1803
  }),
1804
+ getDetectedProjectTools: publicProcedure.query(async ({ ctx }) => {
1805
+ return (await getDetectedProjectTools(ctx.projectDir)).map((tool) => ({
1806
+ name: tool.name,
1807
+ value: tool.value,
1808
+ available: tool.available,
1809
+ successLabel: tool.successLabel
1810
+ }));
1811
+ }),
1789
1812
  getProfileState: publicProcedure.query(async ({ ctx }) => {
1790
1813
  return fetchOpsxProfileState(ctx);
1791
1814
  }),
1815
+ getToolInitStates: publicProcedure.input(z.object({
1816
+ delivery: z.enum([
1817
+ "both",
1818
+ "skills",
1819
+ "commands"
1820
+ ]),
1821
+ workflows: z.array(z.string()).default([])
1822
+ })).query(async ({ ctx, input }) => {
1823
+ return getToolInitStates(ctx.projectDir, {
1824
+ delivery: input.delivery,
1825
+ workflows: input.workflows
1826
+ });
1827
+ }),
1792
1828
  getGlobalConfigPath: publicProcedure.query(async ({ ctx }) => {
1793
1829
  return { path: await resolveGlobalConfigPath(ctx) };
1794
1830
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openspecui/server",
3
- "version": "2.1.2",
3
+ "version": "2.1.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.mjs",
6
6
  "exports": {