@openspecui/web 12.0.0 → 13.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 (69) hide show
  1. package/dist/assets/{App-BagQkLCd.css → App-CYwWbLgm.css} +1 -1
  2. package/dist/assets/{App-Dmag08k5.js → App-Cq2vfNv0.js} +153 -153
  3. package/dist/assets/{main-DXjJbv3-.js → main-CjHLYXqj.js} +2 -2
  4. package/dist/assets/{trpc-CENMN-Kx.js → trpc-BJDrN6rb.js} +1 -1
  5. package/dist/index.html +1 -1
  6. package/dist-ssg/client/.vite/ssr-manifest.json +49 -29
  7. package/dist-ssg/client/assets/CanvasRenderer-BAnUeHzl.js +1 -0
  8. package/dist-ssg/client/assets/WebGLRenderer-DehTnF66.js +1 -0
  9. package/dist-ssg/client/assets/WebGPURenderer-BCXAr50t.js +1 -0
  10. package/dist-ssg/client/assets/browserAll-Brx8TmCT.js +1 -0
  11. package/dist-ssg/client/assets/{config-guide-presentation-GtsojPuN.js → config-guide-presentation-BYWAVHG-.js} +1 -1
  12. package/dist-ssg/client/assets/{dist-DHkPjBBo.js → dist-B014oKqB.js} +1 -1
  13. package/dist-ssg/client/assets/{dist-BxTQbErr.js → dist-B7XysJsL.js} +1 -1
  14. package/dist-ssg/client/assets/dist-BKcEPt5U.js +1 -0
  15. package/dist-ssg/client/assets/dist-BZVFJHY_.js +1 -0
  16. package/dist-ssg/client/assets/{dist-B0xIEOgo.js → dist-CT1adEON.js} +1 -1
  17. package/dist-ssg/client/assets/{dist-BAP9yhhm.js → dist-DBbVV3c6.js} +1 -1
  18. package/dist-ssg/client/assets/{dist-CI3zBObR.js → dist-DFWGpO_L.js} +1 -1
  19. package/dist-ssg/client/assets/{dist-Cgf7W726.js → dist-DUzLJ7IR.js} +1 -1
  20. package/dist-ssg/client/assets/{dist-CJOMMo-D.js → dist-DtpQCgKd.js} +1 -1
  21. package/dist-ssg/client/assets/{dist-C7lTRiju.js → dist-DvnWUGiW.js} +1 -1
  22. package/dist-ssg/client/assets/{dist-Df3fSUJ8.js → dist-PNypP3x_.js} +1 -1
  23. package/dist-ssg/client/assets/dist-qdJFVZmv.js +1 -0
  24. package/dist-ssg/client/assets/{ghostty-web-VZE4TZBO.js → ghostty-web-DSqlIAa4.js} +1 -1
  25. package/dist-ssg/client/assets/{index-CS0xsSqt.css → index-CMfi0IZJ.css} +1 -1
  26. package/dist-ssg/client/assets/{index.ssg-m0qZ-Tbv.js → index.ssg-CJP1DN4-.js} +125 -125
  27. package/dist-ssg/client/assets/{init-0qJSx79q.js → init-ORkrPTI8.js} +1 -1
  28. package/dist-ssg/client/assets/{trpc-D4bSp4J9.js → trpc-DimmQX0m.js} +1 -1
  29. package/dist-ssg/client/assets/webworkerAll-DjsDtAjh.js +1 -0
  30. package/dist-ssg/client/index.ssg.html +2 -2
  31. package/dist-ssg/server/assets/CanvasRenderer-CvVvHnla.js +3 -0
  32. package/dist-ssg/server/assets/WebGLRenderer-ZTMKqKjr.js +3 -0
  33. package/dist-ssg/server/assets/WebGPURenderer-BaTRp8M6.js +3 -0
  34. package/dist-ssg/server/assets/{browserAll-Da2y8ybl.js → browserAll-BoaMSEnC.js} +2 -2
  35. package/dist-ssg/server/assets/{config-guide-presentation-GWnVFKTW.js → config-guide-presentation-B5oRLCcX.js} +1 -1
  36. package/dist-ssg/server/assets/{dist-CRw-jyve.js → dist-BTp4dJw4.js} +1 -1
  37. package/dist-ssg/server/assets/{dist-D3Ubfaie.js → dist-Bi2hyX2D.js} +1 -1
  38. package/dist-ssg/server/assets/{dist-dHhPmrtl.js → dist-C4EXY8oH.js} +1 -1
  39. package/dist-ssg/server/assets/{dist-CmE7gK9r.js → dist-CHiBYKhO.js} +1 -1
  40. package/dist-ssg/server/assets/dist-CIVGOe5c.js +3 -0
  41. package/dist-ssg/server/assets/{dist-DHhdkqG1.js → dist-CLOFOKCn.js} +1 -1
  42. package/dist-ssg/server/assets/{dist-QLG95fVW.js → dist-CUmPwPDw.js} +1 -1
  43. package/dist-ssg/server/assets/dist-DAIXBI5T.js +3 -0
  44. package/dist-ssg/server/assets/{dist-C8mczL_o.js → dist-DQpyDhfS.js} +1 -1
  45. package/dist-ssg/server/assets/{dist-Bk9be2-W.js → dist-DVnu9zoA.js} +1 -1
  46. package/dist-ssg/server/assets/{dist-A6g9ScYS.js → dist-D_mnjXV3.js} +1 -1
  47. package/dist-ssg/server/assets/dist-fy1m8mbf.js +3 -0
  48. package/dist-ssg/server/assets/{entry-server-B1byBTHL.js → entry-server-CXwaLjrK.js} +268 -82
  49. package/dist-ssg/server/assets/{init-BCpyot27.js → init-B1eN597N.js} +1 -1
  50. package/dist-ssg/server/assets/trpc-BQ6eyI7t.js +3 -0
  51. package/dist-ssg/server/assets/webworkerAll-bAKoC1FD.js +4 -0
  52. package/dist-ssg/server/ssr-entry-manifest.json +24 -24
  53. package/package.json +3 -3
  54. package/dist-ssg/client/assets/CanvasRenderer-B3YNEZKU.js +0 -1
  55. package/dist-ssg/client/assets/WebGLRenderer-91FdO4XE.js +0 -1
  56. package/dist-ssg/client/assets/WebGPURenderer-BcSREi3g.js +0 -1
  57. package/dist-ssg/client/assets/browserAll-CRvGxmXW.js +0 -1
  58. package/dist-ssg/client/assets/dist-Bsojfco7.js +0 -1
  59. package/dist-ssg/client/assets/dist-fJz8f69P.js +0 -1
  60. package/dist-ssg/client/assets/dist-we8a11kz.js +0 -1
  61. package/dist-ssg/client/assets/webworkerAll-BUpVAcIt.js +0 -1
  62. package/dist-ssg/server/assets/CanvasRenderer-eDcOd6Sl.js +0 -3
  63. package/dist-ssg/server/assets/WebGLRenderer-BYGgdFoJ.js +0 -3
  64. package/dist-ssg/server/assets/WebGPURenderer-CS5mt9ch.js +0 -3
  65. package/dist-ssg/server/assets/dist-C8ZGbZgL.js +0 -3
  66. package/dist-ssg/server/assets/dist-D2ilXjzO.js +0 -3
  67. package/dist-ssg/server/assets/dist-DbHDr3r9.js +0 -3
  68. package/dist-ssg/server/assets/trpc-D5UIUAYV.js +0 -3
  69. package/dist-ssg/server/assets/webworkerAll-Dg825OUg.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-D5UIUAYV.js");
