@openspecui/web 11.1.0 → 12.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 (72) hide show
  1. package/dist/assets/App-BagQkLCd.css +1 -0
  2. package/dist/assets/{App-V1__U9uZ.js → App-Dmag08k5.js} +159 -159
  3. package/dist/assets/{main-CKiFAoXE.js → main-DXjJbv3-.js} +2 -2
  4. package/dist/assets/{trpc-BLZ0FQJV.js → trpc-CENMN-Kx.js} +1 -1
  5. package/dist/index.html +1 -1
  6. package/dist-ssg/client/.vite/ssr-manifest.json +59 -29
  7. package/dist-ssg/client/assets/CanvasRenderer-B3YNEZKU.js +1 -0
  8. package/dist-ssg/client/assets/WebGLRenderer-91FdO4XE.js +1 -0
  9. package/dist-ssg/client/assets/WebGPURenderer-BcSREi3g.js +1 -0
  10. package/dist-ssg/client/assets/browserAll-CRvGxmXW.js +1 -0
  11. package/dist-ssg/client/assets/{config-guide-presentation-BuoQZFn1.js → config-guide-presentation-GtsojPuN.js} +1 -1
  12. package/dist-ssg/client/assets/{dist-Dtpb6ue4.js → dist-B0xIEOgo.js} +1 -1
  13. package/dist-ssg/client/assets/{dist-2ZcaJZrJ.js → dist-BAP9yhhm.js} +1 -1
  14. package/dist-ssg/client/assets/dist-Bsojfco7.js +1 -0
  15. package/dist-ssg/client/assets/{dist-CH33y9Yu.js → dist-BxTQbErr.js} +1 -1
  16. package/dist-ssg/client/assets/{dist-Bbf-AGCl.js → dist-C7lTRiju.js} +1 -1
  17. package/dist-ssg/client/assets/{dist-B_-3nALe.js → dist-CI3zBObR.js} +1 -1
  18. package/dist-ssg/client/assets/{dist-LQ5AvrWf.js → dist-CJOMMo-D.js} +1 -1
  19. package/dist-ssg/client/assets/{dist-DHX5Y9iH.js → dist-Cgf7W726.js} +1 -1
  20. package/dist-ssg/client/assets/{dist-csqKQiDd.js → dist-DHkPjBBo.js} +1 -1
  21. package/dist-ssg/client/assets/{dist-BCSOUbi7.js → dist-Df3fSUJ8.js} +1 -1
  22. package/dist-ssg/client/assets/dist-fJz8f69P.js +1 -0
  23. package/dist-ssg/client/assets/dist-we8a11kz.js +1 -0
  24. package/dist-ssg/client/assets/{ghostty-web-CvjC3u3U.js → ghostty-web-VZE4TZBO.js} +1 -1
  25. package/dist-ssg/client/assets/index-CS0xsSqt.css +1 -0
  26. package/dist-ssg/client/assets/index.ssg-m0qZ-Tbv.js +1650 -0
  27. package/dist-ssg/client/assets/{init-DkFTD8N9.js → init-0qJSx79q.js} +1 -1
  28. package/dist-ssg/client/assets/{trpc-CeLyGxLD.js → trpc-D4bSp4J9.js} +1 -1
  29. package/dist-ssg/client/assets/webworkerAll-BUpVAcIt.js +1 -0
  30. package/dist-ssg/client/index.ssg.html +2 -2
  31. package/dist-ssg/server/assets/CanvasRenderer-eDcOd6Sl.js +3 -0
  32. package/dist-ssg/server/assets/WebGLRenderer-BYGgdFoJ.js +3 -0
  33. package/dist-ssg/server/assets/WebGPURenderer-CS5mt9ch.js +3 -0
  34. package/dist-ssg/server/assets/{browserAll-B9JXZQ_b.js → browserAll-Da2y8ybl.js} +2 -2
  35. package/dist-ssg/server/assets/{config-guide-presentation-D921NMVc.js → config-guide-presentation-GWnVFKTW.js} +1 -1
  36. package/dist-ssg/server/assets/{dist-CXVf0s87.js → dist-A6g9ScYS.js} +1 -1
  37. package/dist-ssg/server/assets/{dist-D4O-5WhW.js → dist-Bk9be2-W.js} +1 -1
  38. package/dist-ssg/server/assets/dist-C8ZGbZgL.js +3 -0
  39. package/dist-ssg/server/assets/{dist-BhaY9Mk5.js → dist-C8mczL_o.js} +1 -1
  40. package/dist-ssg/server/assets/{dist-D5RQw1xh.js → dist-CRw-jyve.js} +1 -1
  41. package/dist-ssg/server/assets/{dist-BjB76DhT.js → dist-CmE7gK9r.js} +1 -1
  42. package/dist-ssg/server/assets/dist-D2ilXjzO.js +3 -0
  43. package/dist-ssg/server/assets/{dist-BJhwVaSw.js → dist-D3Ubfaie.js} +1 -1
  44. package/dist-ssg/server/assets/{dist-CX9PVvRC.js → dist-DHhdkqG1.js} +1 -1
  45. package/dist-ssg/server/assets/dist-DbHDr3r9.js +3 -0
  46. package/dist-ssg/server/assets/{dist-CbRRi2nf.js → dist-QLG95fVW.js} +1 -1
  47. package/dist-ssg/server/assets/{dist-D6j5GTM2.js → dist-dHhPmrtl.js} +1 -1
  48. package/dist-ssg/server/assets/{entry-server-QFuPLrwO.js → entry-server-B1byBTHL.js} +702 -94
  49. package/dist-ssg/server/assets/{init-B0dChRpm.js → init-BCpyot27.js} +1 -1
  50. package/dist-ssg/server/assets/trpc-D5UIUAYV.js +3 -0
  51. package/dist-ssg/server/assets/webworkerAll-Dg825OUg.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-wF-eA1hn.css +0 -1
  55. package/dist-ssg/client/assets/CanvasRenderer-DcF6YeUw.js +0 -1
  56. package/dist-ssg/client/assets/WebGLRenderer-CUyEgGvz.js +0 -1
  57. package/dist-ssg/client/assets/WebGPURenderer-HO--KqMy.js +0 -1
  58. package/dist-ssg/client/assets/browserAll-CK2e9DJ7.js +0 -1
  59. package/dist-ssg/client/assets/dist-B8CANbA6.js +0 -1
  60. package/dist-ssg/client/assets/dist-BM2XFyj7.js +0 -1
  61. package/dist-ssg/client/assets/dist-CzvTcdIB.js +0 -1
  62. package/dist-ssg/client/assets/index-CTUS2FEE.css +0 -1
  63. package/dist-ssg/client/assets/index.ssg-qirBkhbD.js +0 -1650
  64. package/dist-ssg/client/assets/webworkerAll-D9xesa9H.js +0 -1
  65. package/dist-ssg/server/assets/CanvasRenderer-Bvd3pXBF.js +0 -3
  66. package/dist-ssg/server/assets/WebGLRenderer-jIngAd_2.js +0 -3
  67. package/dist-ssg/server/assets/WebGPURenderer-C6g3K2oe.js +0 -3
  68. package/dist-ssg/server/assets/dist-1rQWAJV4.js +0 -3
  69. package/dist-ssg/server/assets/dist-BIgXEKIS.js +0 -3
  70. package/dist-ssg/server/assets/dist-CzCglUOQ.js +0 -3
  71. package/dist-ssg/server/assets/trpc-CbiCXi-L.js +0 -3
  72. package/dist-ssg/server/assets/webworkerAll-DukCMCoQ.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-CbiCXi-L.js");
