@openspecui/web 13.0.0 → 13.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/assets/{App-Cq2vfNv0.js → App-BFiJJmOe.js} +150 -150
  2. package/dist/assets/App-CJAg_zBM.css +1 -0
  3. package/dist/assets/{main-CjHLYXqj.js → main-DP5AA7T8.js} +2 -2
  4. package/dist/assets/{trpc-BJDrN6rb.js → trpc-CoFrOhYa.js} +1 -1
  5. package/dist/index.html +1 -1
  6. package/dist-ssg/client/.vite/ssr-manifest.json +39 -29
  7. package/dist-ssg/client/assets/CanvasRenderer-9Cqh3Omm.js +1 -0
  8. package/dist-ssg/client/assets/WebGLRenderer-BuKPvwwK.js +1 -0
  9. package/dist-ssg/client/assets/WebGPURenderer-D--aziy9.js +1 -0
  10. package/dist-ssg/client/assets/browserAll-B2xWksCP.js +1 -0
  11. package/dist-ssg/client/assets/{config-guide-presentation-BYWAVHG-.js → config-guide-presentation-BnPXaBWb.js} +1 -1
  12. package/dist-ssg/client/assets/dist--Ym0xKR0.js +1 -0
  13. package/dist-ssg/client/assets/{dist-DFWGpO_L.js → dist-B-VN_V_x.js} +1 -1
  14. package/dist-ssg/client/assets/{dist-DBbVV3c6.js → dist-BD-45k70.js} +1 -1
  15. package/dist-ssg/client/assets/{dist-CT1adEON.js → dist-BRAQcINV.js} +1 -1
  16. package/dist-ssg/client/assets/{dist-DUzLJ7IR.js → dist-BY_UBuCJ.js} +1 -1
  17. package/dist-ssg/client/assets/{dist-DvnWUGiW.js → dist-BpGxtKw4.js} +1 -1
  18. package/dist-ssg/client/assets/{dist-B014oKqB.js → dist-CTLF_n4x.js} +1 -1
  19. package/dist-ssg/client/assets/dist-CWSG-_Cm.js +1 -0
  20. package/dist-ssg/client/assets/{dist-PNypP3x_.js → dist-CaJDVBYQ.js} +1 -1
  21. package/dist-ssg/client/assets/{dist-DtpQCgKd.js → dist-CqGjG57_.js} +1 -1
  22. package/dist-ssg/client/assets/{dist-B7XysJsL.js → dist-UdCD0Xt7.js} +1 -1
  23. package/dist-ssg/client/assets/dist-yI5mAB5M.js +1 -0
  24. package/dist-ssg/client/assets/{ghostty-web-DSqlIAa4.js → ghostty-web-B4UZWg1Q.js} +1 -1
  25. package/dist-ssg/client/assets/index--tFLAZQ-.css +1 -0
  26. package/dist-ssg/client/assets/{index.ssg-CJP1DN4-.js → index.ssg-DNgiMN3S.js} +93 -93
  27. package/dist-ssg/client/assets/{init-ORkrPTI8.js → init-DFr9qeU_.js} +1 -1
  28. package/dist-ssg/client/assets/{trpc-DimmQX0m.js → trpc-DyWBkNL8.js} +1 -1
  29. package/dist-ssg/client/assets/webworkerAll-ChxVgXMo.js +1 -0
  30. package/dist-ssg/client/index.ssg.html +2 -2
  31. package/dist-ssg/server/assets/CanvasRenderer-VdoPCddE.js +3 -0
  32. package/dist-ssg/server/assets/WebGLRenderer-BGWO4Aaa.js +3 -0
  33. package/dist-ssg/server/assets/WebGPURenderer-BBiS4Qa7.js +3 -0
  34. package/dist-ssg/server/assets/{browserAll-BoaMSEnC.js → browserAll-MoEM-nXs.js} +2 -2
  35. package/dist-ssg/server/assets/{config-guide-presentation-B5oRLCcX.js → config-guide-presentation-Cji5XRfB.js} +1 -1
  36. package/dist-ssg/server/assets/{dist-Bi2hyX2D.js → dist-0aQeTIoi.js} +1 -1
  37. package/dist-ssg/server/assets/{dist-DQpyDhfS.js → dist-3qCMKg-J.js} +1 -1
  38. package/dist-ssg/server/assets/{dist-DVnu9zoA.js → dist-BC_SFEy1.js} +1 -1
  39. package/dist-ssg/server/assets/{dist-CHiBYKhO.js → dist-Bje3KXXQ.js} +1 -1
  40. package/dist-ssg/server/assets/{dist-D_mnjXV3.js → dist-BysPZ53t.js} +1 -1
  41. package/dist-ssg/server/assets/{dist-BTp4dJw4.js → dist-C8dQw205.js} +1 -1
  42. package/dist-ssg/server/assets/dist-CJQNYu8f.js +3 -0
  43. package/dist-ssg/server/assets/dist-Cby8evAB.js +3 -0
  44. package/dist-ssg/server/assets/{dist-CLOFOKCn.js → dist-DBlIdFv8.js} +1 -1
  45. package/dist-ssg/server/assets/{dist-C4EXY8oH.js → dist-DpiAsvsU.js} +1 -1
  46. package/dist-ssg/server/assets/dist-J8FQ60oq.js +3 -0
  47. package/dist-ssg/server/assets/{dist-CUmPwPDw.js → dist-KtEgkR36.js} +1 -1
  48. package/dist-ssg/server/assets/{entry-server-CXwaLjrK.js → entry-server-BqIqbfZo.js} +391 -78
  49. package/dist-ssg/server/assets/{init-B1eN597N.js → init-D4SqIz1z.js} +1 -1
  50. package/dist-ssg/server/assets/trpc-ui6oSp6K.js +3 -0
  51. package/dist-ssg/server/assets/webworkerAll-V-joRC8L.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-CYwWbLgm.css +0 -1
  55. package/dist-ssg/client/assets/CanvasRenderer-BAnUeHzl.js +0 -1
  56. package/dist-ssg/client/assets/WebGLRenderer-DehTnF66.js +0 -1
  57. package/dist-ssg/client/assets/WebGPURenderer-BCXAr50t.js +0 -1
  58. package/dist-ssg/client/assets/browserAll-Brx8TmCT.js +0 -1
  59. package/dist-ssg/client/assets/dist-BKcEPt5U.js +0 -1
  60. package/dist-ssg/client/assets/dist-BZVFJHY_.js +0 -1
  61. package/dist-ssg/client/assets/dist-qdJFVZmv.js +0 -1
  62. package/dist-ssg/client/assets/index-CMfi0IZJ.css +0 -1
  63. package/dist-ssg/client/assets/webworkerAll-DjsDtAjh.js +0 -1
  64. package/dist-ssg/server/assets/CanvasRenderer-CvVvHnla.js +0 -3
  65. package/dist-ssg/server/assets/WebGLRenderer-ZTMKqKjr.js +0 -3
  66. package/dist-ssg/server/assets/WebGPURenderer-BaTRp8M6.js +0 -3
  67. package/dist-ssg/server/assets/dist-CIVGOe5c.js +0 -3
  68. package/dist-ssg/server/assets/dist-DAIXBI5T.js +0 -3
  69. package/dist-ssg/server/assets/dist-fy1m8mbf.js +0 -3
  70. package/dist-ssg/server/assets/trpc-BQ6eyI7t.js +0 -3
  71. 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-ui6oSp6K.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-ui6oSp6K.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
31055
31059
  key: this.storageKey,
