@openspecui/web 10.0.0 → 11.1.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 (71) hide show
  1. package/dist/assets/{App-DJc144W-.js → App-V1__U9uZ.js} +122 -122
  2. package/dist/assets/App-wF-eA1hn.css +1 -0
  3. package/dist/assets/{main-DXrIDd5i.js → main-CKiFAoXE.js} +2 -2
  4. package/dist/assets/{trpc-EqFJjKn0.js → trpc-BLZ0FQJV.js} +1 -1
  5. package/dist/index.html +1 -1
  6. package/dist-ssg/client/.vite/ssr-manifest.json +39 -29
  7. package/dist-ssg/client/assets/CanvasRenderer-DcF6YeUw.js +1 -0
  8. package/dist-ssg/client/assets/WebGLRenderer-CUyEgGvz.js +1 -0
  9. package/dist-ssg/client/assets/WebGPURenderer-HO--KqMy.js +1 -0
  10. package/dist-ssg/client/assets/browserAll-CK2e9DJ7.js +1 -0
  11. package/dist-ssg/client/assets/{config-guide-presentation-BcSY1KFl.js → config-guide-presentation-BuoQZFn1.js} +1 -1
  12. package/dist-ssg/client/assets/{dist-B6Pffk4D.js → dist-2ZcaJZrJ.js} +1 -1
  13. package/dist-ssg/client/assets/dist-B8CANbA6.js +1 -0
  14. package/dist-ssg/client/assets/{dist-DP2j-YyT.js → dist-BCSOUbi7.js} +1 -1
  15. package/dist-ssg/client/assets/dist-BM2XFyj7.js +1 -0
  16. package/dist-ssg/client/assets/{dist-D_u4DgCb.js → dist-B_-3nALe.js} +1 -1
  17. package/dist-ssg/client/assets/{dist-C6Glwe3G.js → dist-Bbf-AGCl.js} +1 -1
  18. package/dist-ssg/client/assets/{dist-C24XzhQ9.js → dist-CH33y9Yu.js} +1 -1
  19. package/dist-ssg/client/assets/dist-CzvTcdIB.js +1 -0
  20. package/dist-ssg/client/assets/{dist-iFk0rzRc.js → dist-DHX5Y9iH.js} +1 -1
  21. package/dist-ssg/client/assets/{dist-DqLAJpLg.js → dist-Dtpb6ue4.js} +1 -1
  22. package/dist-ssg/client/assets/{dist-WVAwgVsq.js → dist-LQ5AvrWf.js} +1 -1
  23. package/dist-ssg/client/assets/{dist--KYFoBcy.js → dist-csqKQiDd.js} +1 -1
  24. package/dist-ssg/client/assets/{ghostty-web-lktg9S8z.js → ghostty-web-CvjC3u3U.js} +1 -1
  25. package/dist-ssg/client/assets/index-CTUS2FEE.css +1 -0
  26. package/dist-ssg/client/assets/{index.ssg-n59gyR9q.js → index.ssg-qirBkhbD.js} +101 -101
  27. package/dist-ssg/client/assets/{init-Cy2h-29G.js → init-DkFTD8N9.js} +1 -1
  28. package/dist-ssg/client/assets/{trpc-DxTuySH7.js → trpc-CeLyGxLD.js} +1 -1
  29. package/dist-ssg/client/assets/webworkerAll-D9xesa9H.js +1 -0
  30. package/dist-ssg/client/index.ssg.html +2 -2
  31. package/dist-ssg/server/assets/CanvasRenderer-Bvd3pXBF.js +3 -0
  32. package/dist-ssg/server/assets/WebGLRenderer-jIngAd_2.js +3 -0
  33. package/dist-ssg/server/assets/WebGPURenderer-C6g3K2oe.js +3 -0
  34. package/dist-ssg/server/assets/{browserAll-ByxW2BCo.js → browserAll-B9JXZQ_b.js} +2 -2
  35. package/dist-ssg/server/assets/{config-guide-presentation-BfkVCRQq.js → config-guide-presentation-D921NMVc.js} +1 -1
  36. package/dist-ssg/server/assets/dist-1rQWAJV4.js +3 -0
  37. package/dist-ssg/server/assets/dist-BIgXEKIS.js +3 -0
  38. package/dist-ssg/server/assets/{dist-C-7lPLui.js → dist-BJhwVaSw.js} +1 -1
  39. package/dist-ssg/server/assets/{dist-DzYuWuV1.js → dist-BhaY9Mk5.js} +1 -1
  40. package/dist-ssg/server/assets/{dist-wEaYViHh.js → dist-BjB76DhT.js} +1 -1
  41. package/dist-ssg/server/assets/{dist-j6yIDF4P.js → dist-CX9PVvRC.js} +1 -1
  42. package/dist-ssg/server/assets/{dist-DvJqEVFD.js → dist-CXVf0s87.js} +1 -1
  43. package/dist-ssg/server/assets/{dist-7sF3GmjJ.js → dist-CbRRi2nf.js} +1 -1
  44. package/dist-ssg/server/assets/dist-CzCglUOQ.js +3 -0
  45. package/dist-ssg/server/assets/{dist-5xHpmSpA.js → dist-D4O-5WhW.js} +1 -1
  46. package/dist-ssg/server/assets/{dist-Cj2NABFW.js → dist-D5RQw1xh.js} +1 -1
  47. package/dist-ssg/server/assets/{dist-BPIetWhy.js → dist-D6j5GTM2.js} +1 -1
  48. package/dist-ssg/server/assets/{entry-server-DccPywiF.js → entry-server-QFuPLrwO.js} +287 -68
  49. package/dist-ssg/server/assets/{init-mk1myhk2.js → init-B0dChRpm.js} +1 -1
  50. package/dist-ssg/server/assets/trpc-CbiCXi-L.js +3 -0
  51. package/dist-ssg/server/assets/webworkerAll-DukCMCoQ.js +4 -0
  52. package/dist-ssg/server/ssr-entry-manifest.json +24 -24
  53. package/package.json +3 -3
  54. package/dist/assets/App-CRdki6ZH.css +0 -1
  55. package/dist-ssg/client/assets/CanvasRenderer-CngPuJLR.js +0 -1
  56. package/dist-ssg/client/assets/WebGLRenderer-D6PAqEKt.js +0 -1
  57. package/dist-ssg/client/assets/WebGPURenderer-CtCVeRwN.js +0 -1
  58. package/dist-ssg/client/assets/browserAll-BiLg81NS.js +0 -1
  59. package/dist-ssg/client/assets/dist-BN2GrXVl.js +0 -1
  60. package/dist-ssg/client/assets/dist-DqTWWRfT.js +0 -1
  61. package/dist-ssg/client/assets/dist-ZlYc7_kt.js +0 -1
  62. package/dist-ssg/client/assets/index-CDBo5TOs.css +0 -1
  63. package/dist-ssg/client/assets/webworkerAll-B5n4bM-i.js +0 -1
  64. package/dist-ssg/server/assets/CanvasRenderer-D58O6peF.js +0 -3
  65. package/dist-ssg/server/assets/WebGLRenderer-CLVKAqNO.js +0 -3
  66. package/dist-ssg/server/assets/WebGPURenderer-D4vaKOO4.js +0 -3
  67. package/dist-ssg/server/assets/dist-CiijDa1h.js +0 -3
  68. package/dist-ssg/server/assets/dist-CkT7sc-T.js +0 -3
  69. package/dist-ssg/server/assets/dist-Ct3YhJiO.js +0 -3
  70. package/dist-ssg/server/assets/trpc-BPMx2lHD.js +0 -3
  71. package/dist-ssg/server/assets/webworkerAll-5v7Fs7LO.js +0 -4