30911
+ const { trpcClient } = await import("./trpc-D5UIUAYV.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-CbiCXi-L.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31054
+ import("./trpc-D5UIUAYV.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31055
31055
  key: this.storageKey,
31056
31056
  value: {
31057
31057
  mainTabs: this.state.mainTabs,
@@ -39144,23 +39144,109 @@ var CliValidationTotalsSchema = objectType({
39144
39144
  passed: numberType(),
39145
39145
  failed: numberType()
39146
39146
  }).passthrough();
39147
+ /** One bulk Validate item: verdict, full issue array, and runtime-dependent duration. */
39148
+ var CliValidateItemSchema = objectType({
39149
+ id: stringType(),
39150
+ type: enumType(["change", "spec"]),
39151
+ valid: booleanType(),
39152
+ issues: arrayType(CliValidationIssueSchema),
39153
+ durationMs: numberType()
39154
+ }).passthrough();
39155
+ /** Shared Validate summary: full-run totals plus per-type totals, never the filtered view. */
39156
+ var CliValidateSummarySchema = objectType({
39157
+ totals: CliValidationTotalsSchema,
39158
+ byType: recordType(CliValidationTotalsSchema)
39159
+ }).passthrough();
39147
39160
  /** Typed ordinary Validate report, also used by 1.9 `validate --archived --json`. */
39148
39161
  var CliValidateReportSchema = objectType({
39149
- items: arrayType(objectType({
39150
- id: stringType(),
39151
- type: enumType(["change", "spec"]),
39152
- valid: booleanType(),
39153
- issues: arrayType(CliValidationIssueSchema),
39154
- durationMs: numberType()
39155
- }).passthrough()),
39156
- summary: objectType({
39157
- totals: CliValidationTotalsSchema,
39158
- byType: recordType(CliValidationTotalsSchema)
39159
- }).passthrough(),
39162
+ items: arrayType(CliValidateItemSchema),
39163
+ summary: CliValidateSummarySchema,
39160
39164
  version: stringType(),
39161
39165
  root: CliRootSchema
39162
39166
  }).passthrough();
39163
39167
  unionType([CliValidateReportSchema, CliDiagnosticFailureSchema]);
39168
+ /**
39169
+ * Typed OpenSpec 1.12 `validate --report findings` document.
39170
+ *
39171
+ * The findings report is a filtered evidence transport beside the full report, never the
39172
+ * validation truth: `itemFindings` carries only items with issues, while `summary` and
39173
+ * `root` stay the full-run values the CLI computed over every item in scope.
39174
+ * `report.returnedItems`/`report.totalItems` distinguish the filtered view from the run
39175
+ * size, and the process exit code keeps the full-run rule (`failed > 0 -> 1`), so decoding
39176
+ * never consults it. An empty scope is the success document
39177
+ * `{ returnedItems: 0, totalItems: 0, itemFindings: [] }`, not a failure sum type.
39178
+ *
39179
+ * Two upstream-guaranteed invariants are decode-level facts (pinned v1.12.0
39180
+ * `projectValidationFindings`): every `itemFindings` entry carries at least one issue
39181
+ * (upstream filters `item.issues.length > 0`), and `returnedItems` never exceeds
39182
+ * `totalItems` (the filtered view is a subset of the full run). Upstream also happens to
39183
+ * set `returnedItems === itemFindings.length` today; that equality stays unasserted so a
39184
+ * future patch-level count adjustment inside the admitted range cannot fabricate a
39185
+ * contract error out of otherwise well-formed CLI evidence.
39186
+ */
39187
+ var CliValidateFindingsSchema = objectType({
39188
+ report: objectType({
39189
+ kind: literalType("validation-findings"),
39190
+ version: stringType(),
39191
+ scope: enumType([
39192
+ "all",
39193
+ "changes",
39194
+ "specs",
39195
+ "archived"
39196
+ ]),
39197
+ returnedItems: numberType(),
39198
+ totalItems: numberType()
39199
+ }).passthrough(),
39200
+ itemFindings: arrayType(CliValidateItemSchema),
39201
+ summary: CliValidateSummarySchema,
39202
+ root: CliRootSchema
39203
+ }).passthrough().superRefine((document, ctx) => {
39204
+ if (document.report.returnedItems > document.report.totalItems) ctx.addIssue({
39205
+ code: ZodIssueCode.custom,
39206
+ path: ["report", "returnedItems"],
39207
+ message: `returnedItems (${document.report.returnedItems}) must not exceed totalItems (${document.report.totalItems}).`
39208
+ });
39209
+ document.itemFindings.forEach((finding, index) => {
39210
+ if (finding.issues.length === 0) ctx.addIssue({
39211
+ code: ZodIssueCode.custom,
39212
+ path: [
39213
+ "itemFindings",
39214
+ index,
39215
+ "issues"
39216
+ ],
39217
+ message: "Every findings item must carry at least one issue."
39218
+ });
39219
+ });
39220
+ });
39221
+ /**
39222
+ * Typed findings or request-failure result of `validate --report findings --json`.
39223
+ *
39224
+ * Invalid requests (no bulk scope, an item name, archived+active mixing, or an unknown
39225
+ * report value) produce the shared status-array failure envelope with code
39226
+ * `invalid_validation_report_request`, decoded here through the shared diagnostic
39227
+ * failure schema including its optional `fix` string.
39228
+ */
39229
+ var CliValidateFindingsResultSchema = unionType([CliValidateFindingsSchema, CliDiagnosticFailureSchema]);
39230
+ /**
39231
+ * Whether a findings result is the findings document rather than the request-failure
39232
+ * envelope. Passthrough tolerance means a failure envelope may legally carry unknown
39233
+ * keys, so mere `report`-key presence cannot discriminate the union: the guard validates
39234
+ * the upstream discriminator shape — `report` is an object whose `kind` is the
39235
+ * `validation-findings` literal and whose count fields are numbers.
39236
+ *
39237
+ * The input is deliberately `unknown`: route and evidence consumers receive the union
39238
+ * of every validate transport (`CliValidate | CliValidateFindingsResult | null`), so the
39239
+ * guard must accept the consumed boundary, not only the already-narrowed findings union.
39240
+ * It stays a cheap shape check, never a second decode: schema-level invariants
39241
+ * (issue presence, count bounds) belong to `CliValidateFindingsSchema` alone.
39242
+ */
39243
+ function isCliValidateFindings(result) {
39244
+ if (typeof result !== "object" || result === null) return false;
39245
+ const report = result.report;
39246
+ if (typeof report !== "object" || report === null) return false;
39247
+ const { kind, returnedItems, totalItems } = report;
39248
+ return kind === "validation-findings" && typeof returnedItems === "number" && typeof totalItems === "number";
39249
+ }
39164
39250
  var CliArchiveTotalsSchema = objectType({
39165
39251
  added: numberType(),
39166
39252
  modified: numberType(),
@@ -47051,6 +47137,20 @@ var Moon = createLucideIcon("Moon", [["path", {
47051
47137
  d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z",
47052
47138
  key: "a7tn18"
47053
47139
  }]]);
47140
+ var OctagonAlert = createLucideIcon("OctagonAlert", [
47141
+ ["path", {
47142
+ d: "M12 16h.01",
47143
+ key: "1drbdi"
47144
+ }],
47145
+ ["path", {
47146
+ d: "M12 8v4",
47147
+ key: "1got3b"
47148
+ }],
47149
+ ["path", {
47150
+ d: "M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z",
47151
+ key: "1fd625"
47152
+ }]
47153
+ ]);
47054
47154
  var PackageOpen = createLucideIcon("PackageOpen", [
47055
47155
  ["path", {
47056
47156
  d: "M12 22v-9",
@@ -71180,7 +71280,7 @@ var browserExt = {
71180
71280
  },
71181
71281
  test: () => true,
71182
71282
  load: async () => {
71183
- await import("./browserAll-B9JXZQ_b.js");
71283
+ await import("./browserAll-Da2y8ybl.js");
71184
71284
  }
71185
71285
  };
71186
71286
  //#endregion
@@ -71193,7 +71293,7 @@ var webworkerExt = {
71193
71293
  },
71194
71294
  test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
71195
71295
  load: async () => {
71196
- await import("./webworkerAll-DukCMCoQ.js");
71296
+ await import("./webworkerAll-Dg825OUg.js");
71197
71297
  }
71198
71298
  };
71199
71299
  //#endregion
@@ -73787,7 +73887,7 @@ async function autoDetectRenderer(options) {
73787
73887
  for (let i = 0; i < preferredOrder.length; i++) {
73788
73888
  const rendererType = preferredOrder[i];
73789
73889
  if (rendererType === "webgpu" && await isWebGPUSupported()) {
73790
- const { WebGPURenderer } = await import("./WebGPURenderer-C6g3K2oe.js");
73890
+ const { WebGPURenderer } = await import("./WebGPURenderer-CS5mt9ch.js");
73791
73891
  RendererClass = WebGPURenderer;
73792
73892
  finalOptions = {
73793
73893
  ...options,
@@ -73795,7 +73895,7 @@ async function autoDetectRenderer(options) {
73795
73895
  };
73796
73896
  break;
73797
73897
  } else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
73798
- const { WebGLRenderer } = await import("./WebGLRenderer-jIngAd_2.js");
73898
+ const { WebGLRenderer } = await import("./WebGLRenderer-BYGgdFoJ.js");
73799
73899
  RendererClass = WebGLRenderer;
73800
73900
  finalOptions = {
73801
73901
  ...options,
@@ -73803,7 +73903,7 @@ async function autoDetectRenderer(options) {
73803
73903
  };
73804
73904
  break;
73805
73905
  } else if (rendererType === "canvas") {
73806
- const { CanvasRenderer } = await import("./CanvasRenderer-Bvd3pXBF.js");
73906
+ const { CanvasRenderer } = await import("./CanvasRenderer-eDcOd6Sl.js");
73807
73907
  RendererClass = CanvasRenderer;
73808
73908
  finalOptions = {
73809
73909
  ...options,
@@ -97552,7 +97652,7 @@ var TerminalController = class {
97552
97652
  if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
97553
97653
  this.configPersistTimer = setTimeout(() => {
97554
97654
  this.configPersistTimer = null;
97555
- import("./trpc-CbiCXi-L.js").then(({ trpcClient }) => {
97655
+ import("./trpc-D5UIUAYV.js").then(({ trpcClient }) => {
97556
97656
  trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
97557
97657
  }).catch(() => {});
97558
97658
  }, CONFIG_PERSIST_DEBOUNCE);
@@ -108113,7 +108213,7 @@ var languages = [
108113
108213
  name: "CSS",
108114
108214
  extensions: ["css"],
108115
108215
  load() {
108116
- return import("./dist-1rQWAJV4.js").then((m) => m.css());
108216
+ return import("./dist-C8ZGbZgL.js").then((m) => m.css());
108117
108217
  }
108118
108218
  }),
108119
108219
  /* @__PURE__ */ LanguageDescription.of({
@@ -108133,7 +108233,7 @@ var languages = [
108133
108233
  "hbs"
108134
108234
  ],
108135
108235
  load() {
108136
- return import("./dist-D6j5GTM2.js").then((m) => m.html());
108236
+ return import("./dist-dHhPmrtl.js").then((m) => m.html());
108137
108237
  }
108138
108238
  }),
108139
108239
  /* @__PURE__ */ LanguageDescription.of({
@@ -108167,7 +108267,7 @@ var languages = [
108167
108267
  "jinja2"
108168
108268
  ],
108169
108269
  load() {
108170
- return import("./dist-D5RQw1xh.js").then((m) => m.jinja());
108270
+ return import("./dist-CRw-jyve.js").then((m) => m.jinja());
108171
108271
  }
108172
108272
  }),
108173
108273
  /* @__PURE__ */ LanguageDescription.of({
@@ -108175,7 +108275,7 @@ var languages = [
108175
108275
  alias: ["json5"],
108176
108276
  extensions: ["json", "map"],
108177
108277
  load() {
108178
- return import("./dist-BIgXEKIS.js").then((m) => m.json());
108278
+ return import("./dist-D2ilXjzO.js").then((m) => m.json());
108179
108279
  }
108180
108280
  }),
108181
108281
  /* @__PURE__ */ LanguageDescription.of({
@@ -108189,14 +108289,14 @@ var languages = [
108189
108289
  name: "LESS",
108190
108290
  extensions: ["less"],
108191
108291
  load() {
108192
- return import("./dist-BhaY9Mk5.js").then((m) => m.less());
108292
+ return import("./dist-C8mczL_o.js").then((m) => m.less());
108193
108293
  }
108194
108294
  }),
108195
108295
  /* @__PURE__ */ LanguageDescription.of({
108196
108296
  name: "Liquid",
108197
108297
  extensions: ["liquid"],
108198
108298
  load() {
108199
- return import("./dist-BjB76DhT.js").then((m) => m.liquid());
108299
+ return import("./dist-CmE7gK9r.js").then((m) => m.liquid());
108200
108300
  }
108201
108301
  }),
108202
108302
  /* @__PURE__ */ LanguageDescription.of({
@@ -108213,7 +108313,7 @@ var languages = [
108213
108313
  "mkd"
108214
108314
  ],
108215
108315
  load() {
108216
- return import("./dist-D4O-5WhW.js").then((m) => m.markdown());
108316
+ return import("./dist-Bk9be2-W.js").then((m) => m.markdown());
108217
108317
  }
108218
108318
  }),
108219
108319
  /* @__PURE__ */ LanguageDescription.of({
@@ -108239,7 +108339,7 @@ var languages = [
108239
108339
  "phtml"
108240
108340
  ],
108241
108341
  load() {
108242
- return import("./dist-CbRRi2nf.js").then((m) => m.php());
108342
+ return import("./dist-QLG95fVW.js").then((m) => m.php());
108243
108343
  }
108244
108344
  }),
108245
108345
  /* @__PURE__ */ LanguageDescription.of({
@@ -108279,14 +108379,14 @@ var languages = [
108279
108379
  name: "Sass",
108280
108380
  extensions: ["sass"],
108281
108381
  load() {
108282
- return import("./dist-BJhwVaSw.js").then((m) => m.sass({ indented: true }));
108382
+ return import("./dist-D3Ubfaie.js").then((m) => m.sass({ indented: true }));
108283
108383
  }
108284
108384
  }),
108285
108385
  /* @__PURE__ */ LanguageDescription.of({
108286
108386
  name: "SCSS",
108287
108387
  extensions: ["scss"],
108288
108388
  load() {
108289
- return import("./dist-BJhwVaSw.js").then((m) => m.sass());
108389
+ return import("./dist-D3Ubfaie.js").then((m) => m.sass());
108290
108390
  }
108291
108391
  }),
108292
108392
  /* @__PURE__ */ LanguageDescription.of({
@@ -108353,7 +108453,7 @@ var languages = [
108353
108453
  alias: ["yml"],
108354
108454
  extensions: ["yaml", "yml"],
108355
108455
  load() {
108356
- return import("./dist-CzCglUOQ.js").then((m) => m.yaml());
108456
+ return import("./dist-DbHDr3r9.js").then((m) => m.yaml());
108357
108457
  }
108358
108458
  }),
108359
108459
  /* @__PURE__ */ LanguageDescription.of({
@@ -109240,13 +109340,13 @@ var languages = [
109240
109340
  name: "Vue",
109241
109341
  extensions: ["vue"],
109242
109342
  load() {
109243
- return import("./dist-CXVf0s87.js").then((m) => m.vue());
109343
+ return import("./dist-A6g9ScYS.js").then((m) => m.vue());
109244
109344
  }
109245
109345
  }),
109246
109346
  /* @__PURE__ */ LanguageDescription.of({
109247
109347
  name: "Angular Template",
109248
109348
  load() {
109249
- return import("./dist-CX9PVvRC.js").then((m) => m.angular());
109349
+ return import("./dist-DHhdkqG1.js").then((m) => m.angular());
109250
109350
  }
109251
109351
  })
109252
109352
  ];
@@ -171483,17 +171583,31 @@ function ChangeReferenceFailureNotice({ referenceEvidence }) {
171483
171583
  });
171484
171584
  }
171485
171585
  //#endregion
171586
+ //#region src/components/evidence-layer-header.tsx
171587
+ function EvidenceLayerHeader({ title, summary }) {
171588
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
171589
+ className: "border-border mb-4 flex min-w-0 flex-wrap items-baseline justify-between gap-x-3 gap-y-1 border-b py-2.5",
171590
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
171591
+ className: "min-w-0 text-sm font-semibold tracking-tight",
171592
+ children: title
171593
+ }), summary ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
171594
+ className: "text-muted-foreground min-w-0 text-[11px]",
171595
+ children: summary
171596
+ }) : null]
171597
+ });
171598
+ }
171599
+ //#endregion
171486
171600
  //#region ../core/src/openspec-compat.ts
171487
- var OPENSPEC_CLI_TARGET_SERIES = "1.11";
171488
- var OPENSPEC_CLI_SUPPORTED_SERIES = ["1.10", "1.11"];
171489
- var OPENSPEC_CLI_ACCEPTED_RANGE = ">=1.10.0 <1.12.0";
171601
+ var OPENSPEC_CLI_TARGET_SERIES = "1.12";
171602
+ var OPENSPEC_CLI_SUPPORTED_SERIES = ["1.12"];
171603
+ var OPENSPEC_CLI_ACCEPTED_RANGE = ">=1.12.0 <1.13.0";
171490
171604
  /**
171491
171605
  * Derive command capabilities from one parsed CLI version.
171492
171606
  *
171493
171607
  * Only an admitted version — stable inside the accepted range — can select version-specific
171494
- * capabilities. Unsupported forms (prereleases, >=1.12, below-range) and unparseable output
171608
+ * capabilities. Unsupported forms (prereleases, >=1.13, below-range) and unparseable output
171495
171609
  * keep their mismatch evidence and expose no capability, so a page-level version bypass can
171496
- * never manufacture a 1.11 command surface for a CLI the release line does not admit.
171610
+ * never manufacture a 1.12 command surface for a CLI the release line does not admit.
171497
171611
  */
171498
171612
  function deriveOpenSpecCliCapabilities(version) {
171499
171613
  if (!isAdmittedVersion(version)) return {
@@ -171501,7 +171615,8 @@ function deriveOpenSpecCliCapabilities(version) {
171501
171615
  archivedValidation: false,
171502
171616
  initLanguage: false,
171503
171617
  batchStatus: false,
171504
- requirementDiff: false
171618
+ requirementDiff: false,
171619
+ findingsReport: false
171505
171620
  };
171506
171621
  const onTargetSeries = isSeries(version, OPENSPEC_CLI_TARGET_SERIES);
171507
171622
  return {
@@ -171509,7 +171624,8 @@ function deriveOpenSpecCliCapabilities(version) {
171509
171624
  archivedValidation: true,
171510
171625
  initLanguage: true,
171511
171626
  batchStatus: onTargetSeries,
171512
- requirementDiff: onTargetSeries
171627
+ requirementDiff: onTargetSeries,
171628
+ findingsReport: onTargetSeries
171513
171629
  };
171514
171630
  }
171515
171631
  function parseOpenSpecCliVersion(raw) {
@@ -171533,7 +171649,7 @@ function isStable(version) {
171533
171649
  /** True only for stable versions inside the accepted range (current or supported non-current). */
171534
171650
  function isAdmittedVersion(version) {
171535
171651
  if (!version || !isStable(version)) return false;
171536
- return isSeries(version, "1.11") || isSupportedNonCurrentSeries(version);
171652
+ return isSeries(version, "1.12") || isSupportedNonCurrentSeries(version);
171537
171653
  }
171538
171654
  function isSupportedNonCurrentSeries(version) {
171539
171655
  return OPENSPEC_CLI_SUPPORTED_SERIES.filter((series) => series !== OPENSPEC_CLI_TARGET_SERIES).some((series) => isSeries(version, series));
@@ -171541,12 +171657,12 @@ function isSupportedNonCurrentSeries(version) {
171541
171657
  //#endregion
171542
171658
  //#region src/components/archived-validation-evidence.tsx
171543
171659
  /**
171544
- * Orthogonal intents (updated 2026-08-28 Asia/Shanghai):
171660
+ * Orthogonal intents (updated 2026-09-03 Asia/Shanghai):
171545
171661
  * 1. Present OpenSpec `validate --archived --json` as typed CLI evidence.
171546
171662
  * 2. Preserve item issues, totals, root, and exit/failure evidence without repair actions.
171547
171663
  * 3. Identify the evidence as unavailable in static snapshots instead of fabricating it.
171548
- * 4. Derive the capability from the detected admitted CLI; both admitted v11 lines (1.10 and
171549
- * 1.11) declare it, so the unavailable branch names the accepted range, not one series.
171664
+ * 4. Derive the capability from the detected admitted CLI; the admitted 1.12 line declares
171665
+ * it, so the unavailable branch names the accepted range, not one series.
171550
171666
  * 5. Validate report payloads with the Core contract schema, never shallow shape guards.
171551
171667
  * 6. Mount directly inside the Evidence workspace detail pane: the Accordion shell is gone, the
171552
171668
  * section header keeps the title and summary facts, and `onChip` reports only derived facts
@@ -171555,6 +171671,8 @@ function isSupportedNonCurrentSeries(version) {
171555
171671
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
171556
171672
  * Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。"
171557
171673
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
171674
+ * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
171675
+ * Owner walkthrough correction (2026-09-04): every Evidence detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding); this replaces each layer's local weak header.
171558
171676
  */
171559
171677
  function parseValidationReport$1(value) {
171560
171678
  const parsed = CliValidateReportSchema.safeParse(value);
@@ -171586,7 +171704,7 @@ function IssueList$1({ issues }) {
171586
171704
  }, index))
171587
171705
  });
171588
171706
  }
171589
- function RunButton$1({ pending, label, onRun }) {
171707
+ function RunButton$2({ pending, label, onRun }) {
171590
171708
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
171591
171709
  type: "button",
171592
171710
  onClick: onRun,
@@ -171612,17 +171730,11 @@ function ArchivedValidationSection({ summary, children }) {
171612
171730
  "data-evidence-section": "archived-validation",
171613
171731
  "aria-label": "Archived validation",
171614
171732
  className: "min-w-0",
171615
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
171616
- className: "border-border/60 flex min-w-0 flex-wrap items-baseline justify-between gap-x-3 gap-y-1 border-b pb-2",
171617
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
171618
- className: "min-w-0 text-xs font-semibold",
171619
- children: "Archived validation"
171620
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
171621
- className: "text-muted-foreground min-w-0 text-[11px]",
171622
- children: summary
171623
- })]
171733
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
171734
+ title: "Archived validation",
171735
+ summary
171624
171736
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171625
- className: "min-w-0 pt-3",
171737
+ className: "min-w-0 text-xs",
171626
171738
  children
171627
171739
  })]
171628
171740
  });
@@ -171716,7 +171828,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171716
171828
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
171717
171829
  className: "text-muted-foreground",
171718
171830
  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$1, {
171831
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$2, {
171720
171832
  pending,
171721
171833
  label: "Validate archived tasks",
171722
171834
  onRun: () => void run()
@@ -171744,7 +171856,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171744
171856
  className: "min-w-0 break-all",
171745
171857
  children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The archived validation command failed."
171746
171858
  })]
171747
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
171859
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$2, {
171748
171860
  pending,
171749
171861
  label: "Rerun",
171750
171862
  onRun: () => void run()
@@ -171812,7 +171924,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171812
171924
  })]
171813
171925
  }, item.id))
