@openspecui/web 13.0.0 → 13.0.1

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 (67) hide show
  1. package/dist/assets/{App-Cq2vfNv0.js → App-C6nQouC6.js} +150 -150
  2. package/dist/assets/{main-CjHLYXqj.js → main-CGJ5sQ3N.js} +2 -2
  3. package/dist/assets/{trpc-BJDrN6rb.js → trpc-Cq_wSpa5.js} +1 -1
  4. package/dist/index.html +1 -1
  5. package/dist-ssg/client/.vite/ssr-manifest.json +39 -29
  6. package/dist-ssg/client/assets/CanvasRenderer-Dxe-hfnN.js +1 -0
  7. package/dist-ssg/client/assets/WebGLRenderer-CUJXjtiP.js +1 -0
  8. package/dist-ssg/client/assets/WebGPURenderer-CZL-JNBq.js +1 -0
  9. package/dist-ssg/client/assets/browserAll-5wBADmKd.js +1 -0
  10. package/dist-ssg/client/assets/{config-guide-presentation-BYWAVHG-.js → config-guide-presentation-DqNeQzUr.js} +1 -1
  11. package/dist-ssg/client/assets/dist-9A8186dQ.js +1 -0
  12. package/dist-ssg/client/assets/{dist-B7XysJsL.js → dist-BD3jMQZ6.js} +1 -1
  13. package/dist-ssg/client/assets/dist-BMEQqWwb.js +1 -0
  14. package/dist-ssg/client/assets/dist-BTKdGHSA.js +1 -0
  15. package/dist-ssg/client/assets/{dist-DvnWUGiW.js → dist-Bbhzl31A.js} +1 -1
  16. package/dist-ssg/client/assets/{dist-DBbVV3c6.js → dist-CY1qnMaG.js} +1 -1
  17. package/dist-ssg/client/assets/{dist-DFWGpO_L.js → dist-CaeREplI.js} +1 -1
  18. package/dist-ssg/client/assets/{dist-PNypP3x_.js → dist-CdubN8-m.js} +1 -1
  19. package/dist-ssg/client/assets/{dist-CT1adEON.js → dist-DImGv92l.js} +1 -1
  20. package/dist-ssg/client/assets/{dist-B014oKqB.js → dist-DvFFLa-_.js} +1 -1
  21. package/dist-ssg/client/assets/{dist-DtpQCgKd.js → dist-DvI6Bh6U.js} +1 -1
  22. package/dist-ssg/client/assets/{dist-DUzLJ7IR.js → dist-FrX9lO7v.js} +1 -1
  23. package/dist-ssg/client/assets/{ghostty-web-DSqlIAa4.js → ghostty-web-iJUDy0Q_.js} +1 -1
  24. package/dist-ssg/client/assets/{index.ssg-CJP1DN4-.js → index.ssg-C1gQDtR3.js} +93 -93
  25. package/dist-ssg/client/assets/{init-ORkrPTI8.js → init-CXOzxy8a.js} +1 -1
  26. package/dist-ssg/client/assets/{trpc-DimmQX0m.js → trpc-DeGTgf0N.js} +1 -1
  27. package/dist-ssg/client/assets/webworkerAll-D2PWaP7M.js +1 -0
  28. package/dist-ssg/client/index.ssg.html +1 -1
  29. package/dist-ssg/server/assets/CanvasRenderer-B1MUQY2W.js +3 -0
  30. package/dist-ssg/server/assets/WebGLRenderer-DIOoeqKv.js +3 -0
  31. package/dist-ssg/server/assets/WebGPURenderer-hzdCHpRg.js +3 -0
  32. package/dist-ssg/server/assets/{browserAll-BoaMSEnC.js → browserAll-C3aU2kkg.js} +2 -2
  33. package/dist-ssg/server/assets/{config-guide-presentation-B5oRLCcX.js → config-guide-presentation-BQdHuc5R.js} +1 -1
  34. package/dist-ssg/server/assets/{dist-CLOFOKCn.js → dist-BrgApT3v.js} +1 -1
  35. package/dist-ssg/server/assets/{dist-CUmPwPDw.js → dist-BuA1hNQD.js} +1 -1
  36. package/dist-ssg/server/assets/{dist-CHiBYKhO.js → dist-C8tud7al.js} +1 -1
  37. package/dist-ssg/server/assets/{dist-C4EXY8oH.js → dist-CYFz-Xe6.js} +1 -1
  38. package/dist-ssg/server/assets/{dist-DQpyDhfS.js → dist-CeAwBeY0.js} +1 -1
  39. package/dist-ssg/server/assets/dist-DQfK_0MA.js +3 -0
  40. package/dist-ssg/server/assets/{dist-DVnu9zoA.js → dist-DVq3OitZ.js} +1 -1
  41. package/dist-ssg/server/assets/dist-DhIAeIAf.js +3 -0
  42. package/dist-ssg/server/assets/{dist-BTp4dJw4.js → dist-DoPtyXvU.js} +1 -1
  43. package/dist-ssg/server/assets/{dist-D_mnjXV3.js → dist-cd39lbM_.js} +1 -1
  44. package/dist-ssg/server/assets/{dist-Bi2hyX2D.js → dist-uLS_wgVI.js} +1 -1
  45. package/dist-ssg/server/assets/dist-wVpQUanK.js +3 -0
  46. package/dist-ssg/server/assets/{entry-server-CXwaLjrK.js → entry-server-DOzQvxeU.js} +243 -60
  47. package/dist-ssg/server/assets/{init-B1eN597N.js → init-Dw3wIW5D.js} +1 -1
  48. package/dist-ssg/server/assets/trpc-CE2cP14O.js +3 -0
  49. package/dist-ssg/server/assets/webworkerAll-CMJ1pR5p.js +4 -0
  50. package/dist-ssg/server/ssr-entry-manifest.json +24 -24
  51. package/package.json +3 -3
  52. package/dist-ssg/client/assets/CanvasRenderer-BAnUeHzl.js +0 -1
  53. package/dist-ssg/client/assets/WebGLRenderer-DehTnF66.js +0 -1
  54. package/dist-ssg/client/assets/WebGPURenderer-BCXAr50t.js +0 -1
  55. package/dist-ssg/client/assets/browserAll-Brx8TmCT.js +0 -1
  56. package/dist-ssg/client/assets/dist-BKcEPt5U.js +0 -1
  57. package/dist-ssg/client/assets/dist-BZVFJHY_.js +0 -1
  58. package/dist-ssg/client/assets/dist-qdJFVZmv.js +0 -1
  59. package/dist-ssg/client/assets/webworkerAll-DjsDtAjh.js +0 -1
  60. package/dist-ssg/server/assets/CanvasRenderer-CvVvHnla.js +0 -3
  61. package/dist-ssg/server/assets/WebGLRenderer-ZTMKqKjr.js +0 -3
  62. package/dist-ssg/server/assets/WebGPURenderer-BaTRp8M6.js +0 -3
  63. package/dist-ssg/server/assets/dist-CIVGOe5c.js +0 -3
  64. package/dist-ssg/server/assets/dist-DAIXBI5T.js +0 -3
  65. package/dist-ssg/server/assets/dist-fy1m8mbf.js +0 -3
  66. package/dist-ssg/server/assets/trpc-BQ6eyI7t.js +0 -3
  67. package/dist-ssg/server/assets/webworkerAll-bAKoC1FD.js +0 -4