@@ -30908,7 +30908,7 @@ var NavController = class {
30908
30908
  this.storageKey = scopedStorageKey;
30909
30909
  this.rebindProjectScopedLayout(scopedStorageKey);
30910
30910
  }
30911
- const { trpcClient } = await import("./trpc-BPMx2lHD.js");
30911
+ const { trpcClient } = await import("./trpc-CbiCXi-L.js");
30912
30912
  const remote = parsePersistedLayout(await trpcClient.kv.get.query({ key: this.storageKey }));
30913
30913
  if (remote) {
30914
30914
  if (remote.updatedAt > this.state.updatedAt) this.dispatch({
@@ -31051,7 +31051,7 @@ var NavController = class {
31051
31051
  this.cancelPersistTimer();
31052
31052
  this.persistTimer = setTimeout(() => {
31053
31053
  this.persistTimer = null;
31054
- import("./trpc-BPMx2lHD.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31054
+ import("./trpc-CbiCXi-L.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31055
31055
  key: this.storageKey,
31056
31056
  value: {
31057
31057
  mainTabs: this.state.mainTabs,
@@ -71180,7 +71180,7 @@ var browserExt = {
71180
71180
  },
71181
71181
  test: () => true,
71182
71182
  load: async () => {
71183
- await import("./browserAll-ByxW2BCo.js");
71183
+ await import("./browserAll-B9JXZQ_b.js");
71184
71184
  }
71185
71185
  };
71186
71186
  //#endregion
@@ -71193,7 +71193,7 @@ var webworkerExt = {
71193
71193
  },
71194
71194
  test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
71195
71195
  load: async () => {
71196
- await import("./webworkerAll-5v7Fs7LO.js");
71196
+ await import("./webworkerAll-DukCMCoQ.js");
71197
71197
  }
71198
71198
  };
71199
71199
  //#endregion
@@ -73787,7 +73787,7 @@ async function autoDetectRenderer(options) {
73787
73787
  for (let i = 0; i < preferredOrder.length; i++) {
73788
73788
  const rendererType = preferredOrder[i];
73789
73789
  if (rendererType === "webgpu" && await isWebGPUSupported()) {
73790
- const { WebGPURenderer } = await import("./WebGPURenderer-D4vaKOO4.js");
73790
+ const { WebGPURenderer } = await import("./WebGPURenderer-C6g3K2oe.js");
73791
73791
  RendererClass = WebGPURenderer;
73792
73792
  finalOptions = {
73793
73793
  ...options,
@@ -73795,7 +73795,7 @@ async function autoDetectRenderer(options) {
73795
73795
  };
73796
73796
  break;
73797
73797
  } else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
73798
- const { WebGLRenderer } = await import("./WebGLRenderer-CLVKAqNO.js");
73798
+ const { WebGLRenderer } = await import("./WebGLRenderer-jIngAd_2.js");
73799
73799
  RendererClass = WebGLRenderer;
73800
73800
  finalOptions = {
73801
73801
  ...options,
@@ -73803,7 +73803,7 @@ async function autoDetectRenderer(options) {
73803
73803
  };
73804
73804
  break;
73805
73805
  } else if (rendererType === "canvas") {
73806
- const { CanvasRenderer } = await import("./CanvasRenderer-D58O6peF.js");
73806
+ const { CanvasRenderer } = await import("./CanvasRenderer-Bvd3pXBF.js");
73807
73807
  RendererClass = CanvasRenderer;
73808
73808
  finalOptions = {
73809
73809
  ...options,
@@ -97552,7 +97552,7 @@ var TerminalController = class {
97552
97552
  if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
97553
97553
  this.configPersistTimer = setTimeout(() => {
97554
97554
  this.configPersistTimer = null;
97555
- import("./trpc-BPMx2lHD.js").then(({ trpcClient }) => {
97555
+ import("./trpc-CbiCXi-L.js").then(({ trpcClient }) => {
97556
97556
  trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
97557
97557
  }).catch(() => {});
97558
97558
  }, CONFIG_PERSIST_DEBOUNCE);
@@ -108113,7 +108113,7 @@ var languages = [
108113
108113
  name: "CSS",
108114
108114
  extensions: ["css"],
108115
108115
  load() {
108116
- return import("./dist-CiijDa1h.js").then((m) => m.css());
108116
+ return import("./dist-1rQWAJV4.js").then((m) => m.css());
108117
108117
  }
108118
108118
  }),
108119
108119
  /* @__PURE__ */ LanguageDescription.of({
@@ -108133,7 +108133,7 @@ var languages = [
108133
108133
  "hbs"
108134
108134
  ],
108135
108135
  load() {
108136
- return import("./dist-BPIetWhy.js").then((m) => m.html());
108136
+ return import("./dist-D6j5GTM2.js").then((m) => m.html());
108137
108137
  }
108138
108138
  }),
108139
108139
  /* @__PURE__ */ LanguageDescription.of({
@@ -108167,7 +108167,7 @@ var languages = [
108167
108167
  "jinja2"
108168
108168
  ],
108169
108169
  load() {
108170
- return import("./dist-Cj2NABFW.js").then((m) => m.jinja());
108170
+ return import("./dist-D5RQw1xh.js").then((m) => m.jinja());
108171
108171
  }
108172
108172
  }),
108173
108173
  /* @__PURE__ */ LanguageDescription.of({
@@ -108175,7 +108175,7 @@ var languages = [
108175
108175
  alias: ["json5"],
108176
108176
  extensions: ["json", "map"],
108177
108177
  load() {
108178
- return import("./dist-Ct3YhJiO.js").then((m) => m.json());
108178
+ return import("./dist-BIgXEKIS.js").then((m) => m.json());
108179
108179
  }
108180
108180
  }),
108181
108181
  /* @__PURE__ */ LanguageDescription.of({
@@ -108189,14 +108189,14 @@ var languages = [
108189
108189
  name: "LESS",
108190
108190
  extensions: ["less"],
108191
108191
  load() {
108192
- return import("./dist-DzYuWuV1.js").then((m) => m.less());
108192
+ return import("./dist-BhaY9Mk5.js").then((m) => m.less());
108193
108193
  }
108194
108194
  }),
108195
108195
  /* @__PURE__ */ LanguageDescription.of({
108196
108196
  name: "Liquid",
108197
108197
  extensions: ["liquid"],
108198
108198
  load() {
108199
- return import("./dist-wEaYViHh.js").then((m) => m.liquid());
108199
+ return import("./dist-BjB76DhT.js").then((m) => m.liquid());
108200
108200
  }
108201
108201
  }),
108202
108202
  /* @__PURE__ */ LanguageDescription.of({
@@ -108213,7 +108213,7 @@ var languages = [
108213
108213
  "mkd"
108214
108214
  ],
108215
108215
  load() {
108216
- return import("./dist-5xHpmSpA.js").then((m) => m.markdown());
108216
+ return import("./dist-D4O-5WhW.js").then((m) => m.markdown());
108217
108217
  }
108218
108218
  }),
108219
108219
  /* @__PURE__ */ LanguageDescription.of({
@@ -108239,7 +108239,7 @@ var languages = [
108239
108239
  "phtml"
108240
108240
  ],
108241
108241
  load() {
108242
- return import("./dist-7sF3GmjJ.js").then((m) => m.php());
108242
+ return import("./dist-CbRRi2nf.js").then((m) => m.php());
108243
108243
  }
108244
108244
  }),
108245
108245
  /* @__PURE__ */ LanguageDescription.of({
@@ -108279,14 +108279,14 @@ var languages = [
108279
108279
  name: "Sass",
108280
108280
  extensions: ["sass"],
108281
108281
  load() {
108282
- return import("./dist-C-7lPLui.js").then((m) => m.sass({ indented: true }));
108282
+ return import("./dist-BJhwVaSw.js").then((m) => m.sass({ indented: true }));
108283
108283
  }
108284
108284
  }),
108285
108285
  /* @__PURE__ */ LanguageDescription.of({
108286
108286
  name: "SCSS",
108287
108287
  extensions: ["scss"],
108288
108288
  load() {
108289
- return import("./dist-C-7lPLui.js").then((m) => m.sass());
108289
+ return import("./dist-BJhwVaSw.js").then((m) => m.sass());
108290
108290
  }
108291
108291
  }),
108292
108292
  /* @__PURE__ */ LanguageDescription.of({
@@ -108353,7 +108353,7 @@ var languages = [
108353
108353
  alias: ["yml"],
108354
108354
  extensions: ["yaml", "yml"],
108355
108355
  load() {
108356
- return import("./dist-CkT7sc-T.js").then((m) => m.yaml());
108356
+ return import("./dist-CzCglUOQ.js").then((m) => m.yaml());
108357
108357
  }
108358
108358
  }),
108359
108359
  /* @__PURE__ */ LanguageDescription.of({
@@ -109240,13 +109240,13 @@ var languages = [
109240
109240
  name: "Vue",
109241
109241
  extensions: ["vue"],
109242
109242
  load() {
109243
- return import("./dist-DvJqEVFD.js").then((m) => m.vue());
109243
+ return import("./dist-CXVf0s87.js").then((m) => m.vue());
109244
109244
  }
109245
109245
  }),
109246
109246
  /* @__PURE__ */ LanguageDescription.of({
109247
109247
  name: "Angular Template",
109248
109248
  load() {
109249
- return import("./dist-j6yIDF4P.js").then((m) => m.angular());
109249
+ return import("./dist-CX9PVvRC.js").then((m) => m.angular());
109250
109250
  }
109251
109251
  })
109252
109252
  ];
@@ -171556,7 +171556,7 @@ function isSupportedNonCurrentSeries(version) {
171556
171556
  * Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。"
171557
171557
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
171558
171558
  */
171559
- function parseValidationReport(value) {
171559
+ function parseValidationReport$1(value) {
171560
171560
  const parsed = CliValidateReportSchema.safeParse(value);
171561
171561
  if (parsed.success) return {
171562
171562
  report: parsed.data,
@@ -171567,7 +171567,7 @@ function parseValidationReport(value) {
171567
171567
  schemaIssues: parsed.error.issues.map((issue) => `${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`)
171568
171568
  };
171569
171569
  }
171570
- function IssueList({ issues }) {
171570
+ function IssueList$1({ issues }) {
171571
171571
  if (issues.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
171572
171572
  className: "text-muted-foreground",
171573
171573
  children: "No CLI issue reported."
@@ -171586,7 +171586,7 @@ function IssueList({ issues }) {
171586
171586
  }, index))
171587
171587
  });
171588
171588
  }
171589
- function RunButton({ pending, label, onRun }) {
171589
+ function RunButton$1({ pending, label, onRun }) {
171590
171590
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
171591
171591
  type: "button",
171592
171592
  onClick: onRun,
@@ -171645,7 +171645,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171645
171645
  tone: "unavailable"
171646
171646
  };
171647
171647
  if (!report && !error) return null;
171648
- const parsed = report ? parseValidationReport(report.data) : {
171648
+ const parsed = report ? parseValidationReport$1(report.data) : {
171649
171649
  report: null,
171650
171650
  schemaIssues: []
171651
171651
  };
@@ -171716,14 +171716,14 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171716
171716
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
171717
171717
  className: "text-muted-foreground",
171718
171718
  children: "Run the official CLI's archived-task validation and keep its typed report as evidence. OpenSpecUI never repairs or archives from here."
171719
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
171719
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
171720
171720
  pending,
171721
171721
  label: "Validate archived tasks",
171722
171722
  onRun: () => void run()
171723
171723
  })]
171724
171724
  })
171725
171725
  });
171726
- const parsed = report ? parseValidationReport(report.data) : {
171726
+ const parsed = report ? parseValidationReport$1(report.data) : {
171727
171727
  report: null,
171728
171728
  schemaIssues: []
171729
171729
  };
@@ -171744,7 +171744,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171744
171744
  className: "min-w-0 break-all",
171745
171745
  children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The archived validation command failed."
171746
171746
  })]
171747
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
171747
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
171748
171748
  pending,
171749
171749
  label: "Rerun",
171750
171750
  onRun: () => void run()
@@ -171808,11 +171808,11 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171808
171808
  })]
171809
171809
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171810
171810
  className: "mt-1",
171811
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IssueList, { issues: item.issues })
171811
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IssueList$1, { issues: item.issues })
171812
171812
  })]
171813
171813
  }, item.id))
171814
171814
  }),