171814
171926
  }),
171815
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
171927
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$2, {
171816
171928
  pending,
171817
171929
  label: "Rerun",
171818
171930
  onRun: () => void run()
@@ -171824,12 +171936,13 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171824
171936
  //#endregion
171825
171937
  //#region src/components/change-diff-evidence.tsx
171826
171938
  /**
171827
- * Orthogonal intents (updated 2026-08-28 Asia/Shanghai):
171939
+ * Orthogonal intents (updated 2026-09-03 Asia/Shanghai):
171828
171940
  * 1. Present the CLI-provided MODIFIED-delta `diff`/`warning` fields as Change Detail evidence.
171829
171941
  * 2. Color the unified diff body by line role (+/-/@@) without recomputing anything locally.
171830
171942
  * 3. Render the exact upstream warning text beside its diff so a near-miss never swallows evidence.
171831
- * 4. Gate the fetch on the detected admitted CLI's `requirementDiff` capability (1.11 only) and on
171832
- * live mode: static snapshots and 1.10 sessions never issue the transport call.
171943
+ * 4. Gate the fetch on the detected admitted CLI's `requirementDiff` capability (the admitted
171944
+ * 1.12 line) and on live mode: static snapshots and retired sessions never issue the
171945
+ * transport call.
171833
171946
  * 5. Degrade to the existing delta presentation when the fields are absent — no fabricated diff
171834
171947
  * or warning may appear.
171835
171948
  * 6. Mount directly inside the Evidence workspace detail pane: the Accordion shell is gone, the
@@ -171838,6 +171951,8 @@ function ArchivedValidationEvidence({ onChip } = {}) {
171838
171951
  *
171839
171952
  * Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。"
171840
171953
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
171954
+ * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
171955
+ * Owner walkthrough correction (2026-09-04): every Evidence detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding); this replaces each layer's local weak header.
171841
171956
  */
171842
171957
  function diffLineRole(line) {
171843
171958
  if (line.startsWith("@@")) return "hunk";
@@ -171928,22 +172043,16 @@ function RequirementDiffsSection({ summary, children }) {
171928
172043
  "data-evidence-section": "requirement-diffs",
171929
172044
  "aria-label": "Requirement diffs",
171930
172045
  className: "min-w-0",
171931
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
171932
- className: "border-border/60 flex min-w-0 flex-wrap items-baseline justify-between gap-x-3 gap-y-1 border-b pb-2",
171933
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
171934
- className: "min-w-0 text-xs font-semibold",
171935
- children: "Requirement diffs"
171936
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
171937
- className: "text-muted-foreground min-w-0 text-[11px]",
171938
- children: summary
171939
- })]
172046
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
172047
+ title: "Requirement diffs",
172048
+ summary
171940
172049
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171941
- className: "min-w-0 pt-3",
172050
+ className: "min-w-0 text-xs",
171942
172051
  children