@@ -29769,11 +29769,14 @@ objectType({
29769
29769
  * 1. Publish browser-safe lenient Spec/active-Change entry schemas for Store-content projection.
29770
29770
  * 2. Define the additive Store-content compatibility fact and demand-driven content kind.
29771
29771
  * 3. Keep this entry free of Node runtime dependencies for hosted browser consumers.
29772
+ * 4. Model the OpenSpec 1.13.1 `nested` member on Store active-Change entries so the
29773
+ * server-side content projection can exclude namespace folders from its projected list.
29772
29774
  *
29773
29775
  * Original request (2026-07-30): "Stores 完全可以融入 `Environment Center` 这个东西,就跟 Config 和 Context 的关系一样。"
29774
29776
  * Derived boundary (2026-07-30): Store UI identity is `(backend-issued envUri, Store id)`; Store Detail
29775
29777
  * shows readonly content summaries sourced from typed `list --specs|--changes --store <id>`.
29776
29778
  * Spec: hosted-environment-delivery › "Environment-Scoped Store Content Projection".
29779
+ * Original request (2026-09-17): "Openspec 1.13.1 释放了…" — change-list nested/warnings projection (update-openspec-cli-1131 Slice 2).
29777
29780
  *
29778
29781
  * Capability visibility is a compatibility fact, not authorization. A backend that omits
29779
29782
  * `stores.content.inspect` simply does not advertise the content projection; the App renders the
@@ -29794,7 +29797,8 @@ var StoreContentChangeEntrySchema = objectType({
29794
29797
  "no-tasks",
29795
29798
  "complete",
29796
29799
  "in-progress"
29797
- ])
29800
+ ]),
29801
+ nested: arrayType(stringType()).optional()
29798
29802
  }).passthrough();