31056
31060
  value: {
31057
31061
  mainTabs: this.state.mainTabs,
@@ -38940,6 +38944,60 @@ 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-26 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
+ * 10. Type the OpenSpec 1.13.2 Apply tracking-evidence members (`taskTrackingConfigured`
38973
+ * boolean, `unavailableTrackingFiles` `{path, reason}[]`) as additive optional success
38974
+ * members: 1.13.2 always emits the boolean while 1.13.0/1.13.1 (still admitted) emit
38975
+ * neither, so absence stays "unknown" and is never synthesized; the array is
38976
+ * absent-when-everything-is-readable and both stay verbatim evidence.
38977
+ *
38978
+ * Original request (2026-07-15): "为不同命令建立强类型适配器,不实现平行解析规则。"
38979
+ * Original request (2026-07-26): "展开全面的接口升级和内核升级和测试升级。"
38980
+ * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
38981
+ * Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。"
38982
+ * Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。"
38983
+ * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
38984
+ * Original request (2026-09-17): "Openspec 1.13.1 释放了…" — change-list nested/warnings projection (update-openspec-cli-1131 Slice 2).
38985
+ * Original request (2026-09-26): "Openspec 1.13.2 释放了…" — Apply tracking-evidence decode contract (update-openspec-cli-1132 Slice 2).
38986
+ */
38987
+ /**
38988
+ * One top-level change-list hygiene warning (OpenSpec 1.13.1 `list --json`).
38989
+ *
38990
+ * `code` is an open string, not a literal: the upstream contract documents
38991
+ * `nested_change_directory` as the only current code while reserving room for more, so an
38992
+ * in-window patch adding a code must survive decode as evidence instead of failing the
38993
+ * whole document. The whole array is absent when empty (never `null`, never `[]`).
38994
+ */
38995
+ var CliChangeListWarningSchema = objectType({
38996
+ code: stringType(),
38997
+ name: stringType(),
38998
+ nested: arrayType(stringType()),
38999
+ message: stringType()
39000
+ }).passthrough();
38943
39001
  objectType({
38944
39002
  changes: arrayType(objectType({
38945
39003
  name: stringType(),
@@ -38950,8 +39008,10 @@ objectType({
38950
39008
  "no-tasks",
38951
39009
  "complete",
38952
39010
  "in-progress"
38953
- ])
39011
+ ]),
39012
+ nested: arrayType(stringType()).optional()
38954
39013
  }).passthrough()),
39014
+ warnings: arrayType(CliChangeListWarningSchema).optional(),
38955
39015
  root: CliRootSchema.nullable(),
38956
39016
  status: arrayType(CliDiagnosticSchema).optional()
38957
39017
  }).passthrough();