171943
172052
  })]
171944
172053
  });
171945
172054
  }
171946
- /** CLI MODIFIED-delta diff evidence for the Change Evidence workspace (live 1.11 sessions only). */
172055
+ /** CLI MODIFIED-delta diff evidence for the Change Evidence workspace (admitted-line live sessions only). */
171947
172056
  function ChangeDiffEvidence({ changeId, onChip }) {
171948
172057
  const cli = useRootActionState().context?.cli;
171949
172058
  const diffCapable = deriveOpenSpecCliCapabilities(cli?.available ? parseOpenSpecCliVersion(cli.version) : null).requirementDiff;
@@ -172017,9 +172126,13 @@ function ChangeDiffEvidence({ changeId, onChip }) {
172017
172126
  if (!diffCapable) {
172018
172127
  if (cli?.available !== true) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequirementDiffsSection, {
172019
172128
  summary: "CLI diff evidence",
172020
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172129
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
172021
172130
  className: "text-muted-foreground",
172022
- children: "Requirement diff evidence from `show --diff` appears here on admitted OpenSpec CLI 1.11 sessions once the CLI is detected."
172131
+ children: [
172132
+ "Requirement diff evidence from `show --diff` appears here on admitted OpenSpec CLI sessions (",
172133
+ OPENSPEC_CLI_ACCEPTED_RANGE,
172134
+ ") once the CLI is detected."
172135
+ ]
172023
172136
  })
172024
172137
  });