171815
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
171815
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
171816
171816
  pending,
171817
171817
  label: "Rerun",
171818
171818
  onRun: () => void run()
@@ -173116,7 +173116,7 @@ var CONFIG_GUIDE_STAGE_META = {
173116
173116
  //#region src/components/config/config-guide.tsx
173117
173117
  var ConfigGuideContext = (0, import_react.createContext)(null);
173118
173118
  (0, import_react.lazy)(async () => {
173119
- return { default: (await import("./config-guide-presentation-BfkVCRQq.js")).ConfigGuidePresentationLayer };
173119
+ return { default: (await import("./config-guide-presentation-D921NMVc.js")).ConfigGuidePresentationLayer };
173120
173120
  });
173121
173121
  /** Access the root-owned adaptive Guide runtime. */
173122
173122
  function useConfigGuide() {
@@ -178823,6 +178823,208 @@ function SettingsStatic() {
178823
178823
  });
178824
178824
  }
178825
178825
  //#endregion
178826
+ //#region src/components/spec-validation-evidence.tsx
178827
+ /**
178828
+ * Orthogonal intents (created 2026-08-28 Asia/Shanghai):
178829
+ * 1. Present OpenSpec `validate --specs` and `validate <id> --type spec --json` as typed CLI evidence.
178830
+ * 2. Share one on-demand, read-only surface for the all-specs toolbar action and the owned-spec
178831
+ * detail action; OpenSpecUI never repairs or rewrites anything from here.
178832
+ * 3. Identify the evidence as unavailable in static snapshots instead of fabricating it.
178833
+ * 4. Validate transport and report payloads with the Core contract schemas, never shallow guards.
178834
+ *
178835
+ * Original request (2026-08-28): Specifications 列表右上角提供"校验全部 specs",单 spec 详情右上角提供单项校验。
178836
+ */
178837
+ function parseValidationReport(value) {
178838
+ const parsed = CliValidateReportSchema.safeParse(value);
178839
+ if (parsed.success) return {
178840
+ report: parsed.data,
178841
+ schemaIssues: []
178842
+ };
178843
+ return {
178844
+ report: null,
178845
+ schemaIssues: parsed.error.issues.map((issue) => `${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`)
178846
+ };
178847
+ }
178848
+ function IssueList({ issues }) {
178849
+ if (issues.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
178850
+ className: "text-muted-foreground",
178851
+ children: "No CLI issue reported."
178852
+ });
178853
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
178854
+ className: "text-muted-foreground space-y-0.5",
178855
+ children: issues.map((issue, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
178856
+ className: "break-words",
178857
+ children: [
178858
+ issue.level,
178859
+ " · ",
178860
+ issue.path,
178861
+ " · ",
178862
+ issue.message
178863
+ ]
178864
+ }, index))
178865
+ });
178866
+ }
178867
+ function RunButton({ pending, label, onRun }) {
178868
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
178869
+ type: "button",
178870
+ onClick: onRun,
178871
+ disabled: pending,
178872
+ "aria-busy": pending || void 0,
178873
+ className: "border-border hover:bg-muted inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-xs disabled:opacity-50",
178874
+ children: [pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
178875
+ className: "h-3.5 w-3.5 animate-spin",
178876
+ "aria-hidden": true
178877
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCw, {
178878
+ className: "h-3.5 w-3.5",
178879
+ "aria-hidden": true
178880
+ }), label]
178881
+ });
178882
+ }
178883
+ /**
178884
+ * On-demand spec-scope validation evidence. Mounts with its trigger aligned to the inline-end
178885
+ * of a page header; the typed report panel unfolds beneath it only after a run, so unexecuted
178886
+ * sessions render no verdict at all.
178887
+ */
178888
+ function SpecValidationEvidence({ target }) {
178889
+ const [report, setReport] = (0, import_react.useState)(null);
178890
+ const [error, setError] = (0, import_react.useState)(null);
178891
+ const [pending, setPending] = (0, import_react.useState)(false);
178892
+ const staticMode = isStaticMode();
178893
+ const label = target.kind === "specs" ? "Validate specs" : "Validate this spec";
178894
+ if (staticMode) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
178895
+ className: "text-muted-foreground max-w-xs text-right text-xs",
178896
+ children: "Spec validation is live CLI evidence and is not captured in this static snapshot."
178897
+ });
178898
+ const run = async () => {
178899
+ setPending(true);
178900
+ setError(null);
178901
+ setReport(null);
178902
+ try {
178903
+ const input = target.kind === "specs" ? {
178904
+ kind: "scope",
178905
+ scope: "specs"
178906
+ } : {
178907
+ kind: "item",
178908
+ id: target.specId,
178909
+ type: "spec"
178910
+ };
178911
+ const result = await trpcClient.cli.validate.mutate(input);
178912
+ const transport = CliCommandTransportSchema.safeParse(result);
178913
+ if (transport.success) setReport({
178914
+ ...transport.data,
178915
+ data: transport.data.data ?? null,
178916
+ payload: transport.data.payload ?? null
178917
+ });
178918
+ else setError("The spec validation transport returned an unrecognized result shape.");
178919
+ } catch (cause) {
178920
+ setError(cause instanceof Error ? cause.message : String(cause));
178921
+ } finally {
178922
+ setPending(false);
178923
+ }
178924
+ };
178925
+ if (!report && !error) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
178926
+ pending,
178927
+ label,
178928
+ onRun: () => void run()
178929
+ });
178930
+ const parsed = report ? parseValidationReport(report.data) : {
178931
+ report: null,
178932
+ schemaIssues: []
178933
+ };
178934
+ const validationReport = parsed.report;
178935
+ if (error || !validationReport) {
178936
+ const schemaDiagnostic = parsed.schemaIssues.length > 0 ? parsed.schemaIssues.join("; ") : null;
178937
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
178938
+ className: "border-border/60 w-full max-w-2xl self-end rounded border p-3 text-left",
178939
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
178940
+ className: "text-destructive flex items-start gap-2 break-words",
178941
+ role: "alert",
178942
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
178943
+ className: "mt-0.5 h-3.5 w-3.5 shrink-0",
178944
+ "aria-hidden": true
178945
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
178946
+ className: "min-w-0 break-all",
178947
+ children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The spec validation command failed."
178948
+ })]
178949
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
178950
+ className: "mt-2",
178951
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
178952
+ pending,
178953
+ label: "Rerun",
178954
+ onRun: () => void run()
178955
+ })
178956
+ })]
178957
+ });
178958
+ }
178959
+ const failed = validationReport.summary.totals.failed;
178960
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
178961
+ className: "border-border/60 w-full max-w-2xl self-end rounded border p-3 text-left",
178962
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
178963
+ className: "space-y-3",
178964
+ children: [
178965
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
178966
+ className: "grid min-w-0 gap-x-3 gap-y-1",
178967
+ children: [
178968
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
178969
+ className: "text-muted-foreground",
178970
+ children: "Root"
178971
+ }),
178972
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
178973
+ className: "min-w-0 break-all font-mono",
178974
+ children: validationReport.root.path
178975
+ }),
178976
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
178977
+ className: "text-muted-foreground",
178978
+ children: "Exit"
178979
+ }),
178980
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: report?.exitCode ?? "unknown" }),
178981
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
178982
+ className: "text-muted-foreground",
178983
+ children: "Totals"
178984
+ }),
178985
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dd", { children: [
178986
+ validationReport.summary.totals.passed,
178987
+ " passed · ",
178988
+ failed,
178989
+ " failed ·",
178990
+ " ",
178991
+ validationReport.summary.totals.items,
178992
+ " specs"
178993
+ ] })
178994
+ ]
178995
+ }),
178996
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
178997
+ className: "space-y-2",
178998
+ children: validationReport.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
178999
+ className: "border-border/60 rounded border p-2",
179000
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
179001
+ className: "flex min-w-0 items-center gap-2",
179002
+ children: [item.valid && item.issues.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleCheck, {
179003
+ className: "h-3.5 w-3.5 shrink-0 text-emerald-600",
179004
+ "aria-hidden": true
179005
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
179006
+ className: `h-3.5 w-3.5 shrink-0 ${item.valid ? "text-amber-600" : "text-destructive"}`,
179007
+ "aria-hidden": true
179008
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
179009
+ className: "min-w-0 break-all font-mono text-[11px]",
179010
+ children: item.id
179011
+ })]
179012
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
179013
+ className: "mt-1",
179014
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IssueList, { issues: item.issues })
179015
+ })]
179016
+ }, item.id))
179017
+ }),
179018
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
179019
+ pending,
179020
+ label: "Rerun",
179021
+ onRun: () => void run()
179022
+ })
179023
+ ]
179024
+ })
179025
+ });
179026
+ }
179027
+ //#endregion
178826
179028
  //#region src/routes/spec-list-continuity.ts