@@ -39118,6 +39178,11 @@ unionType([objectType({
39118
39178
  missingArtifacts: arrayType(stringType()).optional(),
39119
39179
  missingPrerequisites: arrayType(stringType()).optional(),
39120
39180
  warnings: arrayType(stringType()).optional(),
39181
+ taskTrackingConfigured: booleanType().optional(),
39182
+ unavailableTrackingFiles: arrayType(objectType({
39183
+ path: stringType(),
39184
+ reason: stringType()
39185
+ })).optional(),
39121
39186
  instruction: stringType(),
39122
39187
  references: arrayType(CliReferenceIndexEntrySchema).optional(),
39123
39188
  context: stringType().optional(),
@@ -43345,7 +43410,7 @@ function createApplyInstructionProgress(input, trackedTaskProgress) {
43345
43410
  //#endregion
43346
43411
  //#region ../core/src/opsx-types.ts
43347
43412
  /**
43348
- * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
43413
+ * Orthogonal intents (updated 2026-09-26 Asia/Shanghai):
43349
43414
  * 1. Publish runtime schemas for final Projection Work payloads, including transformed Apply progress.
43350
43415
  * 2. Keep isPlanningComplete as the authoritative planning fact over any local tracked alias.
43351
43416
  * 3. Carry CLI status evidence, diagnostics, and per-artifact requires as typed facts.
@@ -43354,10 +43419,18 @@ function createApplyInstructionProgress(input, trackedTaskProgress) {
43354
43419
  * 6. Project the OpenSpec 1.13 Apply `warnings` and `missingPrerequisites` fields through the
43355
43420
  * input and final projection schemas verbatim: optional everywhere, never defaulted to
43356
43421
  * empty arrays, and never allowed to alter state/progress/tasks semantics.
43422
+ * 7. Project the OpenSpec 1.13.2 Apply tracking-evidence members (`taskTrackingConfigured`,
43423
+ * `unavailableTrackingFiles`) the same way: absent-when-upstream-absent (never a
43424
+ * synthesized `false` or empty array), verbatim evidence, never apply gating.
43425
+ * 8. Keep `isGlobPattern` a verbatim parity port of the pinned CLI's artifact-graph
43426
+ * recognition (OpenSpec 1.13.2, references/openspec/src/core/artifact-graph/outputs.ts):
43427
+ * original wildcards plus extglob groups and brace expansions after POSIX separator
43428
+ * normalization — watcher-granularity only, so dependency watching never forks upstream.
43357
43429
  *
43358
43430
  * Original request (2026-07-15): "为内核载荷建立强类型。"
43359
43431
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
43360
43432
  * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
43433
+ * Original request (2026-09-26): "Openspec 1.13.2 释放了…" — tracking-evidence projection + glob-recognition watcher parity (update-openspec-cli-1132 Slice 2).
43361
43434
  */
43362
43435
  /** Runtime schema for one JSON value retained from a CLI Status stdout document. */
43363
43436
  var OpsxCliJsonValueSchema = lazyType(() => unionType([
@@ -43453,6 +43526,11 @@ var ApplyInstructionsInputSchema = objectType({
43453
43526
  missingArtifacts: arrayType(stringType()).optional(),
43454
43527
  missingPrerequisites: arrayType(stringType()).optional(),
43455
43528
  warnings: arrayType(stringType()).optional(),
43529
+ taskTrackingConfigured: booleanType().optional(),
43530
+ unavailableTrackingFiles: arrayType(objectType({
43531
+ path: stringType(),
43532
+ reason: stringType()
43533
+ })).optional(),
43456
43534
  instruction: stringType(),
43457
43535
  references: arrayType(CliReferenceIndexEntrySchema).optional(),
43458
43536
  context: stringType().optional(),
@@ -43504,6 +43582,11 @@ var ApplyInstructionsProjectionSchema = objectType({
43504
43582
  missingArtifacts: arrayType(stringType()).optional(),
43505
43583
  missingPrerequisites: arrayType(stringType()).optional(),
43506
43584
  warnings: arrayType(stringType()).optional(),
43585
+ taskTrackingConfigured: booleanType().optional(),
43586
+ unavailableTrackingFiles: arrayType(objectType({
43587
+ path: stringType(),
43588
+ reason: stringType()
43589
+ })).optional(),
43507
43590
  instruction: stringType(),
43508
43591
  references: arrayType(CliReferenceIndexEntrySchema).optional(),
43509
43592
  context: stringType().optional(),
@@ -43594,8 +43677,13 @@ var TemplateContentMapSchema = recordType(stringType(), TemplateContentSchema);
43594
43677
  * 2. Define the runtime-environment Environment Global projection contract.
43595
43678
  * 3. Publish browser-safe lifecycle Pull schemas without importing Node-owned Core modules.
43596
43679
  * 4. Keep projection data discriminated across Status and Artifact/Apply/Archive Instructions.
43680
+ * 5. Model the OpenSpec 1.13.1 change-list namespace facts beside the actionable set:
43681
+ * `entries`/`value` stay actionable-only, `namespaces` is the single structural
43682
+ * namespace-name set for row builders, and `warnings` is passthrough display evidence
43683
+ * (absent when the CLI omitted it, never a synthesized empty array).
43597
43684
  *
43598
43685
  * Original request (2026-07-26): "展开全面的接口升级和内核升级和测试升级。"
43686
+ * Original request (2026-09-17): "Openspec 1.13.1 释放了…" — change-list nested/warnings projection (update-openspec-cli-1131 Slice 2).
43599
43687
  */
43600
43688
  /** Runtime selector for one Planning-root CLI-backed projection. */
43601
43689
  var PlanningCliProjectionSelectorSchema = discriminatedUnionType("kind", [
@@ -43657,6 +43745,8 @@ var PlanningCliProjectionStateSchema = createCliProjectionStateSchema(discrimina
43657
43745
  "in-progress"
43658
43746
  ])
43659
43747
  })),
43748
+ namespaces: arrayType(stringType()),
43749
+ warnings: arrayType(CliChangeListWarningSchema).optional(),
43660
43750
  evidence: CliProjectionCommandEvidenceSchema
43661
43751
  }),
43662
43752
  objectType({
@@ -44863,6 +44953,25 @@ function useOpsxApplyInstructionsSubscription(input) {
44863
44953
  isLoading: false
44864
44954
  };
44865
44955
  }
44956
+ /**
44957
+ * OpenSpec 1.13.1 change-list hygiene warnings (e.g. `nested_change_directory`).
44958
+ *
44959
+ * Display evidence only: the CLI's verbatim warning array rides beside the actionable
44960
+ * change list; it never gates row visibility or mutation authority. Static publication
44961
+ * carries no CLI lifecycle evidence, so the static loader resolves no warnings — an empty
44962
+ * list there is absence of evidence, not a fabricated clean bill of health.
44963
+ */
44964
+ function useOpsxChangeListHygieneWarningsSubscription() {
44965
+ return useCliProjectionSubscription({
44966
+ selector: { kind: "opsx-change-list" },
44967
+ selectData(data) {
44968
+ if (data.kind !== "opsx-change-list") throw new Error(`Expected opsx-change-list projection, received ${data.kind}.`);
44969
+ return data.warnings ?? [];
44970
+ },
44971
+ staticLoader: async () => [],
44972
+ cacheKey: "opsx.changeListHygieneWarnings"
44973
+ });
44974
+ }
44866
44975
  function useOpsxArtifactOutputSubscription(changeId, outputPath) {
44867
44976
  return useSubscription((0, import_react.useCallback)((callbacks) => {
44868
44977
  if (!changeId || !outputPath) {
@@ -71316,7 +71425,7 @@ var browserExt = {
71316
71425
  },
71317
71426
  test: () => true,
71318
71427
  load: async () => {
71319
- await import("./browserAll-BoaMSEnC.js");
71428
+ await import("./browserAll-MoEM-nXs.js");
71320
71429
  }
71321
71430
  };
71322
71431
  //#endregion
@@ -71329,7 +71438,7 @@ var webworkerExt = {
71329
71438
  },
71330
71439
  test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
71331
71440
  load: async () => {
71332
- await import("./webworkerAll-bAKoC1FD.js");
71441
+ await import("./webworkerAll-V-joRC8L.js");
71333
71442
  }
71334
71443
  };
71335
71444
  //#endregion
@@ -73923,7 +74032,7 @@ async function autoDetectRenderer(options) {
73923
74032
  for (let i = 0; i < preferredOrder.length; i++) {
73924
74033
  const rendererType = preferredOrder[i];
73925
74034
  if (rendererType === "webgpu" && await isWebGPUSupported()) {
73926
- const { WebGPURenderer } = await import("./WebGPURenderer-BaTRp8M6.js");
74035
+ const { WebGPURenderer } = await import("./WebGPURenderer-BBiS4Qa7.js");
73927
74036
  RendererClass = WebGPURenderer;
73928
74037
  finalOptions = {
73929
74038
  ...options,
@@ -73931,7 +74040,7 @@ async function autoDetectRenderer(options) {
73931
74040
  };
73932
74041
  break;
73933
74042
  } else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
73934
- const { WebGLRenderer } = await import("./WebGLRenderer-ZTMKqKjr.js");
74043
+ const { WebGLRenderer } = await import("./WebGLRenderer-BGWO4Aaa.js");
73935
74044
  RendererClass = WebGLRenderer;
73936
74045
  finalOptions = {
73937
74046
  ...options,
@@ -73939,7 +74048,7 @@ async function autoDetectRenderer(options) {
73939
74048
  };
73940
74049
  break;
73941
74050
  } else if (rendererType === "canvas") {
73942
- const { CanvasRenderer } = await import("./CanvasRenderer-CvVvHnla.js");
74051
+ const { CanvasRenderer } = await import("./CanvasRenderer-VdoPCddE.js");
73943
74052
  RendererClass = CanvasRenderer;
73944
74053
  finalOptions = {
73945
74054
  ...options,
@@ -97688,7 +97797,7 @@ var TerminalController = class {
97688
97797
  if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
97689
97798
  this.configPersistTimer = setTimeout(() => {
97690
97799
  this.configPersistTimer = null;
97691
- import("./trpc-BQ6eyI7t.js").then(({ trpcClient }) => {
97800
+ import("./trpc-ui6oSp6K.js").then(({ trpcClient }) => {
97692
97801
  trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
97693
97802
  }).catch(() => {});
97694
97803
  }, CONFIG_PERSIST_DEBOUNCE);
@@ -108249,7 +108358,7 @@ var languages = [
108249
108358
  name: "CSS",
108250
108359
  extensions: ["css"],
108251
108360
  load() {
108252
- return import("./dist-fy1m8mbf.js").then((m) => m.css());
108361
+ return import("./dist-Cby8evAB.js").then((m) => m.css());
108253
108362
  }
108254
108363
  }),
108255
108364
  /* @__PURE__ */ LanguageDescription.of({
@@ -108269,7 +108378,7 @@ var languages = [
108269
108378
  "hbs"
108270
108379
  ],
108271
108380
  load() {
108272
- return import("./dist-C4EXY8oH.js").then((m) => m.html());
108381
+ return import("./dist-DpiAsvsU.js").then((m) => m.html());
108273
108382
  }
108274
108383
  }),
108275
108384
  /* @__PURE__ */ LanguageDescription.of({
@@ -108303,7 +108412,7 @@ var languages = [
108303
108412
  "jinja2"
108304
108413
  ],
108305
108414
  load() {
108306
- return import("./dist-BTp4dJw4.js").then((m) => m.jinja());
108415
+ return import("./dist-C8dQw205.js").then((m) => m.jinja());
108307
108416
  }
108308
108417
  }),
108309
108418
  /* @__PURE__ */ LanguageDescription.of({
@@ -108311,7 +108420,7 @@ var languages = [
108311
108420
  alias: ["json5"],
108312
108421
  extensions: ["json", "map"],
108313
108422
  load() {
108314
- return import("./dist-DAIXBI5T.js").then((m) => m.json());
108423
+ return import("./dist-CJQNYu8f.js").then((m) => m.json());
108315
108424
  }
108316
108425
  }),
108317
108426
  /* @__PURE__ */ LanguageDescription.of({
@@ -108325,14 +108434,14 @@ var languages = [
108325
108434
  name: "LESS",
108326
108435
  extensions: ["less"],
108327
108436
  load() {
108328
- return import("./dist-DQpyDhfS.js").then((m) => m.less());
108437
+ return import("./dist-3qCMKg-J.js").then((m) => m.less());
108329
108438
  }
108330
108439
  }),
108331
108440
  /* @__PURE__ */ LanguageDescription.of({
108332
108441
  name: "Liquid",
108333
108442
  extensions: ["liquid"],
108334
108443
  load() {
108335
- return import("./dist-CHiBYKhO.js").then((m) => m.liquid());
108444
+ return import("./dist-Bje3KXXQ.js").then((m) => m.liquid());
108336
108445
  }
108337
108446
  }),
108338
108447
  /* @__PURE__ */ LanguageDescription.of({
@@ -108349,7 +108458,7 @@ var languages = [
108349
108458
  "mkd"
108350
108459
  ],
108351
108460
  load() {
108352
- return import("./dist-DVnu9zoA.js").then((m) => m.markdown());
108461
+ return import("./dist-BC_SFEy1.js").then((m) => m.markdown());
108353
108462
  }
108354
108463
  }),
108355
108464
  /* @__PURE__ */ LanguageDescription.of({
@@ -108375,7 +108484,7 @@ var languages = [
108375
108484
  "phtml"
108376
108485
  ],
108377
108486
  load() {
108378
- return import("./dist-CUmPwPDw.js").then((m) => m.php());
108487
+ return import("./dist-KtEgkR36.js").then((m) => m.php());
108379
108488
  }
108380
108489
  }),
108381
108490
  /* @__PURE__ */ LanguageDescription.of({
@@ -108415,14 +108524,14 @@ var languages = [
108415
108524
  name: "Sass",
108416
108525
  extensions: ["sass"],
108417
108526
  load() {
108418
- return import("./dist-Bi2hyX2D.js").then((m) => m.sass({ indented: true }));
108527
+ return import("./dist-0aQeTIoi.js").then((m) => m.sass({ indented: true }));
108419
108528
  }
108420
108529
  }),
108421
108530
  /* @__PURE__ */ LanguageDescription.of({
108422
108531
  name: "SCSS",
108423
108532
  extensions: ["scss"],
108424
108533
  load() {
108425
- return import("./dist-Bi2hyX2D.js").then((m) => m.sass());
108534
+ return import("./dist-0aQeTIoi.js").then((m) => m.sass());
108426
108535
  }
108427
108536
  }),
108428
108537
  /* @__PURE__ */ LanguageDescription.of({
@@ -108489,7 +108598,7 @@ var languages = [
108489
108598
  alias: ["yml"],
108490
108599
  extensions: ["yaml", "yml"],
108491
108600
  load() {
108492
- return import("./dist-CIVGOe5c.js").then((m) => m.yaml());
108601
+ return import("./dist-J8FQ60oq.js").then((m) => m.yaml());
108493
108602
  }
108494
108603
  }),
108495
108604
  /* @__PURE__ */ LanguageDescription.of({
@@ -109376,13 +109485,13 @@ var languages = [
109376
109485
  name: "Vue",
109377
109486
  extensions: ["vue"],
109378
109487
  load() {
109379
- return import("./dist-D_mnjXV3.js").then((m) => m.vue());
109488
+ return import("./dist-BysPZ53t.js").then((m) => m.vue());
109380
109489
  }
109381
109490
  }),
109382
109491
  /* @__PURE__ */ LanguageDescription.of({
109383
109492
  name: "Angular Template",
109384
109493
  load() {
109385
- return import("./dist-CLOFOKCn.js").then((m) => m.angular());
109494
+ return import("./dist-DBlIdFv8.js").then((m) => m.angular());
109386
109495
  }
109387
109496
  })
109388
109497
  ];
@@ -152756,6 +152865,33 @@ var { codeToHtml, codeToHast, codeToTokens, codeToTokensBase, codeToTokensWithTh
152756
152865
  engine: () => createOnigurumaEngine(import("./wasm-CzpHWGSE.js"))
152757
152866
  }), { guessEmbeddedLanguages });
152758
152867
  //#endregion
152868
+ //#region src/lib/remark-cli-task-parity.ts
152869
+ /**
152870
+ * Box prefix of a CLI 1.13.1 task line: at most one non-`]`/non-whitespace token
152871
+ * (optionally padded with whitespace) or a whitespace-only box. Mirrors
152872
+ * references/openspec/src/utils/task-progress.ts (pinned v1.13.1); the marker and
152873
+ * indentation are already consumed by list parsing, and links parse into link nodes
152874
+ * (never leading text), so the CLI's link-continuation guard holds structurally.
152875
+ */
152876
+ var CLI_TASK_BOX_PREFIX = /^\[(?:\s*([^\]\s]?)\s*\]|\s+\])(?=\s|$)/;
152877
+ /**
152878
+ * Mark unrecognized widened-form list items as task items with the CLI completion
152879
+ * semantics. GFM-recognized items (checked already set) are left untouched.
152880
+ */
152881
+ var remarkCliTaskParity = () => (tree) => {
152882
+ visit(tree, "listItem", (node) => {
152883
+ const item = node;
152884
+ if (item.checked !== null && item.checked !== void 0) return;
152885
+ const first = item.children.find((child) => child.type === "paragraph")?.children[0];
152886
+ if (!first || first.type !== "text") return;
152887
+ const text = first;
152888
+ const match = CLI_TASK_BOX_PREFIX.exec(text.value);
152889
+ if (!match) return;
152890
+ item.checked = (match[1] ?? "").toLowerCase() === "x";
152891
+ text.value = text.value.slice(match[0].length);
152892
+ });
152893
+ };
152894
+ //#endregion
152759
152895
  //#region src/components/markdown-content.tsx
152760
152896
  /**
152761
152897
  * Simple markdown renderer with GFM support and shiki code highlighting.
@@ -152768,7 +152904,7 @@ function MarkdownContent({ children, className = "", components, hastProcessors
152768
152904
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
152769
152905
  className: `markdown-content ${className}`,
152770
152906
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Markdown, {
152771
- remarkPlugins: [remarkGfm],
152907
+ remarkPlugins: [remarkGfm, remarkCliTaskParity],
152772
152908
  rehypePlugins,
152773
152909
  components: {
152774
152910
  ...annotationComponents,
@@ -156148,15 +156284,31 @@ function MarkdownFilesContent({ components, files, emptyMessage, translationConf
156148
156284
  //#endregion
156149
156285
  //#region src/components/opsx/artifact-output-viewer.tsx
156150
156286
  /**
156151
- * Orthogonal intents (updated 2026-08-01 Asia/Shanghai):
156287
+ * Orthogonal intents (updated 2026-09-26 Asia/Shanghai):
156152
156288
  * 1. Render single-file and glob artifact output from the current OPSX projection.
156153
156289
  * 2. Preserve schema-provided artifact fallbacks and document translation configuration.
156154
156290
  * 3. Distinguish initial output admission, missing output, and intentionally skipped non-output.
156291
+ * 4. Classify artifact outputs with the widened OpenSpec 1.13.2 glob syntax (brace/extglob),
156292
+ * mirroring the core `isGlobPattern` owner verbatim (subpath unification is recorded debt).
156155
156293
  *
156156
156294
  * Original request (2026-07-27): "统一修复所有类似的问题(我们也没不多,各个页面都检查一下,特别是app 那边新增的页面)"
156157
- */
156295
+ * Original request (2026-09-26): "Openspec 1.13.2 释放了…" — brace/extglob outputs render as glob content (update-openspec-cli-1132 Slice 2 fold).
156296
+ */
156297
+ var EXTGLOB_RE = /[!*+?@]\([^(]*\)/u;
156298
+ var BRACE_EXPANSION_SEPARATORS_RE = /,|\.\./u;
156299
+ function hasBraceExpansion(pattern) {
156300
+ const openings = [];
156301
+ for (let index = 0; index < pattern.length; index += 1) {
156302
+ if (pattern[index] === "{") openings.push(index);
156303
+ if (pattern[index] !== "}") continue;
156304
+ const opening = openings.pop();
156305
+ if (opening !== void 0 && BRACE_EXPANSION_SEPARATORS_RE.test(pattern.slice(opening, index))) return true;
156306
+ }
156307
+ return false;
156308
+ }
156158
156309
  function isGlobPattern(pattern) {
156159
- return pattern.includes("*") || pattern.includes("?") || pattern.includes("[");
156310
+ const normalized = pattern.replaceAll("\\", "/");
156311
+ return normalized.includes("*") || normalized.includes("?") || normalized.includes("[") || EXTGLOB_RE.test(normalized) || hasBraceExpansion(normalized);
156160
156312
  }
156161
156313
  function ArtifactOutputDocumentShell({ artifact, children }) {
156162
156314
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OpsxArtifactDocumentShell, {
@@ -169664,6 +169816,36 @@ function ReadonlyKanbanRow({ item, laneId, compact }) {
169664
169816
  });
169665
169817
  }
169666
169818
  //#endregion
169819
+ //#region src/lib/change-display-title.ts
169820
+ /**
169821
+ * Orthogonal intents (created 2026-09-12 Asia/Shanghai):
169822
+ * 1. Derive one shared display title for a Change across list, dashboard, and detail surfaces.
169823
+ * 2. Treat the proposal H1 as a human-readable title only when it is informative.
169824
+ * 3. Fall back to the change id (the CLI's own canonical name) otherwise.
169825
+ *
169826
+ * Original request (2026-09-12): Owner walkthrough: the Changes list showed the generic proposal
169827
+ * heading "Proposal" as the row title while Change Detail showed the change id — unify the scheme.
169828
+ */
169829
+ /**
169830
+ * Heading texts that carry no identity information. `openspec new change` scaffolds proposals with
169831
+ * the bare heading "# Proposal"; showing it as a row title reads as a parsing bug rather than a name.
169832
+ */
169833
+ var GENERIC_PROPOSAL_HEADINGS = new Set(["proposal"]);
169834
+ /**
169835
+ * One display title for a Change, identical on every surface.
169836
+ *
169837
+ * `name` is the legacy parser's proposal H1 (absent for parser-less custom schemas); the change id
169838
+ * is the CLI-owned canonical identity (`openspec list --json` names changes by directory). The H1
169839
+ * wins only when it is a real, differentiated title; generic headings and the id itself fall back
169840
+ * to the id, so no surface ever shows two different titles for the same Change.
169841
+ */
169842
+ function changeDisplayTitle(changeId, name) {
169843
+ const trimmed = name?.trim();
169844
+ if (!trimmed || trimmed === changeId) return changeId;
169845
+ if (GENERIC_PROPOSAL_HEADINGS.has(trimmed.toLowerCase())) return changeId;
169846
+ return trimmed;
169847
+ }
169848
+ //#endregion
169667
169849
  //#region src/lib/opsx-compose.ts
169668
169850
  var ACTION_QUERY_KEY = "action";
169669
169851
  var CHANGE_QUERY_KEY = "change";
@@ -169892,15 +170074,18 @@ function useChangeOperatorLauncher({ applyCurrent = true, archiveCurrent = true
169892
170074
  //#endregion
169893
170075
  //#region src/routes/board.tsx
169894
170076
  /**
169895
- * Orthogonal intents (updated 2026-07-28 Asia/Shanghai):
170077
+ * Orthogonal intents (updated 2026-09-18 Asia/Shanghai):
169896
170078
  * 1. Compose live Changes and Archives as independent objective Kanban regions.
169897
170079
  * 2. Bind live commands to shared Change Operators and current projection authority.
169898
170080
  * 3. Render static Board through the shared readonly presentation and archive range policy.
169899
170081
  * 4. Bound the live route to the shell block-size and contain competing page overflow.
170082
+ * 5. Normalize card titles through the shared changeDisplayTitle fallback.
169900
170083
  *
169901
170084
  * Contributor request (2026-07-18): add a Kanban-style Change view.
169902
170085
  * Owner decision (2026-07-28): implement objective OPSX lanes and shared Operator ownership.
169903
170086
  * Owner correction (2026-07-28): prevent competing horizontal scrollbars on narrow `/board`.
170087
+ * Original request (2026-09-18): owner walkthrough Case 5 — every Kanban card showed the
170088
+ * generic scaffold heading "Proposal"; Board never received the display-title fallback.
169904
170089
  */
169905
170090
  var RANGE_OPTIONS = [
169906
170091
  {
@@ -169926,8 +170111,14 @@ function Board() {
169926
170111
  const archivesState = useArchivesSubscription();
169927
170112
  const statusState = useOpsxStatusListSubscription(!staticMode);
169928
170113
  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]);
170114
+ const activeItems = (0, import_react.useMemo)(() => (changesState.data ?? []).map((change) => ({
170115
+ ...change,
170116
+ name: changeDisplayTitle(change.id, change.name)
170117
+ })), [changesState.data]);
170118
+ const archivedItems = (0, import_react.useMemo)(() => filterKanbanArchives(archivesState.data ?? [], range).map((archive) => ({
170119
+ ...archive,
170120
+ name: changeDisplayTitle(archive.id, archive.name)
170121
+ })), [archivesState.data, range]);
169931
170122
  const activeCurrent = changesState.data !== void 0 && !changesState.isLoading && !changesState.isUpdating && changesState.error === null;
169932
170123
  const archiveCurrent = archivesState.data !== void 0 && !archivesState.isLoading && !archivesState.isUpdating && archivesState.error === null;
169933
170124
  const applyStatusCurrent = statusState.data !== void 0 && statusState.authority.state === "current";
@@ -170094,36 +170285,6 @@ function ChangeRowChevron() {
170094
170285
  });
170095
170286
  }
170096
170287
  //#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
170288
  //#region src/lib/change-workflow-phase.ts
170128
170289
  function classifyChangeWorkflowPhase(params) {
170129
170290
  if (params.hasStatus && params.trackedArtifactStatus === "blocked") return {
@@ -170237,6 +170398,8 @@ function useChangeListContinuity(incomingChanges, containerRef) {
170237
170398
  * 3. Preserve ChangeList row continuity and stale display together with collision-safe detail navigation.
170238
170399
  * 4. Keep the advanced New Change command reachable from the page header.
170239
170400
  * 5. Defer aggregate workflow Status until a primary Change row is renderable; preserve explicit failures.
170401
+ * 6. Render OpenSpec 1.13.1 change-list hygiene warnings on the direct plane without ever
170402
+ * turning a namespace directory into a row, task summary, or detail navigation target.
170240
170403
  *
170241
170404
  * Original request (2026-07-23): "现在页面数据的加载数据非常慢(比如dashboard页面、changes页面都要等待非常久,页面刷新后,似乎后台没有缓存一样,也要加载很久。"
170242
170405
  * Original request (2026-07-23): "List mutations and route changes preserve physical continuity through existing motion/View Transition patterns."
@@ -170248,16 +170411,72 @@ function useChangeListContinuity(incomingChanges, containerRef) {
170248
170411
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
170249
170412
  * Original request (2026-09-12): Owner walkthrough: unify the Change display title — generic
170250
170413
  * "# Proposal" headings fall back to the change id on every surface.
170414
+ * Original request (2026-09-17): "Openspec 1.13.1 释放了…" — change-list nested/warnings projection (update-openspec-cli-1131 Slice 2).
170415
+ * Original request (2026-09-27): Owner walkthrough P3 adjudication — No tasks presentation for the CLI no-tasks status.
170251
170416
  */
170252
170417
  function buildStatusMap(statuses) {
170253
170418
  return new Map((statuses ?? []).map((status) => [status.changeName, status]));
170254
170419
  }
170420
+ /** Known OpenSpec 1.13.1 warning codes; every other code renders the generic fallback. */
170421
+ var CHANGE_LIST_WARNING_CODE_LABELS = { nested_change_directory: "Nested change directory" };
170422
+ function changeListWarningLabel(code) {
170423
+ return CHANGE_LIST_WARNING_CODE_LABELS[code] ?? "Change list hygiene warning";
170424
+ }
170425
+ /**
170426
+ * OpenSpec 1.13.1 hygiene warnings on the direct plane: the namespace directory, its
170427
+ * nested change names, and the upstream message verbatim. Display evidence only — no row,
170428
+ * no task summary, no detail-route link, and no read/write/repair attempt on the wrapped
170429
+ * directories (the CLI owns that message; OpenSpecUI only surfaces it).
170430
+ */
170431
+ function ChangeListHygieneWarnings({ warnings }) {
170432
+ if (warnings.length === 0) return null;
170433
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
170434
+ "data-change-list-warnings": true,
170435
+ role: "note",
170436
+ 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",
170437
+ children: warnings.map((warning) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170438
+ className: "flex items-start gap-2",
170439
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
170440
+ className: "mt-0.5 h-4 w-4 shrink-0",
170441
+ "aria-hidden": true
170442
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170443
+ className: "min-w-0",
170444
+ children: [
170445
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170446
+ className: "font-medium",
170447
+ children: changeListWarningLabel(warning.code)
170448
+ }),
170449
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170450
+ className: "text-muted-foreground",
170451
+ children: " · "
170452
+ }),
170453
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170454
+ className: "break-all font-mono text-xs",
170455
+ children: warning.name
170456
+ }),
170457
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170458
+ className: "text-muted-foreground text-xs",
170459
+ children: ["wraps ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170460
+ className: "break-all font-mono",
170461
+ children: warning.nested.join(", ")
170462
+ })]
170463
+ }),
170464
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
170465
+ className: "mt-1 break-words text-xs",
170466
+ children: warning.message
170467
+ })
170468
+ ]
170469
+ })]
170470
+ }, `${warning.code}:${warning.name}`))
170471
+ });
170472
+ }
170255
170473
  function ChangeList() {
170256
170474
  const { data: changes, isLoading, isUpdating, error: changesError, rowErrors = [], progress = null } = useChangesSubscription();
170257
170475
  const listRef = (0, import_react.useRef)(null);
170258
170476
  const { data: statuses, isLoading: isStatusLoading, error: statusError } = useOpsxStatusListSubscription((changes?.length ?? 0) > 0);
170259
170477
  const displayedChanges = useChangeListContinuity(changes, listRef);
170260
170478
  const statusMap = buildStatusMap(statuses);
170479
+ const { data: hygieneWarnings } = useOpsxChangeListHygieneWarningsSubscription();
170261
170480
  const hasCurrentEmptyChanges = changes?.length === 0 && !changesError && !isUpdating;
170262
170481
  const showChangesFrame = (changes?.length ?? 0) > 0 || hasCurrentEmptyChanges;
170263
170482
  if (isLoading && !changes && !changesError) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -170312,6 +170531,7 @@ function ChangeList() {
170312
170531
  "."
170313
170532
  ]
170314
170533
  }),
170534
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeListHygieneWarnings, { warnings: hygieneWarnings ?? [] }),
170315
170535
  changesError ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
170316
170536
  role: "alert",
170317
170537
  className: "border-destructive/40 bg-destructive/10 text-destructive flex items-center gap-2 rounded-md border px-3 py-2 text-sm",
@@ -170376,7 +170596,12 @@ function ChangeList() {
170376
170596
  });
170377
170597
  const cliTaskSummary = change.cliTaskSummary;
170378
170598
  const cliProgressRatio = cliTaskSummary && cliTaskSummary.totalTasks > 0 ? cliTaskSummary.completedTasks / cliTaskSummary.totalTasks : null;
170379
- const cliTaskEvidence = cliTaskSummary ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
170599
+ const cliNoTasks = cliTaskSummary?.status === "no-tasks" && cliTaskSummary.totalTasks === 0;
170600
+ const cliTaskEvidence = cliTaskSummary ? cliNoTasks ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
170601
+ className: "text-muted-foreground",
170602
+ title: "The OpenSpec CLI reports no tasks for this Change (no apply.tracks, or an empty tracked task list).",
170603
+ children: "No tasks"
170604
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
170380
170605
  title: "Task counts reported by the OpenSpec CLI for this Change.",
170381
170606
  children: [
170382
170607
  "Tasks ",
@@ -171454,7 +171679,7 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
171454
171679
  //#endregion
171455
171680
  //#region src/components/apply-progress-notice.tsx
171456
171681
  /**
171457
- * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
171682
+ * Orthogonal intents (updated 2026-09-26 Asia/Shanghai):
171458
171683
  * 1. Attribute Apply instruction counts to the upstream Apply command.
171459
171684
  * 2. Compress agreement to one subtitle badge; keep divergence a direct blocker.
171460
171685
  * 3. Keep divergence's two objective source counts side by side with their causes.
@@ -171467,6 +171692,14 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
171467
171692
  * semantics), including when the Apply state is already `ready`.
171468
171693
  * 7. Degrade to the previous presentation when either 1.13 field is absent — absent keys
171469
171694
  * are the upstream encoding for "none", so no empty state is ever synthesized.
171695
+ * 8. Render the OpenSpec 1.13.2 tracking evidence on the same direct plane: one amber
171696
+ * evidence line per unreadable `{path, reason}` with the same status semantics as the
171697
+ * warnings area, a compact note when the schema tracks no tasks (empty tasks are not
171698
+ * missing evidence), and nothing extra when both members are absent — absence is
171699
+ * "unknown (pre-1.13.2 CLI)", never a fabricated 0/0 or unavailable claim.
171700
+ * 9. Degrade, never hide, the subtitle badge's CLI numbers when the schema tracks no tasks:
171701
+ * `taskTrackingConfigured === false` lowers the badge's visual weight and appends the
171702
+ * qualification to its accessible name and tooltip; the numbers stay CLI-owned verbatim.
171470
171703
  *
171471
171704
  * Original request (2026-07-15): "与 tracked glob 进度分歧时各自归因展示。"
171472
171705
  * Original request (2026-07-28): supporting 6.x evidence should use Badge + Tooltip or Accordion.
@@ -171475,6 +171708,9 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
171475
171708
  * Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
171476
171709
  * Original request (2026-09-12): Owner walkthrough: the always-expanded warning/build-order blocks
171477
171710
  * consumed the page; collapse them behind one summary row while keeping direct-plane discovery.
171711
+ * Original request (2026-09-26): "Openspec 1.13.2 释放了…" — tracking-evidence surface (update-openspec-cli-1132 Slice 2).
171712
+ * Original request (2026-09-27): Owner walkthrough P3 adjudication — badge/list no-tracking count
171713
+ * presentation (clarify-no-tracking-task-counts).
171478
171714
  */
171479
171715
  /**
171480
171716
  * One compact, source-attributed Apply progress badge for the Change subtitle row.
@@ -171482,11 +171718,13 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
171482
171718
  * this stays rendered whenever instructions exist — agreement is not a reason to hide the
171483
171719
  * CLI's own count, but it needs no separate block.
171484
171720
  */
171485
- function ApplyProgressBadge({ applyInstructionProgress }) {
171721
+ function ApplyProgressBadge({ applyInstructionProgress, taskTrackingConfigured }) {
171486
171722
  const { complete, total, remaining } = applyInstructionProgress;
171723
+ const untracked = taskTrackingConfigured === false;
171487
171724
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
171488
- ariaLabel: `Apply instructions progress ${complete} of ${total}`,
171489
- tooltip: `Progress reported by openspec instructions apply — ${complete} of ${total} tasks applied, ${remaining} remaining.`,
171725
+ ariaLabel: `Apply instructions progress ${complete} of ${total}${untracked ? "; schema tracks no tasks" : ""}`,
171726
+ tooltip: untracked ? `Progress reported by openspec instructions apply — ${complete} of ${total} tasks applied, ${remaining} remaining. The schema sets no apply.tracks, so 0 of 0 is not incomplete work.` : `Progress reported by openspec instructions apply — ${complete} of ${total} tasks applied, ${remaining} remaining.`,
171727
+ className: untracked ? "opacity-75" : void 0,
171490
171728
  children: [
171491
171729
  "Apply ",
171492
171730
  complete,
@@ -171502,16 +171740,21 @@ var GUIDANCE_DETAIL_ID = "apply-readiness-guidance-detail";
171502
171740
  * Render the Apply/tracked divergence as one direct, source-attributed blocker, plus the
171503
171741
  * OpenSpec 1.13 `warnings` and `missingPrerequisites` evidence as one collapsible summary row:
171504
171742
  * 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.
171743
+ * and expanding reveals the verbatim upstream evidence on the same direct plane. The OpenSpec
171744
+ * 1.13.2 tracking evidence rides the same plane: unreadable tracking files render one amber
171745
+ * evidence line each (path + verbatim reason) and a no-tracking schema renders a compact note
171746
+ * so its empty task list is never read as missing evidence.
171506
171747
  * 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.
171748
+ * {@link ApplyProgressBadge}, and absent upstream keys render nothing.
171508
171749
  */
171509
- function ApplyProgressNotice({ applyInstructionProgress, warnings, missingPrerequisites }) {
171750
+ function ApplyProgressNotice({ applyInstructionProgress, warnings, missingPrerequisites, taskTrackingConfigured, unavailableTrackingFiles }) {
171510
171751
  const divergence = applyInstructionProgress.divergence;
171511
171752
  const hasWarnings = (warnings?.length ?? 0) > 0;
171512
171753
  const hasPrerequisites = (missingPrerequisites?.length ?? 0) > 0;
171754
+ const hasUnavailableTracking = (unavailableTrackingFiles?.length ?? 0) > 0;
171755
+ const tracksNoTasks = taskTrackingConfigured === false;
171513
171756
  const [expanded, setExpanded] = (0, import_react.useState)(false);
171514
- if (!divergence && !hasWarnings && !hasPrerequisites) return null;
171757
+ if (!divergence && !hasWarnings && !hasPrerequisites && !hasUnavailableTracking && !tracksNoTasks) return null;
171515
171758
  const guidanceSummaryParts = [];
171516
171759
  if (hasWarnings) {
171517
171760
  const count = warnings.length;
@@ -171590,6 +171833,55 @@ function ApplyProgressNotice({ applyInstructionProgress, warnings, missingPrereq
171590
171833
  })]
171591
171834
  }) : null]
171592
171835
  }) : null,
171836
+ hasUnavailableTracking ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171837
+ role: "status",
171838
+ "data-apply-notice": "tracking-unavailable",
171839
+ "aria-label": `Apply tracking evidence unavailable from ${APPLY_COMMAND_ATTRIBUTION}`,
171840
+ 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",
171841
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
171842
+ className: "mt-0.5 h-4 w-4 shrink-0",
171843
+ "aria-hidden": "true"
171844
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171845
+ className: "min-w-0 space-y-1",
171846
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171847
+ className: "font-medium",
171848
+ children: ["Tracking evidence unavailable — reported by ", APPLY_COMMAND_ATTRIBUTION]
171849
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
171850
+ className: "space-y-1",
171851
+ children: unavailableTrackingFiles?.map((file) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
171852
+ className: "min-w-0 space-y-0.5",
171853
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171854
+ className: "break-words rounded border border-amber-400/60 bg-amber-100/60 px-1 py-0.5 font-mono [overflow-wrap:anywhere] dark:border-amber-800 dark:bg-amber-900/40",
171855
+ children: file.path
171856
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
171857
+ className: "break-words [overflow-wrap:anywhere]",
171858
+ children: file.reason
171859
+ })]
171860
+ }, file.path))
171861
+ })]
171862
+ })]
171863
+ }) : null,
171864
+ tracksNoTasks ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171865
+ role: "status",
171866
+ "data-apply-notice": "no-tracking",
171867
+ "aria-label": "Apply task tracking not configured",
171868
+ className: "text-muted-foreground flex min-w-0 items-center gap-2 rounded-md border px-3 py-1.5 text-xs",
171869
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Info$1, {
171870
+ className: "h-4 w-4 shrink-0",
171871
+ "aria-hidden": "true"
171872
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
171873
+ className: "min-w-0",
171874
+ children: [
171875
+ "Schema tracks no tasks (no ",
171876
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
171877
+ className: "font-mono",
171878
+ children: "apply.tracks"
171879
+ }),
171880
+ " configured) — an empty task list is not missing evidence — ",
171881
+ APPLY_COMMAND_ATTRIBUTION
171882
+ ]
171883
+ })]
171884
+ }) : null,
171593
171885
  divergence ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