172025
172138
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequirementDiffsSection, {
@@ -172027,7 +172140,9 @@ function ChangeDiffEvidence({ changeId, onChip }) {
172027
172140
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
172028
172141
  className: "text-muted-foreground",
172029
172142
  children: [
172030
- "Requirement diffs require an admitted OpenSpec CLI 1.11 session",
172143
+ "Requirement diffs require an admitted OpenSpec CLI session (",
172144
+ OPENSPEC_CLI_ACCEPTED_RANGE,
172145
+ ")",
172031
172146
  cli.version ? ` (detected ${cli.version.trim()})` : "",
172032
172147
  ". This session's CLI does not declare the `show --diff` capability, so the delta presentation keeps using the captured local content."
172033
172148
  ]
@@ -172062,11 +172177,11 @@ function ChangeDiffEvidence({ changeId, onChip }) {
172062
172177
  summary: "CLI diff evidence",
172063
172178
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172064
172179
  className: "text-muted-foreground",
172065
- children: "Requirement diff evidence from `show --diff` appears here on 1.11 sessions."
172180
+ children: "Requirement diff evidence from `show --diff` appears here on admitted CLI sessions."
172066
172181
  })
172067
172182
  });
172068
172183
  if (evidence.kind !== "executed") {
172069
- const detail = evidence.reason === "command-failed" ? evidence.detail : evidence.reason === "capability" ? "The detected OpenSpec CLI does not declare the 1.11 requirement-diff capability." : "The planning root is unavailable, so requirement-diff evidence cannot be fetched.";
172184
+ const detail = evidence.reason === "command-failed" ? evidence.detail : evidence.reason === "capability" ? "The detected OpenSpec CLI does not declare the requirement-diff capability." : "The planning root is unavailable, so requirement-diff evidence cannot be fetched.";
172070
172185
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequirementDiffsSection, {
172071
172186
  summary: "CLI evidence unavailable",
172072
172187
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -172149,6 +172264,7 @@ function ChangeDiffEvidence({ changeId, onChip }) {
172149
172264
  *
172150
172265
  * Original request (2026-08-03): use an Evidence tab to carry complete Change Detail information.
172151
172266
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
172267
+ * Owner walkthrough correction (2026-09-04): every Evidence detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding); this replaces each layer's local weak header.
172152
172268
  */
172153
172269
  /** Shared section frame for the Evidence workspace detail pane; keeps the a11y heading. */
172154
172270
  function WorkspaceSection({ id, title, summary, children, container = false }) {
@@ -172156,17 +172272,11 @@ function WorkspaceSection({ id, title, summary, children, container = false }) {
172156
172272
  "data-evidence-section": id,
172157
172273
  "aria-label": title,
172158
172274
  className: container ? "@container min-w-0" : "min-w-0",
172159
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
172160
- className: "border-border/60 flex min-w-0 flex-wrap items-baseline justify-between gap-x-3 gap-y-1 border-b pb-2",
172161
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
172162
- className: "min-w-0 text-xs font-semibold",
172163
- children: title
172164
- }), summary ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
172165
- className: "text-muted-foreground min-w-0 text-[11px]",
172166
- children: summary
172167
- }) : null]
172275
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
172276
+ title,
172277
+ summary
172168
172278
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
172169
- className: "min-w-0 pt-3 text-xs",
172279
+ className: "min-w-0 text-xs",
172170
172280
  children
172171
172281
  })]
172172
172282
  });
@@ -172454,20 +172564,502 @@ function EvidenceList({ label, values }) {
172454
172564
  });
172455
172565
  }
172456
172566
  //#endregion