178827
179029
  /**
178828
179030
  * Orthogonal intents (created 2026-07-23 Asia/Shanghai):
@@ -178917,7 +179119,7 @@ function useSpecListContinuity(incomingSpecs, scope, containerRef) {
178917
179119
  //#endregion
178918
179120
  //#region src/routes/spec-list.tsx
178919
179121
  /**
178920
- * Orthogonal intents (updated 2026-08-01 Asia/Shanghai):
179122
+ * Orthogonal intents (updated 2026-08-28 Asia/Shanghai):
178921
179123
  * 1. Default the project Spec Catalog to writable Owned Specs.
178922
179124
  * 2. Group direct read-only Referenced Specs by Store identity and preserve source-distinct Catalog policy.
178923
179125
  * 3. Preserve complete recursive routes, collision-safe View Transition identity, and local row continuity.
@@ -178927,6 +179129,7 @@ function useSpecListContinuity(incomingSpecs, scope, containerRef) {
178927
179129
  * Original request (2026-07-15): "Specs defaults to Owned and provides a Store-grouped Referenced view with immutable entries."
178928
179130
  * Original request (2026-07-28): compact Catalog source and read-only metadata without hiding enumeration failures.
178929
179131
  * Original request (2026-08-01): adapt OpenSpec 1.7 nested Spec ids such as `platform/auth`.
179132
+ * Original request (2026-08-28): Specifications 顶部右侧提供“校验全部 specs”动作。
178930
179133
  */