171594
171886
  role: "status",
171595
171887
  "data-apply-notice": "divergence",
@@ -171646,6 +171938,7 @@ function ApplyProgressNotice({ applyInstructionProgress, warnings, missingPrereq
171646
171938
  * Owner correction (2026-08-03): unify Change scan Tooltips in the subtitle and keep failures below the Header.
171647
171939
  * Original request (2026-08-15): Owner walkthrough: merge Apply progress into the subtitle badge row.
171648
171940
  * Original request (2026-08-15): 刷新/解析中的 lifecycle 锁收敛为副标题行内的 shiny 徽章 + Tooltip。
171941
+ * Original request (2026-09-27): Owner walkthrough P3 adjudication — taskTrackingConfigured passthrough to the apply badge.
171649
171942
  */
171650
171943
  function summarizeReferences(references) {
171651
171944
  return references.reduce((counts, reference) => {
@@ -171666,7 +171959,7 @@ function referenceErrorLabels(references) {
171666
171959
  });
171667
171960
  }
171668
171961
  /** Compact source-attributed facts that share the Change Header subtitle. */
171669
- function ChangeContextSummary({ status, referenceEvidence, applyInstructionProgress, statusRefreshing = null, rootChecking = null }) {
171962
+ function ChangeContextSummary({ status, referenceEvidence, applyInstructionProgress, taskTrackingConfigured, statusRefreshing = null, rootChecking = null }) {
171670
171963
  const provenance = status.provenance;
171671
171964
  const references = referenceEvidence.state === "unavailable" ? null : referenceEvidence.references;
171672
171965
  const referenceCounts = references ? summarizeReferences(references) : null;
@@ -171692,7 +171985,10 @@ function ChangeContextSummary({ status, referenceEvidence, applyInstructionProgr
171692
171985
  " artifacts"
171693
171986
  ]
171694
171987
  }),
171695
- applyInstructionProgress ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressBadge, { applyInstructionProgress }) : null,
171988
+ applyInstructionProgress ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressBadge, {
171989
+ applyInstructionProgress,
171990
+ taskTrackingConfigured
171991
+ }) : null,
171696
171992
  provenance.kind === "static" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InformationBadge, {
171697
171993
  ariaLabel: "Static Change context has no live backend provenance",
171698
171994
  tooltip: "CLI Change context is unavailable in this static snapshot.",
@@ -173682,7 +173978,7 @@ function RootActionNotice({ state }) {
173682
173978
  //#endregion
173683
173979
  //#region src/routes/change-view.tsx
173684
173980
  /**
173685
- * Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
173981
+ * Orthogonal intents (updated 2026-09-26 Asia/Shanghai):
173686
173982
  * 1. Render schema-aware change artifacts and source files while retaining terminal status errors.
173687
173983
  * 2. Dispatch change workflows through routed compose/verify surfaces and the shared Operator launcher.
173688
173984
  * 3. Lock every change workflow action behind current Root Context and Status projection authority.
@@ -173690,6 +173986,9 @@ function RootActionNotice({ state }) {
173690
173986
  * 5. Keep compact Change facts in subtitle badges while routing complete CLI evidence through a dedicated tab.
173691
173987
  * 6. Mount the container-responsive list-detail Evidence workspace as the sole Evidence tab surface.
173692
173988
  * 7. Mount OpenSpec 1.13 Apply warnings and the build-order chain on the direct status plane.
173989
+ * 8. Mount OpenSpec 1.13.2 Apply tracking evidence on the same plane: unreadable tracking
173990
+ * files and no-tracking schemas (`taskTrackingConfigured === false`) mount the status
173991
+ * region and reach the notice, while absent members keep the pre-1.13.2 presentation.
173693
173992
  *
173694
173993
  * Original request (2026-07-15): "Root-dependent actions remain locked until root selection succeeds."
173695
173994
  * Review request (2026-07-23): "代码已经提交,开始review。如果有问题,那么可更新change。"
@@ -173707,6 +174006,8 @@ function RootActionNotice({ state }) {
173707
174006
  * headings fall back to the change id) and collapse Apply readiness guidance into one summary row.
173708
174007
  * — the status region gains the OpenSpec 1.13 Apply `warnings` and `missingPrerequisites`
173709
174008
  * direct-plane evidence beside the existing divergence notice.
174009
+ * Original request (2026-09-26): "Openspec 1.13.2 释放了…" — tracking-evidence direct-plane mounting (update-openspec-cli-1132 Slice 2).
174010
+ * Original request (2026-09-27): Owner walkthrough P3 adjudication — badge receives taskTrackingConfigured.
173710
174011
  */
173711
174012
  function ChangeView() {
173712
174013
  const { changeId } = useParams({ from: "/changes/$changeId" });
@@ -173789,7 +174090,7 @@ function ChangeView() {
173789
174090
  })
173790
174091
  }] : [], [referenceEvidence, status]);
173791
174092
  const hasReferenceFailures = referenceEvidence.state !== "unavailable" && referenceEvidence.references.some((reference) => reference.status.some((diagnostic) => diagnostic.severity === "error"));
173792
- const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence) || (applyInstructions?.warnings?.length ?? 0) > 0 || (applyInstructions?.missingPrerequisites?.length ?? 0) > 0;
174093
+ const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence) || (applyInstructions?.warnings?.length ?? 0) > 0 || (applyInstructions?.missingPrerequisites?.length ?? 0) > 0 || (applyInstructions?.unavailableTrackingFiles?.length ?? 0) > 0 || applyInstructions?.taskTrackingConfigured === false;
173793
174094
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OpsxEntityDetailView, {
173794
174095
  entityId: changeId,
173795
174096
  sharedFamily: "changes",
@@ -173801,6 +174102,7 @@ function ChangeView() {
173801
174102
  status,
173802
174103
  referenceEvidence,
173803
174104
  applyInstructionProgress: applyInstructions?.applyInstructionProgress ?? null,
174105
+ taskTrackingConfigured: applyInstructions?.taskTrackingConfigured,
173804
174106
  statusRefreshing: statusCurrent ? null : {
173805
174107
  label: "Status refreshing",
173806
174108
  message: statusAuthorityMessage ?? ""
@@ -173867,7 +174169,9 @@ function ChangeView() {
173867
174169
  applyInstructions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressNotice, {
173868
174170
  applyInstructionProgress: applyInstructions.applyInstructionProgress,
173869
174171
  warnings: applyInstructions.warnings,
173870
- missingPrerequisites: applyInstructions.missingPrerequisites
174172
+ missingPrerequisites: applyInstructions.missingPrerequisites,
174173
+ taskTrackingConfigured: applyInstructions.taskTrackingConfigured,
174174
+ unavailableTrackingFiles: applyInstructions.unavailableTrackingFiles
173871
174175
  }) : null
173872
174176
  ]
173873
174177
  }) : null