172567
+ //#region src/components/validation-findings-evidence.tsx
172568
+ /**
172569
+ * Orthogonal intents (updated 2026-09-04 Asia/Shanghai):
172570
+ * 1. Present the OpenSpec 1.12 `validate --report findings` document as typed CLI evidence.
172571
+ * 2. Attribute every item finding to its owning change: entries owned by the current change
172572
+ * render as the primary "This change" list, while entries owned by other active changes
172573
+ * stay in a clearly-labeled secondary disclosure with prominent change attribution — a
172574
+ * finding never presents as this change's finding just because the scope is shared.
172575
+ * 3. Render INFO as a first-class informational class, distinct from warnings and errors.
172576
+ * 4. Show the filtered view honestly: `returnedItems` beside the preserved full-run totals,
172577
+ * labeled as filtered, never presented as the complete validation result. Scope-level
172578
+ * counts are never filtered to the current change.
172579
+ * 5. Gate the affordance behind the admitted line's `findingsReport` capability: non-admitted
172580
+ * sessions get no findings action; static snapshots state the evidence is unavailable.
172581
+ * 6. Validate transport and findings payloads with the Core contract schemas, never shallow
172582
+ * guards, and keep the CLI-owned request-error envelope on the direct plane.
172583
+ *
172584
+ * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
172585
+ * Owner walkthrough correction (2026-09-04): findings must attribute their owning change; the Evidence detail panel styling follows the vision review and every detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding) instead of a local weak header.
172586
+ */
172587
+ function parseFindingsPayload(value) {
172588
+ const parsed = CliValidateFindingsResultSchema.safeParse(value);
172589
+ if (parsed.success) return isCliValidateFindings(parsed.data) ? {
172590
+ kind: "findings",
172591
+ findings: parsed.data
172592
+ } : {
172593
+ kind: "request-failure",
172594
+ failure: parsed.data
172595
+ };
172596
+ const document = CliValidateFindingsSchema.safeParse(value);
172597
+ return {
172598
+ kind: "malformed",
172599
+ schemaIssues: (document.success ? parsed.error : document.error).issues.map((issue) => `${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`)
172600
+ };
172601
+ }
172602
+ /** Semantic level chip: box-radius geometry, distinct glyph per class, tinted never flooded. */
172603
+ var LEVEL_CHIP_CLASS = {
172604
+ INFO: "border-blue-600/40 bg-blue-500/5 text-blue-600 dark:text-blue-400",
172605
+ WARNING: "border-amber-600/40 bg-amber-500/5 text-amber-600 dark:text-amber-400",
172606
+ ERROR: "border-red-600/40 bg-red-500/5 text-red-600 dark:text-red-400"
172607
+ };
172608
+ var LEVEL_CHIP_GLYPH = {
172609
+ INFO: Info$1,
172610
+ WARNING: TriangleAlert,
172611
+ ERROR: OctagonAlert
172612
+ };
172613
+ function LevelChip({ level }) {
172614
+ const Glyph = LEVEL_CHIP_GLYPH[level];
172615
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
172616
+ "data-findings-level": level,
172617
+ className: `inline-flex shrink-0 items-center gap-1 border px-1.5 py-0.5 text-[11px] font-semibold uppercase tracking-wide ${LEVEL_CHIP_CLASS[level]}`,
172618
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Glyph, {
172619
+ className: "h-3 w-3",
172620
+ "aria-hidden": true
172621
+ }), level]
172622
+ });
172623
+ }
172624
+ /**
172625
+ * One findings item as a header/body card. Each issue owns a header row (level chip, issue
172626
+ * path, item identity) and a neutral message body; multiple issues stack as divided rows.
172627
+ * The message itself never carries the level color — the chip is the only color carrier.
172628
+ */
172629
+ function FindingCard({ item }) {
172630
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("article", {
172631
+ "data-findings-item": item.id,
172632
+ className: "border-border bg-card min-w-0 overflow-hidden rounded border",
172633
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
172634
+ className: "border-border/60 m-0 list-none divide-y p-0",
172635
+ children: item.issues.map((issue, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
172636
+ "data-findings-issue": issue.level,
172637
+ className: "min-w-0",
172638
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
172639
+ className: "border-border flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 border-b px-2.5 py-1.5",
172640
+ children: [
172641
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LevelChip, { level: issue.level }),
172642
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
172643
+ className: "text-foreground min-w-0 flex-1 basis-[6rem] font-mono text-xs [overflow-wrap:anywhere]",
172644
+ children: issue.path
172645
+ }),
172646
+ index === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
172647
+ className: "text-muted-foreground max-w-full shrink-0 text-right font-mono text-[11px] [overflow-wrap:anywhere]",
172648
+ children: [
172649
+ item.id,
172650
+ " · ",
172651
+ item.type,
172652
+ " · ",
172653
+ item.valid ? "valid" : "invalid"
172654
+ ]
172655
+ }) : null
172656
+ ]
172657
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172658
+ className: "text-foreground/90 px-2.5 py-2 text-xs leading-relaxed [overflow-wrap:anywhere]",
172659
+ children: issue.message
172660
+ })]
172661
+ }, index))
172662
+ })
172663
+ });
172664
+ }
172665
+ /** Compact count chip (box radius; pill geometry stays reserved for bare numeric counts). */
172666
+ function CountChip({ label, tone }) {
172667
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
172668
+ className: cn$1("inline-flex shrink-0 items-center rounded border px-1.5 py-0.5 text-xs font-medium", tone === "passed" && "border-emerald-600/40 bg-emerald-500/5 text-emerald-700 dark:text-emerald-400", tone === "failed" && "border-red-600/40 bg-red-500/5 text-red-600 dark:text-red-400", tone === "muted" && "border-border bg-muted/50 text-muted-foreground"),
172669
+ children: label
172670
+ });
172671
+ }
172672
+ function RunButton$1({ pending, label, onRun }) {
172673
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
172674
+ type: "button",
172675
+ onClick: onRun,
172676
+ disabled: pending,
172677
+ "aria-busy": pending || void 0,
172678
+ 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",
172679
+ children: [pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
172680
+ className: "h-3.5 w-3.5 animate-spin",
172681
+ "aria-hidden": true
172682
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCw, {
172683
+ className: "h-3.5 w-3.5 shrink-0",
172684
+ "aria-hidden": true
172685
+ }), label]
172686
+ });
172687
+ }
172688
+ /**
172689
+ * Structure-agnostic section frame for the Evidence workspace detail pane: heading plus
172690
+ * summary facts stay on the record; the workspace, not a disclosure, owns reveal behavior.
172691
+ * The header follows the workspace's one header contract: rule, baseline padding, margin.
172692
+ */
172693
+ function ValidationFindingsSection({ summary, children }) {
172694
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
172695
+ "data-evidence-section": "validation-findings",
172696
+ "aria-label": "Validation findings",
172697
+ className: "min-w-0",
172698
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
172699
+ title: "Validation findings",
172700
+ summary
172701
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
172702
+ className: "min-w-0 text-xs",
172703
+ children
172704
+ })]
172705
+ });
172706
+ }
172707
+ /**
172708
+ * On-demand, read-only validation findings evidence for the Change Evidence workspace.
172709
+ *
172710
+ * The findings report is a filtered view — only items with issues — over the same full-run
172711
+ * totals the complete validation report carries, so the section always presents
172712
+ * `returnedItems` beside the preserved totals and never claims to be the complete result.
172713
+ * The report covers the whole changes scope, so every item finding is attributed: the
172714
+ * current change's entries render as the primary list and other changes' entries stay in a
172715
+ * labeled secondary disclosure with the owning change id prominent.
172716
+ */
172717
+ function ValidationFindingsEvidence({ changeId, onChip }) {
172718
+ const [report, setReport] = (0, import_react.useState)(null);
172719
+ const [error, setError] = (0, import_react.useState)(null);
172720
+ const [pending, setPending] = (0, import_react.useState)(false);
172721
+ const cli = useRootActionState().context?.cli;
172722
+ const staticMode = isStaticMode();
172723
+ const capabilities = deriveOpenSpecCliCapabilities(cli?.available ? parseOpenSpecCliVersion(cli.version) : null);
172724
+ const chip = (0, import_react.useMemo)(() => {
172725
+ if (staticMode) return {
172726
+ label: "unavailable",
172727
+ tone: "unavailable"
172728
+ };
172729
+ if (cli?.available === true && !capabilities.findingsReport) return {
172730
+ label: "unavailable",
172731
+ tone: "unavailable"
172732
+ };
172733
+ if (!report && !error) return null;
172734
+ const parsed = report ? parseFindingsPayload(report.data) : null;
172735
+ if (error || !parsed || parsed.kind === "malformed") return {
172736
+ label: "fail",
172737
+ tone: "negative"
172738
+ };
172739
+ if (parsed.kind === "request-failure") return {
172740
+ label: "fail",
172741
+ tone: "negative"
172742
+ };
172743
+ const findings = parsed.findings;
172744
+ return findings.summary.totals.failed > 0 ? {
172745
+ label: `${findings.summary.totals.failed} failed`,
172746
+ tone: "negative"
172747
+ } : {
172748
+ label: `${findings.report.returnedItems} findings`,
172749
+ tone: "neutral"
172750
+ };
172751
+ }, [
172752
+ capabilities.findingsReport,
172753
+ cli?.available,
172754
+ error,
172755
+ report,
172756
+ staticMode
172757
+ ]);
172758
+ (0, import_react.useEffect)(() => {
172759
+ onChip?.(chip);
172760
+ }, [chip, onChip]);
172761
+ if (staticMode) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
172762
+ summary: "Unavailable in static snapshot",
172763
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172764
+ className: "text-muted-foreground",
172765
+ children: "Validation findings are live CLI evidence and are not captured in this static snapshot."
172766
+ })
172767
+ });
172768
+ if (cli?.available === true && !capabilities.findingsReport) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
172769
+ summary: "Unavailable on this CLI line",
172770
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
172771
+ className: "text-muted-foreground",
172772
+ children: [
172773
+ "Validation findings require the admitted OpenSpec CLI line (",
172774
+ OPENSPEC_CLI_ACCEPTED_RANGE,
172775
+ ")",
172776
+ cli.version ? ` (detected ${cli.version.trim()})` : "",
172777
+ ". This session's CLI does not declare the findings-report capability, so no command is offered."
172778
+ ]
172779
+ })
172780
+ });
172781
+ const run = async () => {
172782
+ setPending(true);
172783
+ setError(null);
172784
+ setReport(null);
172785
+ try {
172786
+ const result = await trpcClient.cli.validate.mutate({
172787
+ kind: "findings",
172788
+ scope: "changes"
172789
+ });
172790
+ const transport = CliCommandTransportSchema.safeParse(result);
172791
+ if (transport.success) setReport({
172792
+ ...transport.data,
172793
+ data: transport.data.data ?? null,
172794
+ payload: transport.data.payload ?? null
172795
+ });
172796
+ else setError("The validation findings transport returned an unrecognized result shape.");
172797
+ } catch (cause) {
172798
+ setError(cause instanceof Error ? cause.message : String(cause));
172799
+ } finally {
172800
+ setPending(false);
172801
+ }
172802
+ };
172803
+ if (!report && !error) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
172804
+ summary: "Not yet run",
172805
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
172806
+ className: "border-border bg-muted/20 max-w-[72ch] rounded-md border border-dashed p-6",
172807
+ children: pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172808
+ className: "flex items-center gap-2",
172809
+ role: "status",
172810
+ "data-findings-running": "",
172811
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
172812
+ className: "text-muted-foreground h-4 w-4 animate-spin",
172813
+ "aria-hidden": true
172814
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
172815
+ className: "text-xs font-medium",
172816
+ children: "Running findings report…"
172817
+ })]
172818
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172819
+ className: "space-y-3",
172820
+ children: [
172821
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172822
+ className: "text-xs font-semibold",
172823
+ children: "No findings loaded"
172824
+ }),
172825
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172826
+ className: "text-muted-foreground",
172827
+ children: "Load the official CLI's validation findings to see advisory issues reported for the active changes in this scope — including archive-merge advisories. This is read-only evidence; nothing is repaired from here."
172828
+ }),
172829
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {
172830
+ className: "border-border bg-muted rounded border px-1 py-0.5 font-mono text-[11px]",
172831
+ children: "openspec validate --report findings"
172832
+ }) }),
172833
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
172834
+ pending,
172835
+ label: "Load validation findings",
172836
+ onRun: () => void run()
172837
+ })
172838
+ ]
172839
+ })
172840
+ })
172841
+ });
172842
+ const parsed = report ? parseFindingsPayload(report.data) : null;
172843
+ if (error || !parsed || parsed.kind === "malformed") {
172844
+ const schemaDiagnostic = parsed?.kind === "malformed" && parsed.schemaIssues.length > 0 ? parsed.schemaIssues.join("; ") : null;
172845
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
172846
+ summary: "CLI failure evidence",
172847
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172848
+ className: "space-y-2",
172849
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172850
+ className: "text-destructive flex items-start gap-2 break-words",
172851
+ role: "alert",
172852
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
172853
+ className: "mt-0.5 h-3.5 w-3.5 shrink-0",
172854
+ "aria-hidden": true
172855
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
172856
+ className: "min-w-0 [overflow-wrap:anywhere]",
172857
+ children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The validation findings command failed."
172858
+ })]
172859
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
172860
+ pending,
172861
+ label: "Rerun",
172862
+ onRun: () => void run()
172863
+ })]
172864
+ })
172865
+ });
172866
+ }
172867
+ if (parsed.kind === "request-failure") {
172868
+ const entries = parsed.failure.status;
172869
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
172870
+ summary: "CLI request failure",
172871
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172872
+ className: "space-y-2",
172873
+ children: [
172874
+ entries.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172875
+ "data-findings-request-error": entry.code,
172876
+ className: "text-destructive flex items-start gap-2 break-words",
172877
+ role: "alert",
172878
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
172879
+ className: "mt-0.5 h-3.5 w-3.5 shrink-0",
172880
+ "aria-hidden": true
172881
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
172882
+ className: "min-w-0 [overflow-wrap:anywhere]",
172883
+ children: [
172884
+ entry.code,
172885
+ ": ",
172886
+ entry.message
172887
+ ]
172888
+ })]
172889
+ }, index)),
172890
+ entries.some((entry) => entry.fix !== void 0) ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
172891
+ className: "break-words",
172892
+ "data-findings-request-fix": true,
172893
+ children: ["CLI fix suggestion: ", entries.find((entry) => entry.fix !== void 0)?.fix]
172894
+ }) : null,
172895
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
172896
+ pending,
172897
+ label: "Rerun",
172898
+ onRun: () => void run()
172899
+ })
172900
+ ]
172901
+ })
172902
+ });
172903
+ }
172904
+ const findings = parsed.findings;
172905
+ const totals = findings.summary.totals;
172906
+ const ownFindings = findings.itemFindings.filter((item) => item.id === changeId);
172907
+ const otherFindings = findings.itemFindings.filter((item) => item.id !== changeId);
172908
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
172909
+ summary: `Filtered view · ${findings.report.returnedItems} of ${findings.report.totalItems} items with findings`,
172910
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172911
+ className: "space-y-3",
172912
+ children: [
172913
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172914
+ className: "text-muted-foreground",
172915
+ "data-findings-filtered-note": true,
172916
+ children: "Filtered CLI evidence: only items that reported issues are listed. The complete validation result remains the full report; totals below are the full-run values the CLI preserved."
172917
+ }),
172918
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
172919
+ "data-findings-provenance": "",
172920
+ className: "@[28rem]:grid-cols-[150px_1fr] grid min-w-0 grid-cols-1 gap-x-3 gap-y-1",
172921
+ children: [
172922
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
172923
+ className: "text-muted-foreground",
172924
+ children: "Root"
172925
+ }),
172926
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
172927
+ className: "min-w-0 font-mono text-xs [overflow-wrap:anywhere]",
172928
+ children: findings.root.path
172929
+ }),
172930
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
172931
+ className: "text-muted-foreground",
172932
+ children: "Exit status"
172933
+ }),
172934
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
172935
+ className: "min-w-0 font-mono text-xs",
172936
+ children: report?.exitCode === null || report?.exitCode === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
172937
+ className: "text-muted-foreground",
172938
+ children: "—"
172939
+ }) : report.exitCode
172940
+ }),
172941
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
172942
+ className: "text-muted-foreground",
172943
+ children: "Items with findings"
172944
+ }),
172945
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dd", {
172946
+ className: "min-w-0 font-mono text-xs",
172947
+ children: [
172948
+ findings.report.returnedItems,
172949
+ " of ",
172950
+ findings.report.totalItems,
172951
+ " (",
172952
+ findings.report.scope,
172953
+ " ",
172954
+ "scope)"
172955
+ ]
172956
+ })
172957
+ ]
172958
+ }),
172959
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172960
+ className: "space-y-1.5",
172961
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
172962
+ className: "text-muted-foreground text-[11px]",
172963
+ children: "Full-run totals"
172964
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172965
+ className: "flex flex-wrap gap-1.5",
172966
+ "data-findings-totals": "",
172967
+ children: [
172968
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountChip, {
172969
+ label: `${totals.passed} passed`,
172970
+ tone: "passed"
172971
+ }),
172972
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountChip, {
172973
+ label: `${totals.failed} failed`,
172974
+ tone: totals.failed > 0 ? "failed" : "muted"
172975
+ }),
172976
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountChip, {
172977
+ label: `${totals.items} items`,
172978
+ tone: "muted"
172979
+ })
172980
+ ]
172981
+ })]
172982
+ }),
172983
+ findings.itemFindings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172984
+ className: "text-muted-foreground",
172985
+ children: "No item in this scope reported an issue. This filtered view lists issues only — it is not the complete validation result."
172986
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
172987
+ className: "space-y-2",
172988
+ "data-findings-own": "",
172989
+ children: [
172990
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", {
172991
+ className: "text-xs font-semibold",
172992
+ children: "This change"
172993
+ }),
172994
+ ownFindings.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FindingCard, { item }, item.id)),
172995
+ ownFindings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172996
+ className: "text-muted-foreground",
172997
+ "data-findings-own-empty": "",
172998
+ children: "No findings for this change in the filtered scope. Other entries below belong to other active changes."
172999
+ }) : null
173000
+ ]
173001
+ }), otherFindings.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", {
173002
+ "data-findings-other": "",
173003
+ className: "border-border rounded border",
173004
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", {
173005
+ className: "cursor-pointer select-none px-2.5 py-2 text-xs font-medium",
173006
+ children: [
173007
+ "Findings from other active changes (",
173008
+ otherFindings.length,
173009
+ ")"
173010
+ ]
173011
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
173012
+ className: "border-border space-y-3 border-t px-2.5 py-2.5",
173013
+ children: otherFindings.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
173014
+ className: "min-w-0 space-y-1",
173015
+ "data-findings-other-item": "",
173016
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
173017
+ className: "text-foreground font-mono text-xs font-medium",
173018
+ children: item.id
173019
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FindingCard, { item })]
173020
+ }, item.id))
173021
+ })]
173022
+ }) : null] }),
173023
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("footer", {
173024
+ className: "border-border mt-4 flex flex-wrap items-center justify-between gap-x-4 gap-y-2 border-t pt-3",
173025
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
173026
+ className: "text-muted-foreground font-mono text-[11px] [overflow-wrap:anywhere]",
173027
+ children: [
173028
+ "openspec validate --report findings · ",
173029
+ findings.report.scope,
173030
+ " scope"
173031
+ ]
173032
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
173033
+ pending,
173034
+ label: "Rerun",
173035
+ onRun: () => void run()
173036
+ })]
173037
+ })
173038
+ ]
173039
+ })
173040
+ });
173041
+ }
173042
+ //#endregion
172457
173043
  //#region src/components/evidence-workspace.tsx