30911
+ const { trpcClient } = await import("./trpc-BQ6eyI7t.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-D5UIUAYV.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31054
+ import("./trpc-BQ6eyI7t.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31055
31055
  key: this.storageKey,
31056
31056
  value: {
31057
31057
  mainTabs: this.state.mainTabs,
@@ -39116,6 +39116,8 @@ unionType([objectType({
39116
39116
  "ready"
39117
39117
  ]),
39118
39118
  missingArtifacts: arrayType(stringType()).optional(),
39119
+ missingPrerequisites: arrayType(stringType()).optional(),
39120
+ warnings: arrayType(stringType()).optional(),
39119
39121
  instruction: stringType(),
39120
39122
  references: arrayType(CliReferenceIndexEntrySchema).optional(),
39121
39123
  context: stringType().optional(),
@@ -43343,15 +43345,19 @@ function createApplyInstructionProgress(input, trackedTaskProgress) {
43343
43345
  //#endregion
43344
43346
  //#region ../core/src/opsx-types.ts
43345
43347
  /**
43346
- * Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
43348
+ * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
43347
43349
  * 1. Publish runtime schemas for final Projection Work payloads, including transformed Apply progress.
43348
43350
  * 2. Keep isPlanningComplete as the authoritative planning fact over any local tracked alias.
43349
43351
  * 3. Carry CLI status evidence, diagnostics, and per-artifact requires as typed facts.
43350
43352
  * 4. Preserve root-context and store projections as browser-safe contracts.
43351
43353
  * 5. Keep projection notices distinct from payload data so failures never masquerade as results.
43354
+ * 6. Project the OpenSpec 1.13 Apply `warnings` and `missingPrerequisites` fields through the
43355
+ * input and final projection schemas verbatim: optional everywhere, never defaulted to
43356
+ * empty arrays, and never allowed to alter state/progress/tasks semantics.
43352
43357
  *
43353
43358
  * Original request (2026-07-15): "为内核载荷建立强类型。"
43354
43359
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
43360
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
43355
43361
  */
43356
43362
  /** Runtime schema for one JSON value retained from a CLI Status stdout document. */
43357
43363
  var OpsxCliJsonValueSchema = lazyType(() => unionType([
@@ -43445,6 +43451,8 @@ var ApplyInstructionsInputSchema = objectType({
43445
43451
  "ready"
43446
43452
  ]),
43447
43453
  missingArtifacts: arrayType(stringType()).optional(),
43454
+ missingPrerequisites: arrayType(stringType()).optional(),
43455
+ warnings: arrayType(stringType()).optional(),
43448
43456
  instruction: stringType(),
43449
43457
  references: arrayType(CliReferenceIndexEntrySchema).optional(),
43450
43458
  context: stringType().optional(),
@@ -43494,6 +43502,8 @@ var ApplyInstructionsProjectionSchema = objectType({
43494
43502
  "ready"
43495
43503
  ]),
43496
43504
  missingArtifacts: arrayType(stringType()).optional(),
43505
+ missingPrerequisites: arrayType(stringType()).optional(),
43506
+ warnings: arrayType(stringType()).optional(),
43497
43507
  instruction: stringType(),
43498
43508
  references: arrayType(CliReferenceIndexEntrySchema).optional(),
43499
43509
  context: stringType().optional(),
@@ -46966,6 +46976,32 @@ var ListChecks = createLucideIcon("ListChecks", [
46966
46976
  key: "oe0vm4"
46967
46977
  }]
46968
46978
  ]);
46979
+ var ListOrdered = createLucideIcon("ListOrdered", [
46980
+ ["path", {
46981
+ d: "M10 12h11",
46982
+ key: "6m4ad9"
46983
+ }],
46984
+ ["path", {
46985
+ d: "M10 18h11",
46986
+ key: "11hvi2"
46987
+ }],
46988
+ ["path", {
46989
+ d: "M10 6h11",
46990
+ key: "c7qv1k"
46991
+ }],
46992
+ ["path", {
46993
+ d: "M4 10h2",
46994
+ key: "16xx2s"
46995
+ }],
46996
+ ["path", {
46997
+ d: "M4 6h1v4",
46998
+ key: "cnovpq"
46999
+ }],
47000
+ ["path", {
47001
+ d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1",
47002
+ key: "m9a95d"
47003
+ }]
47004
+ ]);
46969
47005
  var ListTodo = createLucideIcon("ListTodo", [
46970
47006
  ["rect", {
46971
47007
  x: "3",
@@ -71280,7 +71316,7 @@ var browserExt = {
71280
71316
  },
71281
71317
  test: () => true,
71282
71318
  load: async () => {
71283
- await import("./browserAll-Da2y8ybl.js");
71319
+ await import("./browserAll-BoaMSEnC.js");
71284
71320
  }
71285
71321
  };
71286
71322
  //#endregion
@@ -71293,7 +71329,7 @@ var webworkerExt = {
71293
71329
  },
71294
71330
  test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
71295
71331
  load: async () => {
71296
- await import("./webworkerAll-Dg825OUg.js");
71332
+ await import("./webworkerAll-bAKoC1FD.js");
71297
71333
  }
71298
71334
  };
71299
71335
  //#endregion
@@ -73887,7 +73923,7 @@ async function autoDetectRenderer(options) {
73887
73923
  for (let i = 0; i < preferredOrder.length; i++) {
73888
73924
  const rendererType = preferredOrder[i];
73889
73925
  if (rendererType === "webgpu" && await isWebGPUSupported()) {
73890
- const { WebGPURenderer } = await import("./WebGPURenderer-CS5mt9ch.js");
73926
+ const { WebGPURenderer } = await import("./WebGPURenderer-BaTRp8M6.js");
73891
73927
  RendererClass = WebGPURenderer;
73892
73928
  finalOptions = {
73893
73929
  ...options,
@@ -73895,7 +73931,7 @@ async function autoDetectRenderer(options) {
73895
73931
  };
73896
73932
  break;
73897
73933
  } else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
73898
- const { WebGLRenderer } = await import("./WebGLRenderer-BYGgdFoJ.js");
73934
+ const { WebGLRenderer } = await import("./WebGLRenderer-ZTMKqKjr.js");
73899
73935
  RendererClass = WebGLRenderer;
73900
73936
  finalOptions = {
73901
73937
  ...options,
@@ -73903,7 +73939,7 @@ async function autoDetectRenderer(options) {
73903
73939
  };
73904
73940
  break;
73905
73941
  } else if (rendererType === "canvas") {
73906
- const { CanvasRenderer } = await import("./CanvasRenderer-eDcOd6Sl.js");
73942
+ const { CanvasRenderer } = await import("./CanvasRenderer-CvVvHnla.js");
73907
73943
  RendererClass = CanvasRenderer;
73908
73944
  finalOptions = {
73909
73945
  ...options,
@@ -97652,7 +97688,7 @@ var TerminalController = class {
97652
97688
  if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
97653
97689
  this.configPersistTimer = setTimeout(() => {
97654
97690
  this.configPersistTimer = null;
97655
- import("./trpc-D5UIUAYV.js").then(({ trpcClient }) => {
97691
+ import("./trpc-BQ6eyI7t.js").then(({ trpcClient }) => {
97656
97692
  trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
97657
97693
  }).catch(() => {});
97658
97694
  }, CONFIG_PERSIST_DEBOUNCE);
@@ -108213,7 +108249,7 @@ var languages = [
108213
108249
  name: "CSS",
108214
108250
  extensions: ["css"],
108215
108251
  load() {
108216
- return import("./dist-C8ZGbZgL.js").then((m) => m.css());
108252
+ return import("./dist-fy1m8mbf.js").then((m) => m.css());
108217
108253
  }
108218
108254
  }),
108219
108255
  /* @__PURE__ */ LanguageDescription.of({
@@ -108233,7 +108269,7 @@ var languages = [
108233
108269
  "hbs"
108234
108270
  ],
108235
108271
  load() {
108236
- return import("./dist-dHhPmrtl.js").then((m) => m.html());
108272
+ return import("./dist-C4EXY8oH.js").then((m) => m.html());
108237
108273
  }
108238
108274
  }),
108239
108275
  /* @__PURE__ */ LanguageDescription.of({
@@ -108267,7 +108303,7 @@ var languages = [
108267
108303
  "jinja2"
108268
108304
  ],
108269
108305
  load() {
108270
- return import("./dist-CRw-jyve.js").then((m) => m.jinja());
108306
+ return import("./dist-BTp4dJw4.js").then((m) => m.jinja());
108271
108307
  }
108272
108308
  }),
108273
108309
  /* @__PURE__ */ LanguageDescription.of({
@@ -108275,7 +108311,7 @@ var languages = [
108275
108311
  alias: ["json5"],
108276
108312
  extensions: ["json", "map"],
108277
108313
  load() {
108278
- return import("./dist-D2ilXjzO.js").then((m) => m.json());
108314
+ return import("./dist-DAIXBI5T.js").then((m) => m.json());
108279
108315
  }
108280
108316
  }),
108281
108317
  /* @__PURE__ */ LanguageDescription.of({
@@ -108289,14 +108325,14 @@ var languages = [
108289
108325
  name: "LESS",
108290
108326
  extensions: ["less"],
108291
108327
  load() {
108292
- return import("./dist-C8mczL_o.js").then((m) => m.less());
108328
+ return import("./dist-DQpyDhfS.js").then((m) => m.less());
108293
108329
  }
108294
108330
  }),
108295
108331
  /* @__PURE__ */ LanguageDescription.of({
108296
108332
  name: "Liquid",
108297
108333
  extensions: ["liquid"],
108298
108334
  load() {
108299
- return import("./dist-CmE7gK9r.js").then((m) => m.liquid());
108335
+ return import("./dist-CHiBYKhO.js").then((m) => m.liquid());
108300
108336
  }
108301
108337
  }),
108302
108338
  /* @__PURE__ */ LanguageDescription.of({
@@ -108313,7 +108349,7 @@ var languages = [
108313
108349
  "mkd"
108314
108350
  ],
108315
108351
  load() {
108316
- return import("./dist-Bk9be2-W.js").then((m) => m.markdown());
108352
+ return import("./dist-DVnu9zoA.js").then((m) => m.markdown());
108317
108353
  }
108318
108354
  }),
108319
108355
  /* @__PURE__ */ LanguageDescription.of({
@@ -108339,7 +108375,7 @@ var languages = [
108339
108375
  "phtml"
108340
108376
  ],
108341
108377
  load() {
108342
- return import("./dist-QLG95fVW.js").then((m) => m.php());
108378
+ return import("./dist-CUmPwPDw.js").then((m) => m.php());
108343
108379
  }
108344
108380
  }),
108345
108381
  /* @__PURE__ */ LanguageDescription.of({
@@ -108379,14 +108415,14 @@ var languages = [
108379
108415
  name: "Sass",
108380
108416
  extensions: ["sass"],
108381
108417
  load() {
108382
- return import("./dist-D3Ubfaie.js").then((m) => m.sass({ indented: true }));
108418
+ return import("./dist-Bi2hyX2D.js").then((m) => m.sass({ indented: true }));
108383
108419
  }
108384
108420
  }),
108385
108421
  /* @__PURE__ */ LanguageDescription.of({
108386
108422
  name: "SCSS",
108387
108423
  extensions: ["scss"],
108388
108424
  load() {
108389
- return import("./dist-D3Ubfaie.js").then((m) => m.sass());
108425
+ return import("./dist-Bi2hyX2D.js").then((m) => m.sass());
108390
108426
  }
108391
108427
  }),
108392
108428
  /* @__PURE__ */ LanguageDescription.of({
@@ -108453,7 +108489,7 @@ var languages = [
108453
108489
  alias: ["yml"],
108454
108490
  extensions: ["yaml", "yml"],
108455
108491
  load() {
108456
- return import("./dist-DbHDr3r9.js").then((m) => m.yaml());
108492
+ return import("./dist-CIVGOe5c.js").then((m) => m.yaml());
108457
108493
  }
108458
108494
  }),
108459
108495
  /* @__PURE__ */ LanguageDescription.of({
@@ -109340,13 +109376,13 @@ var languages = [
109340
109376
  name: "Vue",
109341
109377
  extensions: ["vue"],
109342
109378
  load() {
109343
- return import("./dist-A6g9ScYS.js").then((m) => m.vue());
109379
+ return import("./dist-D_mnjXV3.js").then((m) => m.vue());
109344
109380
  }
109345
109381
  }),
109346
109382
  /* @__PURE__ */ LanguageDescription.of({
109347
109383
  name: "Angular Template",
109348
109384
  load() {
109349
- return import("./dist-DHhdkqG1.js").then((m) => m.angular());
109385
+ return import("./dist-CLOFOKCn.js").then((m) => m.angular());
109350
109386
  }
109351
109387
  })
109352
109388
  ];
@@ -170058,6 +170094,36 @@ function ChangeRowChevron() {
170058
170094
  });
170059
170095
  }
170060
170096
  //#endregion
170097
+ //#region src/lib/change-display-title.ts
170098
+ /**
170099
+ * Orthogonal intents (created 2026-09-12 Asia/Shanghai):
170100
+ * 1. Derive one shared display title for a Change across list, dashboard, and detail surfaces.
170101
+ * 2. Treat the proposal H1 as a human-readable title only when it is informative.
170102
+ * 3. Fall back to the change id (the CLI's own canonical name) otherwise.
170103
+ *
170104
+ * Original request (2026-09-12): Owner walkthrough: the Changes list showed the generic proposal
170105
+ * heading "Proposal" as the row title while Change Detail showed the change id — unify the scheme.
170106
+ */
170107
+ /**
170108
+ * Heading texts that carry no identity information. `openspec new change` scaffolds proposals with
170109
+ * the bare heading "# Proposal"; showing it as a row title reads as a parsing bug rather than a name.
170110
+ */
170111
+ var GENERIC_PROPOSAL_HEADINGS = new Set(["proposal"]);
170112
+ /**
170113
+ * One display title for a Change, identical on every surface.
170114
+ *
170115
+ * `name` is the legacy parser's proposal H1 (absent for parser-less custom schemas); the change id
170116
+ * is the CLI-owned canonical identity (`openspec list --json` names changes by directory). The H1
170117
+ * wins only when it is a real, differentiated title; generic headings and the id itself fall back
170118
+ * to the id, so no surface ever shows two different titles for the same Change.
170119
+ */
170120
+ function changeDisplayTitle(changeId, name) {
170121
+ const trimmed = name?.trim();
170122
+ if (!trimmed || trimmed === changeId) return changeId;
170123
+ if (GENERIC_PROPOSAL_HEADINGS.has(trimmed.toLowerCase())) return changeId;
170124
+ return trimmed;
170125
+ }
170126
+ //#endregion
170061
170127
  //#region src/lib/change-workflow-phase.ts
170062
170128
  function classifyChangeWorkflowPhase(params) {
170063
170129
  if (params.hasStatus && params.trackedArtifactStatus === "blocked") return {
@@ -170180,6 +170246,8 @@ function useChangeListContinuity(incomingChanges, containerRef) {
170180
170246
  * Original request (2026-07-21): "Changes页面的右上角没有 New,你要不要快速补一个"
170181
170247
 
170182
170248
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
170249
+ * Original request (2026-09-12): Owner walkthrough: unify the Change display title — generic
170250
+ * "# Proposal" headings fall back to the change id on every surface.
170183
170251
  */
170184
170252
  function buildStatusMap(statuses) {
170185
170253
  return new Map((statuses ?? []).map((status) => [status.changeName, status]));
@@ -170329,7 +170397,7 @@ function ChangeList() {
170329
170397
  __vtHandoff: {
170330
170398
  family: "changes",
170331
170399
  entityId: change.id,
170332
- title: change.name,
170400
+ title: changeDisplayTitle(change.id, change.name),
170333
170401
  subtitle: change.id
170334
170402
  }
170335
170403
  }),
@@ -170340,7 +170408,7 @@ function ChangeList() {
170340
170408
  className: "flex items-center gap-3",
170341
170409
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
170342
170410
  changeId: change.id,
170343
- name: change.name,
170411
+ name: changeDisplayTitle(change.id, change.name),
170344
170412
  phase,
170345
170413
  updatedAt: change.updatedAt,
170346
170414
  formatTime: formatRelativeTime,
@@ -171386,16 +171454,27 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
171386
171454
  //#endregion
171387
171455
  //#region src/components/apply-progress-notice.tsx
171388
171456
  /**
171389
- * Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
171457
+ * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
171390
171458
  * 1. Attribute Apply instruction counts to the upstream Apply command.
171391
171459
  * 2. Compress agreement to one subtitle badge; keep divergence a direct blocker.
171392
171460
  * 3. Keep divergence's two objective source counts side by side with their causes.
171393
171461
  * 4. Keep tooltips as the keyboard-reachable explanation for every compact count.
171462
+ * 5. Render OpenSpec 1.13 Apply `warnings`/`missingPrerequisites` as ONE always-visible summary
171463
+ * row (count + build-order chain, CLI attribution) whose verbatim evidence is one explicit
171464
+ * expansion away on the same direct plane — advisory guidance must stay discoverable without
171465
+ * consuming the page; a Tooltip-only surface remains forbidden.
171466
+ * 6. Keep `missingPrerequisites` visually and semantically distinct from blockers (status
171467
+ * semantics), including when the Apply state is already `ready`.
171468
+ * 7. Degrade to the previous presentation when either 1.13 field is absent — absent keys
171469
+ * are the upstream encoding for "none", so no empty state is ever synthesized.
171394
171470
  *
171395
171471
  * Original request (2026-07-15): "与 tracked glob 进度分歧时各自归因展示。"
171396
171472
  * Original request (2026-07-28): supporting 6.x evidence should use Badge + Tooltip or Accordion.
171397
171473
  * Original request (2026-08-15): Owner walkthrough: agreement is one badge in the subtitle row,
171398
171474
  * not a two-line block; only divergence owns a notice.
171475
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
171476
+ * Original request (2026-09-12): Owner walkthrough: the always-expanded warning/build-order blocks
171477
+ * consumed the page; collapse them behind one summary row while keeping direct-plane discovery.
171399
171478
  */
171400
171479
  /**
171401
171480
  * One compact, source-attributed Apply progress badge for the Change subtitle row.
@@ -171416,54 +171495,143 @@ function ApplyProgressBadge({ applyInstructionProgress }) {
171416
171495
  ]
171417
171496
  });
171418
171497
  }
171498
+ /** Upstream command that owns every fact rendered by these notices. */
171499
+ var APPLY_COMMAND_ATTRIBUTION = "openspec instructions apply";
171500
+ var GUIDANCE_DETAIL_ID = "apply-readiness-guidance-detail";
171419
171501
  /**
171420
- * Render the Apply/tracked divergence as one direct, source-attributed blocker. Returns
171421
- * null when the sources agree — the agreement case lives in the subtitle badge row via
171422
- * {@link ApplyProgressBadge}.
171502
+ * Render the Apply/tracked divergence as one direct, source-attributed blocker, plus the
171503
+ * OpenSpec 1.13 `warnings` and `missingPrerequisites` evidence as one collapsible summary row:
171504
+ * the row itself names the warning count and the build-order chain (discovery needs no hover),
171505
+ * and expanding reveals the verbatim upstream evidence on the same direct plane.
171506
+ * Returns null when none apply — the agreement case lives in the subtitle badge row via
171507
+ * {@link ApplyProgressBadge}, and absent 1.13 keys render nothing.
171423
171508
  */
171424
- function ApplyProgressNotice({ applyInstructionProgress }) {
171509
+ function ApplyProgressNotice({ applyInstructionProgress, warnings, missingPrerequisites }) {
171425
171510
  const divergence = applyInstructionProgress.divergence;
171426
- if (!divergence) return null;
171427
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171428
- role: "status",
171429
- "aria-label": "Task progress source divergence",
171430
- className: "flex min-w-0 items-start gap-2 border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",
171431
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
171432
- className: "mt-0.5 h-4 w-4 shrink-0",
171433
- "aria-hidden": "true"
171434
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171435
- className: "min-w-0 space-y-2",
171511
+ const hasWarnings = (warnings?.length ?? 0) > 0;
171512
+ const hasPrerequisites = (missingPrerequisites?.length ?? 0) > 0;
171513
+ const [expanded, setExpanded] = (0, import_react.useState)(false);
171514
+ if (!divergence && !hasWarnings && !hasPrerequisites) return null;
171515
+ const guidanceSummaryParts = [];
171516
+ if (hasWarnings) {
171517
+ const count = warnings.length;
171518
+ guidanceSummaryParts.push(`${count} apply warning${count > 1 ? "s" : ""}`);
171519
+ }
171520
+ if (hasPrerequisites) guidanceSummaryParts.push(`next in build order: ${missingPrerequisites.join(" → ")}`);
171521
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
171522
+ hasWarnings || hasPrerequisites ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171523
+ role: "status",
171524
+ "data-apply-notice": "summary",
171525
+ "aria-label": `Apply readiness guidance from ${APPLY_COMMAND_ATTRIBUTION}`,
171526
+ className: hasWarnings ? "flex min-w-0 items-center gap-2 border border-amber-300 bg-amber-50 px-3 py-1.5 text-xs text-amber-950 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100" : "text-muted-foreground flex min-w-0 items-center gap-2 rounded-md border px-3 py-1.5 text-xs",
171436
171527
  children: [
171437
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171438
- className: "font-medium",
171439
- children: "Upstream task progress divergence"
171528
+ hasWarnings ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
171529
+ className: "h-4 w-4 shrink-0",
171530
+ "aria-hidden": "true"
171531
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListOrdered, {
171532
+ className: "h-4 w-4 shrink-0",
171533
+ "aria-hidden": "true"
171440
171534
  }),
171441
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: divergence.message }),
171442
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171443
- className: "flex flex-wrap gap-1.5",
171444
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
171445
- ariaLabel: `Apply instructions progress ${applyInstructionProgress.complete} of ${applyInstructionProgress.total}`,
171446
- tooltip: "Progress reported by openspec instructions apply.",
171447
- children: [
171448
- "Apply ",
171449
- applyInstructionProgress.complete,
171450
- "/",
171451
- applyInstructionProgress.total
171452
- ]
171453
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
171454
- ariaLabel: `Tracked artifact glob progress ${divergence.tracked.completed} of ${divergence.tracked.total}`,
171455
- tooltip: "Progress computed from the workflow's tracked task artifact glob.",
171456
- children: [
171457
- "Tracked ",
171458
- divergence.tracked.completed,
171459
- "/",
171460
- divergence.tracked.total
171461
- ]
171535
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
171536
+ type: "button",
171537
+ onClick: () => setExpanded((value) => !value),
171538
+ "aria-expanded": expanded,
171539
+ "aria-controls": GUIDANCE_DETAIL_ID,
171540
+ className: "flex min-w-0 flex-1 cursor-pointer items-center gap-2 text-left",
171541
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
171542
+ className: "truncate font-medium",
171543
+ children: guidanceSummaryParts.join(" · ")
171544
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
171545
+ className: "text-muted-foreground shrink-0 font-normal",
171546
+ children: ["— ", APPLY_COMMAND_ATTRIBUTION]
171462
171547
  })]
171548
+ }),
171549
+ expanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {
171550
+ className: "h-4 w-4 shrink-0",
171551
+ "aria-hidden": "true"
171552
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, {
171553
+ className: "h-4 w-4 shrink-0",
171554
+ "aria-hidden": "true"
171463
171555
  })
171464
171556
  ]
171465
- })]
171466
- });
171557
+ }) : null,
171558
+ expanded && (hasWarnings || hasPrerequisites) ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171559
+ id: GUIDANCE_DETAIL_ID,
171560
+ className: "text-muted-foreground space-y-2 rounded-md border px-3 py-2 text-xs",
171561
+ children: [hasWarnings ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171562
+ "data-apply-notice": "warnings",
171563
+ className: "min-w-0 space-y-1",
171564
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171565
+ className: "text-foreground font-medium",
171566
+ children: ["Apply warnings — reported by ", APPLY_COMMAND_ATTRIBUTION]
171567
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
171568
+ className: "space-y-1",
171569
+ children: warnings?.map((warning) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
171570
+ className: "break-words",
171571
+ children: warning
171572
+ }, warning))
171573
+ })]
171574
+ }) : null, hasPrerequisites ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171575
+ "data-apply-notice": "build-order",
171576
+ className: "min-w-0 space-y-1",
171577
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171578
+ className: "text-foreground font-medium",
171579
+ children: ["Next in build order — reported by ", APPLY_COMMAND_ATTRIBUTION]
171580
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171581
+ className: "flex flex-wrap items-center gap-1",
171582
+ children: missingPrerequisites?.map((artifactId, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
171583
+ className: "text-muted-foreground/70",
171584
+ "aria-hidden": "true",
171585
+ children: "→"
171586
+ }) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
171587
+ className: "bg-muted break-words rounded border px-1 py-0.5 font-mono [overflow-wrap:anywhere]",
171588
+ children: artifactId
171589
+ })] }, artifactId))
171590
+ })]
171591
+ }) : null]
171592
+ }) : null,
171593
+ divergence ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171594
+ role: "status",
171595
+ "data-apply-notice": "divergence",
171596
+ "aria-label": "Task progress source divergence",
171597
+ className: "flex min-w-0 items-start gap-2 border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",
171598
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
171599
+ className: "mt-0.5 h-4 w-4 shrink-0",
171600
+ "aria-hidden": "true"
171601
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171602
+ className: "min-w-0 space-y-2",
171603
+ children: [
171604
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171605
+ className: "font-medium",
171606
+ children: "Upstream task progress divergence"
171607
+ }),
171608
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: divergence.message }),
171609
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171610
+ className: "flex flex-wrap gap-1.5",
171611
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
171612
+ ariaLabel: `Apply instructions progress ${applyInstructionProgress.complete} of ${applyInstructionProgress.total}`,
171613
+ tooltip: "Progress reported by openspec instructions apply.",
171614
+ children: [
171615
+ "Apply ",
171616
+ applyInstructionProgress.complete,
171617
+ "/",
171618
+ applyInstructionProgress.total
171619
+ ]
171620
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
171621
+ ariaLabel: `Tracked artifact glob progress ${divergence.tracked.completed} of ${divergence.tracked.total}`,
171622
+ tooltip: "Progress computed from the workflow's tracked task artifact glob.",
171623
+ children: [
171624
+ "Tracked ",
171625
+ divergence.tracked.completed,
171626
+ "/",
171627
+ divergence.tracked.total
171628
+ ]
171629
+ })]
171630
+ })
171631
+ ]
171632
+ })]
171633
+ }) : null
171634
+ ] });
171467
171635
  }