@@ -173908,7 +174212,7 @@ var CONFIG_GUIDE_STAGE_META = {
173908
174212
  //#region src/components/config/config-guide.tsx
173909
174213
  var ConfigGuideContext = (0, import_react.createContext)(null);
173910
174214
  (0, import_react.lazy)(async () => {
173911
- return { default: (await import("./config-guide-presentation-B5oRLCcX.js")).ConfigGuidePresentationLayer };
174215
+ return { default: (await import("./config-guide-presentation-Cji5XRfB.js")).ConfigGuidePresentationLayer };
173912
174216
  });
173913
174217
  /** Access the root-owned adaptive Guide runtime. */
173914
174218
  function useConfigGuide() {
@@ -178938,6 +179242,8 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
178938
179242
  *
178939
179243
  * Original request (2026-07-16): "接下来,你来接手后续工作"
178940
179244
  * Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
179245
+ * Original request (2026-09-18): owner walkthrough Case 5 — the compact Kanban cards kept the
179246
+ * generic scaffold heading "Proposal"; normalize active/archive card names once at the route.
178941
179247
  * Derived requirement (2026-07-19): Checkpoint 6.11 preserves Git handoff and action provenance.
178942
179248
  * Original request (2026-07-23): "现在页面数据的加载数据非常慢(比如dashboard页面、changes页面都要等待非常久,页面刷新后,似乎后台没有缓存一样,也要加载很久。"
178943
179249
  * Original request (2026-07-27): "统一修复所有类似的问题(我们也没不多,各个页面都检查一下,特别是app 那边新增的页面)"
@@ -179192,7 +179498,14 @@ function Dashboard() {
179192
179498
  gitAutoRefreshPreset,
179193
179499
  staticMode
179194
179500
  ]);
179195
- const activeChanges = summaryProjection?.activeChanges ?? [];
179501
+ const activeChanges = (0, import_react.useMemo)(() => (summaryProjection?.activeChanges ?? []).map((change) => ({
179502
+ ...change,
179503
+ name: changeDisplayTitle(change.id, change.name)
179504
+ })), [summaryProjection?.activeChanges]);
179505
+ const kanbanArchivedItems = (0, import_react.useMemo)(() => (summaryProjection?.recentArchives ?? []).map((archive) => ({
179506
+ ...archive,
179507
+ name: changeDisplayTitle(archive.id, archive.name)
179508
+ })), [summaryProjection?.recentArchives]);
179196
179509
  const activeChangeIdSet = (0, import_react.useMemo)(() => new Set(activeChanges.map((change) => change.id)), [activeChanges]);
179197
179510
  const activeStatuses = (0, import_react.useMemo)(() => {
179198
179511
  return (statuses ?? []).filter((status) => activeChangeIdSet.has(status.changeName));
@@ -179291,7 +179604,7 @@ function Dashboard() {
179291
179604
  variant: "compact",
179292
179605
  pending: summaryPending,
179293
179606
  activeItems: activeChanges,
179294
- archivedItems: summaryProjection?.recentArchives ?? [],
179607
+ archivedItems: kanbanArchivedItems,
179295
179608
  activeCounts: summaryProjection?.trackedTaskPhaseCounts ?? {
179296
179609
  "no-tasks": 0,
179297
179610
  "in-progress": 0,