172458
173044
  /**
172459
- * Orthogonal intents (created 2026-08-28 Asia/Shanghai):
173045
+ * Orthogonal intents (updated 2026-09-04 Asia/Shanghai):
172460
173046
  * 1. Own the Change Evidence tab's container-responsive list-detail workspace topology.
172461
173047
  * 2. Preserve the decision-plane evidence layer order (summary/paths -> requirement diffs ->
172462
- * archived validation -> CLI/raw payload) in keyboard-reachable list rows.
173048
+ * validation findings -> archived validation -> CLI/raw payload) in keyboard-reachable
173049
+ * list rows.
172463
173050
  * 3. Derive row chips only from settled section facts; never fabricate counts or verdicts.
172464
173051
  * 4. Keep the crowded drill presentational: the detail replaces the list with a back
172465
173052
  * affordance, and back restores the list without unmounting settled evidence; focus
172466
173053
  * follows the drill (row -> back affordance -> originating row) so keyboard users never
172467
173054
  * land on a hidden element.
172468
173055
  * 5. Keep sub-selection local runtime state — it never enters routes or browser storage.
173056
+ * 6. Separate the workspace planes visually: the list column is the muted rail and the
173057
+ * detail column is the card surface; detail prose caps its measure, and only the
173058
+ * selected row ever carries a row fill.
172469
173059
  *
172470
173060
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
173061
+ * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
173062
+ * Owner walkthrough correction (2026-09-04): findings must attribute their owning change; the Evidence detail panel styling follows the vision review and every detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding) instead of a local weak header.
172471
173063
  */