178931
179134
  function readSpecListScopeState(state) {
178932
179135
  if (typeof state !== "object" || state == null) return "owned";
@@ -178994,9 +179197,12 @@ function SpecList() {
178994
179197
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
178995
179198
  className: "space-y-6 p-4",
178996
179199
  children: [
178997
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
178998
- className: "font-nav flex items-center gap-2 text-2xl font-bold",
178999
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileText, { className: "h-6 w-6 shrink-0" }), "Specifications"]
179200
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
179201
+ className: "flex flex-wrap items-center justify-between gap-3",
179202
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
179203
+ className: "font-nav flex items-center gap-2 text-2xl font-bold",
179204
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileText, { className: "h-6 w-6 shrink-0" }), "Specifications"]
179205
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpecValidationEvidence, { target: { kind: "specs" } })]
179000
179206
  }),
179001
179207
  errorAlert,
179002
179208
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -179187,14 +179393,16 @@ function SpecCatalogRow({ spec }) {
179187
179393
  //#endregion
179188
179394
  //#region src/routes/spec-view.tsx
179189
179395
  /**
179190
- * Orthogonal intents (updated 2026-07-25 Asia/Shanghai):
179396
+ * Orthogonal intents (updated 2026-08-28 Asia/Shanghai):
179191
179397
  * 1. Resolve owned and referenced Spec routes through compound identity.
179192
179398
  * 2. Render owned Markdown through the existing document pipeline.
179193
179399
  * 3. Render live CLI evidence and static snapshot conditions without synthesizing CLI or route-derived Store provenance.
179194
179400
  * 4. Preserve collision-safe View Transition identity across source-distinct documents.
179195
179401
  * 5. Retain successful detail content beside terminal document subscription errors.
179402
+ * 6. Offer owned-spec validation as header-inline-end CLI evidence; referenced specs stay read-only.
179196
179403
  *
179197
179404
  * Original request (2026-07-15): "Referenced Specs are navigable and searchable but visibly read-only."
179405
+ * Original request (2026-08-28): 单 spec 详情右上角提供单项校验动作。
179198
179406
  */
179199
179407
  function SpecView() {
179200
179408
  const { specId, storeId } = useParams({ strict: false });
@@ -179254,42 +179462,49 @@ function SpecLoading({ identity, title, subtitle }) {
179254
179462
  })]