29799
29803
  objectType({
29800
29804
  specs: arrayType(StoreContentSpecEntrySchema).default([]),
@@ -30908,7 +30912,7 @@ var NavController = class {
30908
30912
  this.storageKey = scopedStorageKey;
30909
30913
  this.rebindProjectScopedLayout(scopedStorageKey);
30910
30914
  }
30911
- const { trpcClient } = await import("./trpc-BQ6eyI7t.js");
30915
+ const { trpcClient } = await import("./trpc-CE2cP14O.js");
30912
30916
  const remote = parsePersistedLayout(await trpcClient.kv.get.query({ key: this.storageKey }));
30913
30917
  if (remote) {
30914
30918
  if (remote.updatedAt > this.state.updatedAt) this.dispatch({
@@ -31051,7 +31055,7 @@ var NavController = class {
31051
31055
  this.cancelPersistTimer();
31052
31056
  this.persistTimer = setTimeout(() => {
31053
31057
  this.persistTimer = null;
31054
- import("./trpc-BQ6eyI7t.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31058
+ import("./trpc-CE2cP14O.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31055
31059
  key: this.storageKey,
31056
31060
  value: {
31057
31061
  mainTabs: this.state.mainTabs,
@@ -38940,6 +38944,54 @@ var R$2 = class R$2 {
38940
38944
  function F$1(t) {
38941
38945
  throw new I$2(t);
38942
38946
  }
38947
+ //#endregion
38948
+ //#region ../core/src/cli-contracts/workflow.ts
38949
+ /**
38950
+ * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
38951
+ * 1. Model camelCase workflow JSON independently from Store-family JSON.
38952
+ * 2. Preserve strict, archived, and bulk Validate plus Archive outcomes, including failure payloads.
38953
+ * 3. Preserve multiline requirement bodies from `show --json`.
38954
+ * 4. Preserve complete admitted-line (1.10/1.11) Status and operation-Instruction contracts as CLI facts.
38955
+ * 5. Export the successful Spec-document schema for browser-safe projection validation.
38956
+ * 6. Export the root-less Status payload fields and Requirement shape shared with the
38957
+ * OpenSpec 1.11 batch Status and show --diff contracts.
38958
+ * 7. Model the OpenSpec 1.12 `validate --report findings` document beside (never inside) the
38959
+ * full Validate report, sharing the bulk-item and summary shapes while keeping decoding
38960
+ * independent of the process exit code and of full-report validation truth. Decode owns
38961
+ * the upstream-guaranteed invariants (non-empty per-item issues, returnedItems bounded
38962
+ * by totalItems), and the union guard validates the discriminator shape rather than
38963
+ * mere `report`-key presence.
38964
+ * 8. Type the OpenSpec 1.13 Apply Instructions `missingPrerequisites` (build-order closure,
38965
+ * present even when ready) and `warnings` (no-delta-specs advisory) as additive optional
38966
+ * success members that never gain default empty arrays, never alter `state`/`progress`/
38967
+ * `tasks`/`missingArtifacts` semantics, and stay verbatim CLI evidence.
38968
+ * 9. Type the OpenSpec 1.13.1 change-list `nested` entry member and top-level `warnings`
38969
+ * array as additive optional facts (absent when empty, never null): an entry carrying
38970
+ * `nested` is a namespace folder, not an actionable change; `code` stays an open string
38971
+ * because an in-window patch may add codes beyond `nested_change_directory`.
38972
+ *
38973
+ * Original request (2026-07-15): "为不同命令建立强类型适配器,不实现平行解析规则。"
38974
+ * Original request (2026-07-26): "展开全面的接口升级和内核升级和测试升级。"
38975
+ * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
38976
+ * Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。"
38977
+ * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
38978
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
38979
+ * Original request (2026-09-17): "Openspec 1.13.1 释放了…" — change-list nested/warnings projection (update-openspec-cli-1131 Slice 2).
38980
+ */
38981
+ /**
38982
+ * One top-level change-list hygiene warning (OpenSpec 1.13.1 `list --json`).
38983
+ *
38984
+ * `code` is an open string, not a literal: the upstream contract documents
38985
+ * `nested_change_directory` as the only current code while reserving room for more, so an
38986
+ * in-window patch adding a code must survive decode as evidence instead of failing the
38987
+ * whole document. The whole array is absent when empty (never `null`, never `[]`).
38988
+ */
38989
+ var CliChangeListWarningSchema = objectType({
38990
+ code: stringType(),
38991
+ name: stringType(),
38992
+ nested: arrayType(stringType()),
38993
+ message: stringType()
38994
+ }).passthrough();
38943
38995
  objectType({
38944
38996
  changes: arrayType(objectType({
38945
38997
  name: stringType(),
@@ -38950,8 +39002,10 @@ objectType({
38950
39002
  "no-tasks",
38951
39003
  "complete",
38952
39004
  "in-progress"
38953
- ])
39005
+ ]),
39006
+ nested: arrayType(stringType()).optional()
38954
39007
  }).passthrough()),
39008
+ warnings: arrayType(CliChangeListWarningSchema).optional(),
38955
39009
  root: CliRootSchema.nullable(),
38956
39010
  status: arrayType(CliDiagnosticSchema).optional()
38957
39011
  }).passthrough();
@@ -43594,8 +43648,13 @@ var TemplateContentMapSchema = recordType(stringType(), TemplateContentSchema);
43594
43648
  * 2. Define the runtime-environment Environment Global projection contract.
43595
43649
  * 3. Publish browser-safe lifecycle Pull schemas without importing Node-owned Core modules.
43596
43650
  * 4. Keep projection data discriminated across Status and Artifact/Apply/Archive Instructions.
43651
+ * 5. Model the OpenSpec 1.13.1 change-list namespace facts beside the actionable set:
43652
+ * `entries`/`value` stay actionable-only, `namespaces` is the single structural
43653
+ * namespace-name set for row builders, and `warnings` is passthrough display evidence
43654
+ * (absent when the CLI omitted it, never a synthesized empty array).
43597
43655
  *
43598
43656
  * Original request (2026-07-26): "展开全面的接口升级和内核升级和测试升级。"
43657
+ * Original request (2026-09-17): "Openspec 1.13.1 释放了…" — change-list nested/warnings projection (update-openspec-cli-1131 Slice 2).
43599
43658
  */
43600
43659
  /** Runtime selector for one Planning-root CLI-backed projection. */
43601
43660
  var PlanningCliProjectionSelectorSchema = discriminatedUnionType("kind", [
@@ -43657,6 +43716,8 @@ var PlanningCliProjectionStateSchema = createCliProjectionStateSchema(discrimina
43657
43716
  "in-progress"
43658
43717
  ])
43659
43718
  })),
43719
+ namespaces: arrayType(stringType()),
43720
+ warnings: arrayType(CliChangeListWarningSchema).optional(),
43660
43721
  evidence: CliProjectionCommandEvidenceSchema
43661
43722
  }),
43662
43723
  objectType({
@@ -44863,6 +44924,25 @@ function useOpsxApplyInstructionsSubscription(input) {
44863
44924
  isLoading: false
44864
44925
  };
44865
44926
  }
44927
+ /**
44928
+ * OpenSpec 1.13.1 change-list hygiene warnings (e.g. `nested_change_directory`).
44929
+ *
44930
+ * Display evidence only: the CLI's verbatim warning array rides beside the actionable
44931
+ * change list; it never gates row visibility or mutation authority. Static publication
44932
+ * carries no CLI lifecycle evidence, so the static loader resolves no warnings — an empty
44933
+ * list there is absence of evidence, not a fabricated clean bill of health.
44934
+ */
44935
+ function useOpsxChangeListHygieneWarningsSubscription() {
44936
+ return useCliProjectionSubscription({
44937
+ selector: { kind: "opsx-change-list" },
44938
+ selectData(data) {
44939
+ if (data.kind !== "opsx-change-list") throw new Error(`Expected opsx-change-list projection, received ${data.kind}.`);
44940
+ return data.warnings ?? [];
44941
+ },
44942
+ staticLoader: async () => [],
44943
+ cacheKey: "opsx.changeListHygieneWarnings"
44944
+ });
44945
+ }
44866
44946
  function useOpsxArtifactOutputSubscription(changeId, outputPath) {
44867
44947
  return useSubscription((0, import_react.useCallback)((callbacks) => {
44868
44948
  if (!changeId || !outputPath) {
@@ -71316,7 +71396,7 @@ var browserExt = {
71316
71396
  },
71317
71397
  test: () => true,
71318
71398
  load: async () => {
71319
- await import("./browserAll-BoaMSEnC.js");
71399
+ await import("./browserAll-C3aU2kkg.js");
71320
71400
  }
71321
71401
  };
71322
71402
  //#endregion
@@ -71329,7 +71409,7 @@ var webworkerExt = {
71329
71409
  },
71330
71410
  test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
71331
71411
  load: async () => {
71332
- await import("./webworkerAll-bAKoC1FD.js");
71412
+ await import("./webworkerAll-CMJ1pR5p.js");
71333
71413
  }
71334
71414
  };
71335
71415
  //#endregion
@@ -73923,7 +74003,7 @@ async function autoDetectRenderer(options) {
73923
74003
  for (let i = 0; i < preferredOrder.length; i++) {
73924
74004
  const rendererType = preferredOrder[i];
73925
74005
  if (rendererType === "webgpu" && await isWebGPUSupported()) {
73926
- const { WebGPURenderer } = await import("./WebGPURenderer-BaTRp8M6.js");
74006
+ const { WebGPURenderer } = await import("./WebGPURenderer-hzdCHpRg.js");
73927
74007
  RendererClass = WebGPURenderer;
73928
74008
  finalOptions = {
73929
74009
  ...options,
@@ -73931,7 +74011,7 @@ async function autoDetectRenderer(options) {
73931
74011
  };
73932
74012
  break;
73933
74013
  } else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
73934
- const { WebGLRenderer } = await import("./WebGLRenderer-ZTMKqKjr.js");
74014
+ const { WebGLRenderer } = await import("./WebGLRenderer-DIOoeqKv.js");
73935
74015
  RendererClass = WebGLRenderer;
73936
74016
  finalOptions = {
73937
74017
  ...options,
@@ -73939,7 +74019,7 @@ async function autoDetectRenderer(options) {
73939
74019
  };
73940
74020
  break;
73941
74021
  } else if (rendererType === "canvas") {
73942
- const { CanvasRenderer } = await import("./CanvasRenderer-CvVvHnla.js");
74022
+ const { CanvasRenderer } = await import("./CanvasRenderer-B1MUQY2W.js");
73943
74023
  RendererClass = CanvasRenderer;
73944
74024
  finalOptions = {
73945
74025
  ...options,
@@ -97688,7 +97768,7 @@ var TerminalController = class {
97688
97768
  if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
97689
97769
  this.configPersistTimer = setTimeout(() => {
97690
97770
  this.configPersistTimer = null;
97691
- import("./trpc-BQ6eyI7t.js").then(({ trpcClient }) => {
97771
+ import("./trpc-CE2cP14O.js").then(({ trpcClient }) => {
97692
97772
  trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
97693
97773
  }).catch(() => {});
97694
97774
  }, CONFIG_PERSIST_DEBOUNCE);
@@ -108249,7 +108329,7 @@ var languages = [
108249
108329
  name: "CSS",
108250
108330
  extensions: ["css"],
108251
108331
  load() {
108252
- return import("./dist-fy1m8mbf.js").then((m) => m.css());
108332
+ return import("./dist-wVpQUanK.js").then((m) => m.css());
108253
108333
  }
108254
108334
  }),
108255
108335
  /* @__PURE__ */ LanguageDescription.of({
@@ -108269,7 +108349,7 @@ var languages = [
108269
108349
  "hbs"
108270
108350
  ],
108271
108351
  load() {
108272
- return import("./dist-C4EXY8oH.js").then((m) => m.html());
108352
+ return import("./dist-CYFz-Xe6.js").then((m) => m.html());
108273
108353
  }
108274
108354
  }),
108275
108355
  /* @__PURE__ */ LanguageDescription.of({
@@ -108303,7 +108383,7 @@ var languages = [
108303
108383
  "jinja2"
108304
108384
  ],
108305
108385
  load() {
108306
- return import("./dist-BTp4dJw4.js").then((m) => m.jinja());
108386
+ return import("./dist-DoPtyXvU.js").then((m) => m.jinja());
108307
108387
  }
108308
108388
  }),
108309
108389
  /* @__PURE__ */ LanguageDescription.of({
@@ -108311,7 +108391,7 @@ var languages = [
108311
108391
  alias: ["json5"],
108312
108392
  extensions: ["json", "map"],
108313
108393
  load() {
108314
- return import("./dist-DAIXBI5T.js").then((m) => m.json());
108394
+ return import("./dist-DhIAeIAf.js").then((m) => m.json());
108315
108395
  }
108316
108396
  }),
108317
108397
  /* @__PURE__ */ LanguageDescription.of({
@@ -108325,14 +108405,14 @@ var languages = [
108325
108405
  name: "LESS",
108326
108406
  extensions: ["less"],
108327
108407
  load() {
108328
- return import("./dist-DQpyDhfS.js").then((m) => m.less());
108408
+ return import("./dist-CeAwBeY0.js").then((m) => m.less());
108329
108409
  }
108330
108410
  }),
108331
108411
  /* @__PURE__ */ LanguageDescription.of({
108332
108412
  name: "Liquid",
108333
108413
  extensions: ["liquid"],
108334
108414
  load() {
108335
- return import("./dist-CHiBYKhO.js").then((m) => m.liquid());
108415
+ return import("./dist-C8tud7al.js").then((m) => m.liquid());
108336
108416
  }
108337
108417
  }),
108338
108418
  /* @__PURE__ */ LanguageDescription.of({
@@ -108349,7 +108429,7 @@ var languages = [
108349
108429
  "mkd"
108350
108430
  ],
108351
108431
  load() {
108352
- return import("./dist-DVnu9zoA.js").then((m) => m.markdown());
108432
+ return import("./dist-DVq3OitZ.js").then((m) => m.markdown());
108353
108433
  }
108354
108434
  }),
108355
108435
  /* @__PURE__ */ LanguageDescription.of({
@@ -108375,7 +108455,7 @@ var languages = [
108375
108455
  "phtml"
108376
108456
  ],
108377
108457
  load() {
108378
- return import("./dist-CUmPwPDw.js").then((m) => m.php());
108458
+ return import("./dist-BuA1hNQD.js").then((m) => m.php());
108379
108459
  }
108380
108460
  }),
108381
108461
  /* @__PURE__ */ LanguageDescription.of({
@@ -108415,14 +108495,14 @@ var languages = [
108415
108495
  name: "Sass",
108416
108496
  extensions: ["sass"],
108417
108497
  load() {
108418
- return import("./dist-Bi2hyX2D.js").then((m) => m.sass({ indented: true }));
108498
+ return import("./dist-uLS_wgVI.js").then((m) => m.sass({ indented: true }));
108419
108499
  }
108420
108500
  }),
108421
108501
  /* @__PURE__ */ LanguageDescription.of({
108422
108502
  name: "SCSS",
108423
108503
  extensions: ["scss"],
108424
108504
  load() {
108425
- return import("./dist-Bi2hyX2D.js").then((m) => m.sass());
108505
+ return import("./dist-uLS_wgVI.js").then((m) => m.sass());
108426
108506
  }
108427
108507
  }),
108428
108508
  /* @__PURE__ */ LanguageDescription.of({
@@ -108489,7 +108569,7 @@ var languages = [
108489
108569
  alias: ["yml"],
108490
108570
  extensions: ["yaml", "yml"],
108491
108571
  load() {
108492
- return import("./dist-CIVGOe5c.js").then((m) => m.yaml());
108572
+ return import("./dist-DQfK_0MA.js").then((m) => m.yaml());
108493
108573
  }
108494
108574
  }),
108495
108575
  /* @__PURE__ */ LanguageDescription.of({
@@ -109376,13 +109456,13 @@ var languages = [
109376
109456
  name: "Vue",
109377
109457
  extensions: ["vue"],
109378
109458
  load() {
109379
- return import("./dist-D_mnjXV3.js").then((m) => m.vue());
109459
+ return import("./dist-cd39lbM_.js").then((m) => m.vue());
109380
109460
  }
109381
109461
  }),
109382
109462
  /* @__PURE__ */ LanguageDescription.of({
109383
109463
  name: "Angular Template",
109384
109464
  load() {
109385
- return import("./dist-CLOFOKCn.js").then((m) => m.angular());
109465
+ return import("./dist-BrgApT3v.js").then((m) => m.angular());
109386
109466
  }
109387
109467
  })
109388
109468
  ];
@@ -152756,6 +152836,33 @@ var { codeToHtml, codeToHast, codeToTokens, codeToTokensBase, codeToTokensWithTh
152756
152836
  engine: () => createOnigurumaEngine(import("./wasm-CzpHWGSE.js"))
152757
152837
  }), { guessEmbeddedLanguages });
152758
152838
  //#endregion
152839
+ //#region src/lib/remark-cli-task-parity.ts
152840
+ /**
152841
+ * Box prefix of a CLI 1.13.1 task line: at most one non-`]`/non-whitespace token
152842
+ * (optionally padded with whitespace) or a whitespace-only box. Mirrors
152843
+ * references/openspec/src/utils/task-progress.ts (pinned v1.13.1); the marker and
152844
+ * indentation are already consumed by list parsing, and links parse into link nodes
152845
+ * (never leading text), so the CLI's link-continuation guard holds structurally.
152846
+ */
152847
+ var CLI_TASK_BOX_PREFIX = /^\[(?:\s*([^\]\s]?)\s*\]|\s+\])(?=\s|$)/;
152848
+ /**
152849
+ * Mark unrecognized widened-form list items as task items with the CLI completion
152850
+ * semantics. GFM-recognized items (checked already set) are left untouched.
152851
+ */
152852
+ var remarkCliTaskParity = () => (tree) => {
152853
+ visit(tree, "listItem", (node) => {
152854
+ const item = node;
152855
+ if (item.checked !== null && item.checked !== void 0) return;
152856
+ const first = item.children.find((child) => child.type === "paragraph")?.children[0];
152857
+ if (!first || first.type !== "text") return;
152858
+ const text = first;
152859
+ const match = CLI_TASK_BOX_PREFIX.exec(text.value);
152860
+ if (!match) return;
152861
+ item.checked = (match[1] ?? "").toLowerCase() === "x";
152862
+ text.value = text.value.slice(match[0].length);
152863
+ });
152864
+ };
152865
+ //#endregion
152759
152866
  //#region src/components/markdown-content.tsx
152760
152867
  /**
152761
152868
  * Simple markdown renderer with GFM support and shiki code highlighting.
@@ -152768,7 +152875,7 @@ function MarkdownContent({ children, className = "", components, hastProcessors
152768
152875
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
152769
152876
  className: `markdown-content ${className}`,
152770
152877
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Markdown, {
152771
- remarkPlugins: [remarkGfm],
152878
+ remarkPlugins: [remarkGfm, remarkCliTaskParity],
152772
152879
  rehypePlugins,
152773
152880
  components: {
152774
152881
  ...annotationComponents,
@@ -169664,6 +169771,36 @@ function ReadonlyKanbanRow({ item, laneId, compact }) {
169664
169771
  });
169665
169772
  }
169666
169773
  //#endregion
169774
+ //#region src/lib/change-display-title.ts
169775
+ /**
169776
+ * Orthogonal intents (created 2026-09-12 Asia/Shanghai):
169777
+ * 1. Derive one shared display title for a Change across list, dashboard, and detail surfaces.
169778
+ * 2. Treat the proposal H1 as a human-readable title only when it is informative.
169779
+ * 3. Fall back to the change id (the CLI's own canonical name) otherwise.
169780
+ *
169781
+ * Original request (2026-09-12): Owner walkthrough: the Changes list showed the generic proposal
169782
+ * heading "Proposal" as the row title while Change Detail showed the change id — unify the scheme.
169783
+ */
169784
+ /**
169785
+ * Heading texts that carry no identity information. `openspec new change` scaffolds proposals with
169786
+ * the bare heading "# Proposal"; showing it as a row title reads as a parsing bug rather than a name.
169787
+ */
169788
+ var GENERIC_PROPOSAL_HEADINGS = new Set(["proposal"]);
169789
+ /**
169790
+ * One display title for a Change, identical on every surface.
169791
+ *
169792
+ * `name` is the legacy parser's proposal H1 (absent for parser-less custom schemas); the change id
169793
+ * is the CLI-owned canonical identity (`openspec list --json` names changes by directory). The H1
169794
+ * wins only when it is a real, differentiated title; generic headings and the id itself fall back
169795
+ * to the id, so no surface ever shows two different titles for the same Change.
169796
+ */
169797
+ function changeDisplayTitle(changeId, name) {
169798
+ const trimmed = name?.trim();
169799
+ if (!trimmed || trimmed === changeId) return changeId;
169800
+ if (GENERIC_PROPOSAL_HEADINGS.has(trimmed.toLowerCase())) return changeId;
169801
+ return trimmed;
169802
+ }
169803
+ //#endregion
169667
169804
  //#region src/lib/opsx-compose.ts
169668
169805
  var ACTION_QUERY_KEY = "action";
169669
169806
  var CHANGE_QUERY_KEY = "change";
@@ -169892,15 +170029,18 @@ function useChangeOperatorLauncher({ applyCurrent = true, archiveCurrent = true
169892
170029
  //#endregion
169893
170030
  //#region src/routes/board.tsx
169894
170031
  /**
169895
- * Orthogonal intents (updated 2026-07-28 Asia/Shanghai):
170032
+ * Orthogonal intents (updated 2026-09-18 Asia/Shanghai):
169896
170033
  * 1. Compose live Changes and Archives as independent objective Kanban regions.
169897
170034
  * 2. Bind live commands to shared Change Operators and current projection authority.
169898
170035
  * 3. Render static Board through the shared readonly presentation and archive range policy.
169899
170036
  * 4. Bound the live route to the shell block-size and contain competing page overflow.
170037
+ * 5. Normalize card titles through the shared changeDisplayTitle fallback.
169900
170038
  *
169901
170039
  * Contributor request (2026-07-18): add a Kanban-style Change view.
169902
170040
  * Owner decision (2026-07-28): implement objective OPSX lanes and shared Operator ownership.
169903
170041
  * Owner correction (2026-07-28): prevent competing horizontal scrollbars on narrow `/board`.
170042
+ * Original request (2026-09-18): owner walkthrough Case 5 — every Kanban card showed the
170043
+ * generic scaffold heading "Proposal"; Board never received the display-title fallback.
169904
170044
  */
169905
170045
  var RANGE_OPTIONS = [
169906
170046
  {
@@ -169926,8 +170066,14 @@ function Board() {
169926
170066
  const archivesState = useArchivesSubscription();
169927
170067
  const statusState = useOpsxStatusListSubscription(!staticMode);
169928
170068
  const [range, setRange] = (0, import_react.useState)("30d");
169929
- const activeItems = changesState.data ?? [];
169930
- const archivedItems = (0, import_react.useMemo)(() => filterKanbanArchives(archivesState.data ?? [], range), [archivesState.data, range]);
170069
+ const activeItems = (0, import_react.useMemo)(() => (changesState.data ?? []).map((change) => ({
170070
+ ...change,
170071
+ name: changeDisplayTitle(change.id, change.name)
170072
+ })), [changesState.data]);
170073
+ const archivedItems = (0, import_react.useMemo)(() => filterKanbanArchives(archivesState.data ?? [], range).map((archive) => ({
170074
+ ...archive,
170075
+ name: changeDisplayTitle(archive.id, archive.name)
170076
+ })), [archivesState.data, range]);
169931
170077
  const activeCurrent = changesState.data !== void 0 && !changesState.isLoading && !changesState.isUpdating && changesState.error === null;
169932
170078
  const archiveCurrent = archivesState.data !== void 0 && !archivesState.isLoading && !archivesState.isUpdating && archivesState.error === null;
169933
170079
  const applyStatusCurrent = statusState.data !== void 0 && statusState.authority.state === "current";
@@ -170094,36 +170240,6 @@ function ChangeRowChevron() {
170094
170240
  });
170095
170241
  }
170096
170242
  //#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
170127
170243
  //#region src/lib/change-workflow-phase.ts
170128
170244
  function classifyChangeWorkflowPhase(params) {
170129
170245
  if (params.hasStatus && params.trackedArtifactStatus === "blocked") return {
@@ -170237,6 +170353,8 @@ function useChangeListContinuity(incomingChanges, containerRef) {
170237
170353
  * 3. Preserve ChangeList row continuity and stale display together with collision-safe detail navigation.
170238
170354
  * 4. Keep the advanced New Change command reachable from the page header.
170239
170355
  * 5. Defer aggregate workflow Status until a primary Change row is renderable; preserve explicit failures.
170356
+ * 6. Render OpenSpec 1.13.1 change-list hygiene warnings on the direct plane without ever
170357
+ * turning a namespace directory into a row, task summary, or detail navigation target.
170240
170358
  *
170241
170359
  * Original request (2026-07-23): "现在页面数据的加载数据非常慢(比如dashboard页面、changes页面都要等待非常久,页面刷新后,似乎后台没有缓存一样,也要加载很久。"
170242
170360
  * Original request (2026-07-23): "List mutations and route changes preserve physical continuity through existing motion/View Transition patterns."
@@ -170248,16 +170366,71 @@ function useChangeListContinuity(incomingChanges, containerRef) {
170248
170366
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
170249
170367
  * Original request (2026-09-12): Owner walkthrough: unify the Change display title — generic
170250
170368
  * "# Proposal" headings fall back to the change id on every surface.
170369
+ * Original request (2026-09-17): "Openspec 1.13.1 释放了…" — change-list nested/warnings projection (update-openspec-cli-1131 Slice 2).
170251
170370
  */
170252
170371
  function buildStatusMap(statuses) {
170253
170372
  return new Map((statuses ?? []).map((status) => [status.changeName, status]));
170254
170373
  }
170374
+ /** Known OpenSpec 1.13.1 warning codes; every other code renders the generic fallback. */
170375
+ var CHANGE_LIST_WARNING_CODE_LABELS = { nested_change_directory: "Nested change directory" };
170376
+ function changeListWarningLabel(code) {
170377
+ return CHANGE_LIST_WARNING_CODE_LABELS[code] ?? "Change list hygiene warning";
170378
+ }
170379
+ /**
170380
+ * OpenSpec 1.13.1 hygiene warnings on the direct plane: the namespace directory, its
170381
+ * nested change names, and the upstream message verbatim. Display evidence only — no row,
170382
+ * no task summary, no detail-route link, and no read/write/repair attempt on the wrapped
170383
+ * directories (the CLI owns that message; OpenSpecUI only surfaces it).
170384
+ */
170385
+ function ChangeListHygieneWarnings({ warnings }) {
170386
+ if (warnings.length === 0) return null;
170387
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
170388
+ "data-change-list-warnings": true,
170389
+ role: "note",
170390
+ className: "space-y-2 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-sm text-amber-800 dark:text-amber-200",
170391
+ children: warnings.map((warning) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170392
+ className: "flex items-start gap-2",
170393
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
170394
+ className: "mt-0.5 h-4 w-4 shrink-0",
170395
+ "aria-hidden": true
170396
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170397
+ className: "min-w-0",
170398
+ children: [
170399
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170400
+ className: "font-medium",
170401
+ children: changeListWarningLabel(warning.code)
170402
+ }),
170403
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170404
+ className: "text-muted-foreground",
170405
+ children: " · "
170406
+ }),
170407
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170408
+ className: "break-all font-mono text-xs",
170409
+ children: warning.name
170410
+ }),
170411
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170412
+ className: "text-muted-foreground text-xs",
170413
+ children: ["wraps ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170414
+ className: "break-all font-mono",
170415
+ children: warning.nested.join(", ")
170416
+ })]
170417
+ }),
170418
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
170419
+ className: "mt-1 break-words text-xs",
170420
+ children: warning.message
170421
+ })
170422
+ ]
170423
+ })]
170424
+ }, `${warning.code}:${warning.name}`))
170425
+ });
170426
+ }
170255
170427
  function ChangeList() {
170256
170428
  const { data: changes, isLoading, isUpdating, error: changesError, rowErrors = [], progress = null } = useChangesSubscription();
170257
170429
  const listRef = (0, import_react.useRef)(null);
170258
170430
  const { data: statuses, isLoading: isStatusLoading, error: statusError } = useOpsxStatusListSubscription((changes?.length ?? 0) > 0);
170259
170431
  const displayedChanges = useChangeListContinuity(changes, listRef);
170260
170432
  const statusMap = buildStatusMap(statuses);
170433
+ const { data: hygieneWarnings } = useOpsxChangeListHygieneWarningsSubscription();
170261
170434
  const hasCurrentEmptyChanges = changes?.length === 0 && !changesError && !isUpdating;
170262
170435
  const showChangesFrame = (changes?.length ?? 0) > 0 || hasCurrentEmptyChanges;
170263
170436
  if (isLoading && !changes && !changesError) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -170312,6 +170485,7 @@ function ChangeList() {
170312
170485
  "."
170313
170486
  ]
170314
170487
  }),
170488
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeListHygieneWarnings, { warnings: hygieneWarnings ?? [] }),
170315
170489
  changesError ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170316
170490
  role: "alert",
170317
170491
  className: "border-destructive/40 bg-destructive/10 text-destructive flex items-center gap-2 rounded-md border px-3 py-2 text-sm",
@@ -173908,7 +174082,7 @@ var CONFIG_GUIDE_STAGE_META = {
173908
174082
  //#region src/components/config/config-guide.tsx
173909
174083
  var ConfigGuideContext = (0, import_react.createContext)(null);
173910
174084
  (0, import_react.lazy)(async () => {
173911
- return { default: (await import("./config-guide-presentation-B5oRLCcX.js")).ConfigGuidePresentationLayer };
174085
+ return { default: (await import("./config-guide-presentation-BQdHuc5R.js")).ConfigGuidePresentationLayer };
173912
174086
  });
173913
174087
  /** Access the root-owned adaptive Guide runtime. */
173914
174088
  function useConfigGuide() {
@@ -178938,6 +179112,8 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
178938
179112
  *
178939
179113
  * Original request (2026-07-16): "接下来,你来接手后续工作"
178940
179114
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
179115
+ * Original request (2026-09-18): owner walkthrough Case 5 — the compact Kanban cards kept the
179116
+ * generic scaffold heading "Proposal"; normalize active/archive card names once at the route.
178941
179117
  * Derived requirement (2026-07-19): Checkpoint 6.11 preserves Git handoff and action provenance.
178942
179118
  * Original request (2026-07-23): "现在页面数据的加载数据非常慢(比如dashboard页面、changes页面都要等待非常久,页面刷新后,似乎后台没有缓存一样,也要加载很久。"
178943
179119
  * Original request (2026-07-27): "统一修复所有类似的问题(我们也没不多,各个页面都检查一下,特别是app 那边新增的页面)"
@@ -179192,7 +179368,14 @@ function Dashboard() {
179192
179368
  gitAutoRefreshPreset,
179193
179369
  staticMode
179194
179370
  ]);
179195
- const activeChanges = summaryProjection?.activeChanges ?? [];
179371
+ const activeChanges = (0, import_react.useMemo)(() => (summaryProjection?.activeChanges ?? []).map((change) => ({
179372
+ ...change,
179373
+ name: changeDisplayTitle(change.id, change.name)
179374
+ })), [summaryProjection?.activeChanges]);
179375
+ const kanbanArchivedItems = (0, import_react.useMemo)(() => (summaryProjection?.recentArchives ?? []).map((archive) => ({
179376
+ ...archive,
179377
+ name: changeDisplayTitle(archive.id, archive.name)
179378
+ })), [summaryProjection?.recentArchives]);
179196
179379
  const activeChangeIdSet = (0, import_react.useMemo)(() => new Set(activeChanges.map((change) => change.id)), [activeChanges]);
179197
179380
  const activeStatuses = (0, import_react.useMemo)(() => {
179198
179381
  return (statuses ?? []).filter((status) => activeChangeIdSet.has(status.changeName));
@@ -179291,7 +179474,7 @@ function Dashboard() {
179291
179474
  variant: "compact",
179292
179475
  pending: summaryPending,
179293
179476
  activeItems: activeChanges,
179294
- archivedItems: summaryProjection?.recentArchives ?? [],
179477
+ archivedItems: kanbanArchivedItems,
179295
179478
  activeCounts: summaryProjection?.trackedTaskPhaseCounts ?? {
179296
179479
  "no-tasks": 0,
179297
179480
  "in-progress": 0,
@@ -1,5 +1,5 @@
1
1
  import { it as extensions } from "./Geometry-jQ4l8GtP.js";
2
- import { M as FilterPipe, j as FilterSystem } from "./entry-server-CXwaLjrK.js";
2
+ import { M as FilterPipe, j as FilterSystem } from "./entry-server-DOzQvxeU.js";
3
3
  //#region ../../node_modules/.pnpm/pixi.js@8.16.0/node_modules/pixi.js/lib/filters/init.mjs
4
4
  extensions.add(FilterSystem);
5
5
  extensions.add(FilterPipe);
@@ -0,0 +1,3 @@
1
+ import "./jsx-runtime-CQL-l9BP.js";
2
+ import { Nt as trpcClient } from "./entry-server-DOzQvxeU.js";
3
+ export { trpcClient };
@@ -0,0 +1,4 @@
1
+ import "./Geometry-jQ4l8GtP.js";
2
+ import "./entry-server-DOzQvxeU.js";
3
+ import "./init-Dw3wIW5D.js";
4
+ export {};