171468
171636
  //#endregion
171469
171637
  //#region src/components/change-context-summary.tsx
@@ -171598,16 +171766,16 @@ function EvidenceLayerHeader({ title, summary }) {
171598
171766
  }
171599
171767
  //#endregion
171600
171768
  //#region ../core/src/openspec-compat.ts
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";
171769
+ var OPENSPEC_CLI_TARGET_SERIES = "1.13";
171770
+ var OPENSPEC_CLI_SUPPORTED_SERIES = ["1.13"];
171771
+ var OPENSPEC_CLI_ACCEPTED_RANGE = ">=1.13.0 <1.14.0";
171604
171772
  /**
171605
171773
  * Derive command capabilities from one parsed CLI version.
171606
171774
  *
171607
171775
  * Only an admitted version — stable inside the accepted range — can select version-specific
171608
- * capabilities. Unsupported forms (prereleases, >=1.13, below-range) and unparseable output
171776
+ * capabilities. Unsupported forms (prereleases, >=1.14, below-range) and unparseable output
171609
171777
  * keep their mismatch evidence and expose no capability, so a page-level version bypass can
171610
- * never manufacture a 1.12 command surface for a CLI the release line does not admit.
171778
+ * never manufacture a 1.13 command surface for a CLI the release line does not admit.
171611
171779
  */