179255
179463
  });
179256
179464
  }
179257
- function SpecHeader({ identity, title, subtitle, sourceRef, sharedDescriptor }) {
179465
+ function SpecHeader({ identity, title, subtitle, sourceRef, sharedDescriptor, actions }) {
179258
179466
  const sourceLabel = subtitle ?? (identity.kind === "owned" ? `Owned · ${identity.specId}` : `Referenced from ${identity.storeId} · ${identity.specId}`);
179259
179467
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
179260
179468
  className: "flex min-w-0 items-center gap-4",
179261
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(VTLink, {
179262
- to: "/specs",
179263
- state: (previous) => ({
179264
- ...previous,
179265
- __specListScope: identity.kind
179469
+ children: [
179470
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VTLink, {
179471
+ to: "/specs",
179472
+ state: (previous) => ({
179473
+ ...previous,
179474
+ __specListScope: identity.kind
179475
+ }),
179476
+ vt: {
179477
+ source: sourceRef,
179478
+ sharedElements: sharedDescriptor
179479
+ },
179480
+ className: "hover:bg-muted shrink-0 rounded-md p-2",
179481
+ "aria-label": "Back to specifications",
179482
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, { className: "h-5 w-5" })
179266
179483
  }),
179267
- vt: {
179268
- source: sourceRef,
179269
- sharedElements: sharedDescriptor
179270
- },
179271
- className: "hover:bg-muted shrink-0 rounded-md p-2",
179272
- "aria-label": "Back to specifications",
179273
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, { className: "h-5 w-5" })
179274
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
179275
- ref: sourceRef,
179276
- ...getSharedElementBinding(sharedDescriptor, "container"),
179277
- className: "min-w-0",
179278
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
179279
- className: "font-nav flex min-w-0 items-center gap-2 text-2xl font-bold",
179280
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileText, {
179281
- ...getSharedElementBinding(sharedDescriptor, "icon"),
179282
- className: "h-6 w-6 shrink-0"
179283
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
179284
- ...getSharedElementBinding(sharedDescriptor, "title"),
179285
- className: "truncate",
179286
- children: title
179484
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
179485
+ ref: sourceRef,
179486
+ ...getSharedElementBinding(sharedDescriptor, "container"),
179487
+ className: "min-w-0",
179488
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
179489
+ className: "font-nav flex min-w-0 items-center gap-2 text-2xl font-bold",
179490
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileText, {
179491
+ ...getSharedElementBinding(sharedDescriptor, "icon"),
179492
+ className: "h-6 w-6 shrink-0"
179493
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
179494
+ ...getSharedElementBinding(sharedDescriptor, "title"),
179495
+ className: "truncate",
179496
+ children: title
179497
+ })]
179498
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
179499
+ className: "text-muted-foreground truncate",
179500
+ children: sourceLabel
179287
179501
  })]