172472
173064
  /**
172473
173065
  * Spacious threshold: below this inline size the workspace collapses to one column and the
@@ -172518,10 +173110,14 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
172518
173110
  const pendingRestoreRowId = (0, import_react.useRef)(null);
172519
173111
  const backHadFocus = (0, import_react.useRef)(false);
172520
173112
  const [diffChip, setDiffChip] = (0, import_react.useState)(null);
173113
+ const [findingsChip, setFindingsChip] = (0, import_react.useState)(null);
172521
173114
  const [validationChip, setValidationChip] = (0, import_react.useState)(null);
172522
173115
  const handleDiffChip = (0, import_react.useCallback)((chip) => {
172523
173116
  setDiffChip(chip);
172524
173117
  }, []);
173118
+ const handleFindingsChip = (0, import_react.useCallback)((chip) => {
173119
+ setFindingsChip(chip);
173120
+ }, []);
172525
173121
  const handleValidationChip = (0, import_react.useCallback)((chip) => {
172526
173122
  setValidationChip(chip);
172527
173123
  }, []);
@@ -172549,6 +173145,15 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
172549
173145
  onChip: handleDiffChip
172550
173146
  })
172551
173147
  },
173148
+ {
173149
+ id: "validation-findings",
173150
+ label: "Validation findings",
173151
+ chip: findingsChip,
173152
+ content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsEvidence, {
173153
+ changeId,
173154
+ onChip: handleFindingsChip
173155
+ })
173156
+ },
172552
173157
  {
172553
173158
  id: "archived-validation",
172554
173159
  label: "Archived validation",
@@ -172560,7 +173165,9 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
172560
173165
  }, [
172561
173166
  changeId,
172562
173167
  diffChip,
173168
+ findingsChip,
172563
173169
  handleDiffChip,
173170
+ handleFindingsChip,
172564
173171
  handleValidationChip,
172565
173172
  referenceEvidence,
172566
173173
  status,
@@ -172608,7 +173215,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
172608
173215
  "aria-label": "Evidence sections",
172609
173216
  "data-evidence-pane": "list",
172610
173217
  hidden: !showList || void 0,
172611
- className: cn$1("scrollbar-thin scrollbar-track-transparent border-border/60 @[40rem]:border-r min-h-0 min-w-0 overflow-y-auto overflow-x-hidden overscroll-contain", !showList && "hidden"),
173218
+ className: cn$1("scrollbar-thin scrollbar-track-transparent bg-muted/40 border-border @[40rem]:border-r min-h-0 min-w-0 overflow-y-auto overflow-x-hidden overscroll-contain", !showList && "hidden"),
172612
173219
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
172613
173220
  className: "divide-border/20 m-0 list-none divide-y p-0",
172614
173221
  children: sections.map((section) => {
@@ -172639,7 +173246,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
172639
173246
  "data-evidence-pane": "detail",
172640
173247
  "data-change-evidence-scroll-owner": "",
172641
173248
  hidden: !showDetail || void 0,
172642
- className: cn$1("scrollbar-thin scrollbar-track-transparent min-h-0 min-w-0 overflow-y-auto overflow-x-hidden overscroll-contain", showDetail ? "flex flex-col" : "hidden"),
173249
+ className: cn$1("scrollbar-thin scrollbar-track-transparent bg-card min-h-0 min-w-0 overflow-y-auto overflow-x-hidden overscroll-contain", showDetail ? "flex flex-col" : "hidden"),
172643
173250
  children: [!spacious && drilled ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
172644
173251
  ref: backRef,
172645
173252
  type: "button",
@@ -172652,7 +173259,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
172652
173259
  backHadFocus.current = false;
172653
173260
  },
172654
173261
  onClick: backToList,
172655
- className: "bg-background/95 border-border/60 text-muted-foreground hover:text-foreground focus-visible:ring-primary sticky top-0 z-10 flex min-h-9 w-full min-w-0 items-center gap-1.5 border-b px-3 text-xs outline-none backdrop-blur focus-visible:ring-2 focus-visible:ring-inset",
173262
+ className: "bg-card/95 border-border/60 text-muted-foreground hover:text-foreground focus-visible:ring-primary sticky top-0 z-10 flex min-h-9 w-full min-w-0 items-center gap-1.5 border-b px-3 text-xs outline-none backdrop-blur focus-visible:ring-2 focus-visible:ring-inset",
172656
173263
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, {
172657
173264
  className: "h-3.5 w-3.5 shrink-0",
172658
173265
  "aria-hidden": true
@@ -172660,7 +173267,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
172660
173267
  }) : null, sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
172661
173268
  "data-evidence-detail": section.id,
172662
173269
  hidden: section.id !== activeSection.id,
172663
- className: "min-w-0 px-4 pb-4",
173270
+ className: "min-w-0 px-4 pb-6 pt-3 [&_p]:max-w-[88ch]",
172664
173271
  children: section.content
172665
173272
  }, section.id))]
172666
173273
  })]
@@ -172919,7 +173526,8 @@ function RootActionNotice({ state }) {
172919
173526
  * Owner correction (2026-08-03): move Actions inline with the title, unify subtitle badges, and localize unavailable Tooltips.
172920
173527
  * Original request (2026-08-15): 刷新/解析中状态收敛为副标题行内的 shiny 徽章,不再占据 statusRegion 块。
172921
173528
  * Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。" — the Evidence
172922
- * tab gains the 1.11-gated CLI MODIFIED-delta diff evidence beside the existing layers.
173529
+ * tab gains the capability-gated CLI MODIFIED-delta diff evidence beside the existing layers.
173530
+ * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进" — the Evidence tab gains the findings evidence section.
172923
173531
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
172924
173532
  */
172925
173533
  function ChangeView() {
@@ -173116,7 +173724,7 @@ var CONFIG_GUIDE_STAGE_META = {
173116
173724
  //#region src/components/config/config-guide.tsx
173117
173725
  var ConfigGuideContext = (0, import_react.createContext)(null);
173118
173726
  (0, import_react.lazy)(async () => {
173119
- return { default: (await import("./config-guide-presentation-D921NMVc.js")).ConfigGuidePresentationLayer };
173727
+ return { default: (await import("./config-guide-presentation-GWnVFKTW.js")).ConfigGuidePresentationLayer };
173120
173728
  });
173121
173729
  /** Access the root-owned adaptive Guide runtime. */
173122
173730
  function useConfigGuide() {