171612
171780
  function deriveOpenSpecCliCapabilities(version) {
171613
171781
  if (!isAdmittedVersion(version)) return {
@@ -171649,7 +171817,7 @@ function isStable(version) {
171649
171817
  /** True only for stable versions inside the accepted range (current or supported non-current). */
171650
171818
  function isAdmittedVersion(version) {
171651
171819
  if (!version || !isStable(version)) return false;
171652
- return isSeries(version, "1.12") || isSupportedNonCurrentSeries(version);
171820
+ return isSeries(version, "1.13") || isSupportedNonCurrentSeries(version);
171653
171821
  }
171654
171822
  function isSupportedNonCurrentSeries(version) {
171655
171823
  return OPENSPEC_CLI_SUPPORTED_SERIES.filter((series) => series !== OPENSPEC_CLI_TARGET_SERIES).some((series) => isSeries(version, series));
@@ -171657,11 +171825,11 @@ function isSupportedNonCurrentSeries(version) {
171657
171825
  //#endregion
171658
171826
  //#region src/components/archived-validation-evidence.tsx
171659
171827
  /**
171660
- * Orthogonal intents (updated 2026-09-03 Asia/Shanghai):
171828
+ * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
171661
171829
  * 1. Present OpenSpec `validate --archived --json` as typed CLI evidence.
171662
171830
  * 2. Preserve item issues, totals, root, and exit/failure evidence without repair actions.
171663
171831
  * 3. Identify the evidence as unavailable in static snapshots instead of fabricating it.
171664
- * 4. Derive the capability from the detected admitted CLI; the admitted 1.12 line declares
171832
+ * 4. Derive the capability from the detected admitted CLI; the admitted 1.13 line declares
171665
171833
  * it, so the unavailable branch names the accepted range, not one series.
171666
171834
  * 5. Validate report payloads with the Core contract schema, never shallow shape guards.
171667
171835
  * 6. Mount directly inside the Evidence workspace detail pane: the Accordion shell is gone, the
@@ -171673,6 +171841,7 @@ function isSupportedNonCurrentSeries(version) {
171673
171841
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
171674
171842
  * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
171675
171843
  * 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.
171844
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
171676
171845
  */
171677
171846
  function parseValidationReport$1(value) {
171678
171847
  const parsed = CliValidateReportSchema.safeParse(value);
@@ -172566,8 +172735,9 @@ function EvidenceList({ label, values }) {
172566
172735
  //#endregion
172567
172736
  //#region src/components/validation-findings-evidence.tsx
172568
172737
  /**
172569
- * Orthogonal intents (updated 2026-09-04 Asia/Shanghai):
172570
- * 1. Present the OpenSpec 1.12 `validate --report findings` document as typed CLI evidence.
172738
+ * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
172739
+ * 1. Present the OpenSpec 1.12+ `validate --report findings` document (the admitted 1.13
172740
+ * line carries the capability) as typed CLI evidence.
172571
172741
  * 2. Attribute every item finding to its owning change: entries owned by the current change
172572
172742
  * render as the primary "This change" list, while entries owned by other active changes
172573
172743
  * stay in a clearly-labeled secondary disclosure with prominent change attribution — a
@@ -172583,6 +172753,7 @@ function EvidenceList({ label, values }) {
172583
172753
  *
172584
172754
  * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
172585
172755
  * 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.
172756
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
172586
172757
  */
172587
172758
  function parseFindingsPayload(value) {
172588
172759
  const parsed = CliValidateFindingsResultSchema.safeParse(value);
@@ -173060,6 +173231,7 @@ function ValidationFindingsEvidence({ changeId, onChip }) {
173060
173231
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
173061
173232
  * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
173062
173233
  * 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.
173234
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
173063
173235
  */
173064
173236
  /**
173065
173237
  * Spacious threshold: below this inline size the workspace collapses to one column and the
@@ -173510,13 +173682,14 @@ function RootActionNotice({ state }) {
173510
173682
  //#endregion
173511
173683
  //#region src/routes/change-view.tsx
173512
173684
  /**
173513
- * Orthogonal intents (updated 2026-08-28 Asia/Shanghai):
173685
+ * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
173514
173686
  * 1. Render schema-aware change artifacts and source files while retaining terminal status errors.
173515
173687
  * 2. Dispatch change workflows through routed compose/verify surfaces and the shared Operator launcher.
173516
173688
  * 3. Lock every change workflow action behind current Root Context and Status projection authority.
173517
173689
  * 4. Present Apply progress directly and expose project context/guidance through a Header Action Dialog.
173518
173690
  * 5. Keep compact Change facts in subtitle badges while routing complete CLI evidence through a dedicated tab.
173519
173691
  * 6. Mount the container-responsive list-detail Evidence workspace as the sole Evidence tab surface.
173692
+ * 7. Mount OpenSpec 1.13 Apply warnings and the build-order chain on the direct status plane.
173520
173693
  *
173521
173694
  * Original request (2026-07-15): "Root-dependent actions remain locked until root selection succeeds."
173522
173695
  * Review request (2026-07-23): "代码已经提交,开始review。如果有问题,那么可更新change。"
@@ -173529,6 +173702,11 @@ function RootActionNotice({ state }) {
173529
173702
  * tab gains the capability-gated CLI MODIFIED-delta diff evidence beside the existing layers.
173530
173703
  * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进" — the Evidence tab gains the findings evidence section.
173531
173704
  * Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
173705
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
173706
+ * Original request (2026-09-12): Owner walkthrough: unify the Change display title (generic "# Proposal"
173707
+ * headings fall back to the change id) and collapse Apply readiness guidance into one summary row.
173708
+ * — the status region gains the OpenSpec 1.13 Apply `warnings` and `missingPrerequisites`
173709
+ * direct-plane evidence beside the existing divergence notice.
173532
173710
  */
173533
173711
  function ChangeView() {
173534
173712
  const { changeId } = useParams({ from: "/changes/$changeId" });
@@ -173539,6 +173717,8 @@ function ChangeView() {
173539
173717
  const { data: status, isLoading, error } = statusProjection;
173540
173718
  const { data: applyInstructions } = useOpsxApplyInstructionsSubscription({ change: changeId });
173541
173719
  const { data: files } = useChangeFilesSubscription(changeId);
173720
+ const changesRows = useChangesSubscription().data;
173721
+ const displayTitle = changeDisplayTitle(changeId, changesRows?.find((row) => row.id === changeId)?.name ?? status?.changeName);
173542
173722
  const handleComposeAction = (0, import_react.useCallback)((actionId, artifactId) => {
173543
173723
  if (actionId === "apply") {
173544
173724
  launchApply({
@@ -173609,14 +173789,14 @@ function ChangeView() {
173609
173789
  })
173610
173790
  }] : [], [referenceEvidence, status]);
173611
173791
  const hasReferenceFailures = referenceEvidence.state !== "unavailable" && referenceEvidence.references.some((reference) => reference.status.some((diagnostic) => diagnostic.severity === "error"));
173612
- const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence);
173792
+ const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence) || (applyInstructions?.warnings?.length ?? 0) > 0 || (applyInstructions?.missingPrerequisites?.length ?? 0) > 0;
173613
173793
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OpsxEntityDetailView, {
173614
173794
  entityId: changeId,
173615
173795
  sharedFamily: "changes",
173616
173796
  backTo: "/changes",
173617
173797
  backTitle: "Back to Changes",
173618
173798
  icon: GitBranch,
173619
- title: status?.changeName,
173799
+ title: displayTitle,
173620
173800
  subtitle: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeContextSummary, {
173621
173801
  status,
173622
173802
  referenceEvidence,
@@ -173684,7 +173864,11 @@ function ChangeView() {
173684
173864
  }) : null,
173685
173865
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootActionNotice, { state: rootAction }),
173686
173866
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeReferenceFailureNotice, { referenceEvidence }),
173687
- applyInstructions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressNotice, { applyInstructionProgress: applyInstructions.applyInstructionProgress }) : null
173867
+ applyInstructions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressNotice, {
173868
+ applyInstructionProgress: applyInstructions.applyInstructionProgress,
173869
+ warnings: applyInstructions.warnings,
173870
+ missingPrerequisites: applyInstructions.missingPrerequisites
173871
+ }) : null
173688
173872
  ]
173689
173873
  }) : null
173690
173874
  });
@@ -173724,7 +173908,7 @@ var CONFIG_GUIDE_STAGE_META = {
173724
173908
  //#region src/components/config/config-guide.tsx
173725
173909
  var ConfigGuideContext = (0, import_react.createContext)(null);
173726
173910
  (0, import_react.lazy)(async () => {
173727
- return { default: (await import("./config-guide-presentation-GWnVFKTW.js")).ConfigGuidePresentationLayer };
173911
+ return { default: (await import("./config-guide-presentation-B5oRLCcX.js")).ConfigGuidePresentationLayer };
173728
173912
  });
173729
173913
  /** Access the root-owned adaptive Guide runtime. */
173730
173914
  function useConfigGuide() {
@@ -178766,6 +178950,8 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
178766
178950
  * Original request (2026-07-31): "基于真实的布局去做骨架屏,或者说是直接让卡片自身去支持 Pending 样式"
178767
178951
  * Original request (2026-07-31): "Code Git Snapshot 的 Other Worktrees 默认隐藏 (detached)。然后commitList这里默认显示5个就好"
178768
178952
  * Original request (2026-07-31): "检查目前的这个 Code Git Snapshot,它非常慢,有时候甚至要十几秒"
178953
+ * Original request (2026-09-12): Owner walkthrough: unify the Change display title — generic
178954
+ * "# Proposal" headings fall back to the change id on every surface.
178769
178955
  * Owner correction (2026-07-31): Hidden documents pause the timer; visibility resumes the remaining delay or refreshes once when the absolute deadline elapsed.
178770
178956
 
178771
178957
  */
@@ -179254,7 +179440,7 @@ function Dashboard() {
179254
179440
  __vtHandoff: {
179255
179441
  family: "changes",
179256
179442
  entityId: change.id,
179257
- title: change.name,
179443
+ title: changeDisplayTitle(change.id, change.name),
179258
179444
  subtitle: change.id
179259
179445
  }
179260
179446
  }),
@@ -179271,7 +179457,7 @@ function Dashboard() {
179271
179457
  className: "flex min-w-0 items-center gap-3",
179272
179458
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
179273
179459
  changeId: change.id,
179274
- name: change.name,
179460
+ name: changeDisplayTitle(change.id, change.name),
179275
179461
  phase,
179276
179462
  updatedAt: change.updatedAt,
179277
179463
  formatTime: formatRelativeTime,