179288
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
179289
- className: "text-muted-foreground truncate",
179290
- children: sourceLabel
179291
- })]
179292
- })]
179502
+ }),
179503
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
179504
+ className: "ml-auto flex min-w-0 flex-col items-end gap-2",
179505
+ children: actions
179506
+ }) : null
179507
+ ]
179293
179508
  });
179294
179509
  }
179295
179510
  function OwnedSpecContent({ identity, spec, rawMarkdown, translationConfig, errorMessage }) {
@@ -179310,7 +179525,11 @@ function OwnedSpecContent({ identity, spec, rawMarkdown, translationConfig, erro
179310
179525
  identity,
179311
179526
  title: spec.name,
179312
179527
  sourceRef: headerRef,
179313
- sharedDescriptor
179528
+ sharedDescriptor,
179529
+ actions: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpecValidationEvidence, { target: {
179530
+ kind: "spec",
179531
+ specId: identity.specId
179532
+ } })
179314
179533
  }),
179315
179534
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MarkdownViewer, {
179316
179535
  markdown: rawMarkdown,
@@ -1,5 +1,5 @@
1
1
  import { it as extensions } from "./Geometry-jQ4l8GtP.js";
2
- import { M as FilterPipe, j as FilterSystem } from "./entry-server-DccPywiF.js";
2
+ import { M as FilterPipe, j as FilterSystem } from "./entry-server-QFuPLrwO.js";
3
3
  //#region ../../node_modules/.pnpm/pixi.js@8.16.0/node_modules/pixi.js/lib/filters/init.mjs
4
4
  extensions.add(FilterSystem);
5
5
  extensions.add(FilterPipe);
@@ -0,0 +1,3 @@
1
+ import "./jsx-runtime-CQL-l9BP.js";
2
+ import { Nt as trpcClient } from "./entry-server-QFuPLrwO.js";
3
+ export { trpcClient };
@@ -0,0 +1,4 @@
1
+ import "./Geometry-jQ4l8GtP.js";
2
+ import "./entry-server-QFuPLrwO.js";
3
+ import "./init-B0dChRpm.js";
4
+ export {};