@openspecui/web 11.1.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/App-CYwWbLgm.css +1 -0
- package/dist/assets/{App-V1__U9uZ.js → App-Cq2vfNv0.js} +159 -159
- package/dist/assets/{main-CKiFAoXE.js → main-CjHLYXqj.js} +2 -2
- package/dist/assets/{trpc-BLZ0FQJV.js → trpc-BJDrN6rb.js} +1 -1
- package/dist/index.html +1 -1
- package/dist-ssg/client/.vite/ssr-manifest.json +79 -29
- package/dist-ssg/client/assets/CanvasRenderer-BAnUeHzl.js +1 -0
- package/dist-ssg/client/assets/WebGLRenderer-DehTnF66.js +1 -0
- package/dist-ssg/client/assets/WebGPURenderer-BCXAr50t.js +1 -0
- package/dist-ssg/client/assets/browserAll-Brx8TmCT.js +1 -0
- package/dist-ssg/client/assets/{config-guide-presentation-BuoQZFn1.js → config-guide-presentation-BYWAVHG-.js} +1 -1
- package/dist-ssg/client/assets/{dist-csqKQiDd.js → dist-B014oKqB.js} +1 -1
- package/dist-ssg/client/assets/{dist-CH33y9Yu.js → dist-B7XysJsL.js} +1 -1
- package/dist-ssg/client/assets/dist-BKcEPt5U.js +1 -0
- package/dist-ssg/client/assets/dist-BZVFJHY_.js +1 -0
- package/dist-ssg/client/assets/{dist-Dtpb6ue4.js → dist-CT1adEON.js} +1 -1
- package/dist-ssg/client/assets/{dist-2ZcaJZrJ.js → dist-DBbVV3c6.js} +1 -1
- package/dist-ssg/client/assets/{dist-B_-3nALe.js → dist-DFWGpO_L.js} +1 -1
- package/dist-ssg/client/assets/{dist-DHX5Y9iH.js → dist-DUzLJ7IR.js} +1 -1
- package/dist-ssg/client/assets/{dist-LQ5AvrWf.js → dist-DtpQCgKd.js} +1 -1
- package/dist-ssg/client/assets/{dist-Bbf-AGCl.js → dist-DvnWUGiW.js} +1 -1
- package/dist-ssg/client/assets/{dist-BCSOUbi7.js → dist-PNypP3x_.js} +1 -1
- package/dist-ssg/client/assets/dist-qdJFVZmv.js +1 -0
- package/dist-ssg/client/assets/{ghostty-web-CvjC3u3U.js → ghostty-web-DSqlIAa4.js} +1 -1
- package/dist-ssg/client/assets/index-CMfi0IZJ.css +1 -0
- package/dist-ssg/client/assets/index.ssg-CJP1DN4-.js +1650 -0
- package/dist-ssg/client/assets/{init-DkFTD8N9.js → init-ORkrPTI8.js} +1 -1
- package/dist-ssg/client/assets/{trpc-CeLyGxLD.js → trpc-DimmQX0m.js} +1 -1
- package/dist-ssg/client/assets/webworkerAll-DjsDtAjh.js +1 -0
- package/dist-ssg/client/index.ssg.html +2 -2
- package/dist-ssg/server/assets/CanvasRenderer-CvVvHnla.js +3 -0
- package/dist-ssg/server/assets/WebGLRenderer-ZTMKqKjr.js +3 -0
- package/dist-ssg/server/assets/WebGPURenderer-BaTRp8M6.js +3 -0
- package/dist-ssg/server/assets/{browserAll-B9JXZQ_b.js → browserAll-BoaMSEnC.js} +2 -2
- package/dist-ssg/server/assets/{config-guide-presentation-D921NMVc.js → config-guide-presentation-B5oRLCcX.js} +1 -1
- package/dist-ssg/server/assets/{dist-D5RQw1xh.js → dist-BTp4dJw4.js} +1 -1
- package/dist-ssg/server/assets/{dist-BJhwVaSw.js → dist-Bi2hyX2D.js} +1 -1
- package/dist-ssg/server/assets/{dist-D6j5GTM2.js → dist-C4EXY8oH.js} +1 -1
- package/dist-ssg/server/assets/{dist-BjB76DhT.js → dist-CHiBYKhO.js} +1 -1
- package/dist-ssg/server/assets/dist-CIVGOe5c.js +3 -0
- package/dist-ssg/server/assets/{dist-CX9PVvRC.js → dist-CLOFOKCn.js} +1 -1
- package/dist-ssg/server/assets/{dist-CbRRi2nf.js → dist-CUmPwPDw.js} +1 -1
- package/dist-ssg/server/assets/dist-DAIXBI5T.js +3 -0
- package/dist-ssg/server/assets/{dist-BhaY9Mk5.js → dist-DQpyDhfS.js} +1 -1
- package/dist-ssg/server/assets/{dist-D4O-5WhW.js → dist-DVnu9zoA.js} +1 -1
- package/dist-ssg/server/assets/{dist-CXVf0s87.js → dist-D_mnjXV3.js} +1 -1
- package/dist-ssg/server/assets/dist-fy1m8mbf.js +3 -0
- package/dist-ssg/server/assets/{entry-server-QFuPLrwO.js → entry-server-CXwaLjrK.js} +938 -144
- package/dist-ssg/server/assets/{init-B0dChRpm.js → init-B1eN597N.js} +1 -1
- package/dist-ssg/server/assets/trpc-BQ6eyI7t.js +3 -0
- package/dist-ssg/server/assets/webworkerAll-bAKoC1FD.js +4 -0
- package/dist-ssg/server/ssr-entry-manifest.json +24 -24
- package/package.json +3 -3
- package/dist/assets/App-wF-eA1hn.css +0 -1
- package/dist-ssg/client/assets/CanvasRenderer-DcF6YeUw.js +0 -1
- package/dist-ssg/client/assets/WebGLRenderer-CUyEgGvz.js +0 -1
- package/dist-ssg/client/assets/WebGPURenderer-HO--KqMy.js +0 -1
- package/dist-ssg/client/assets/browserAll-CK2e9DJ7.js +0 -1
- package/dist-ssg/client/assets/dist-B8CANbA6.js +0 -1
- package/dist-ssg/client/assets/dist-BM2XFyj7.js +0 -1
- package/dist-ssg/client/assets/dist-CzvTcdIB.js +0 -1
- package/dist-ssg/client/assets/index-CTUS2FEE.css +0 -1
- package/dist-ssg/client/assets/index.ssg-qirBkhbD.js +0 -1650
- package/dist-ssg/client/assets/webworkerAll-D9xesa9H.js +0 -1
- package/dist-ssg/server/assets/CanvasRenderer-Bvd3pXBF.js +0 -3
- package/dist-ssg/server/assets/WebGLRenderer-jIngAd_2.js +0 -3
- package/dist-ssg/server/assets/WebGPURenderer-C6g3K2oe.js +0 -3
- package/dist-ssg/server/assets/dist-1rQWAJV4.js +0 -3
- package/dist-ssg/server/assets/dist-BIgXEKIS.js +0 -3
- package/dist-ssg/server/assets/dist-CzCglUOQ.js +0 -3
- package/dist-ssg/server/assets/trpc-CbiCXi-L.js +0 -3
- package/dist-ssg/server/assets/webworkerAll-DukCMCoQ.js +0 -4
|
@@ -30908,7 +30908,7 @@ var NavController = class {
|
|
|
30908
30908
|
this.storageKey = scopedStorageKey;
|
|
30909
30909
|
this.rebindProjectScopedLayout(scopedStorageKey);
|
|
30910
30910
|
}
|
|
30911
|
-
const { trpcClient } = await import("./trpc-
|
|
30911
|
+
const { trpcClient } = await import("./trpc-BQ6eyI7t.js");
|
|
30912
30912
|
const remote = parsePersistedLayout(await trpcClient.kv.get.query({ key: this.storageKey }));
|
|
30913
30913
|
if (remote) {
|
|
30914
30914
|
if (remote.updatedAt > this.state.updatedAt) this.dispatch({
|
|
@@ -31051,7 +31051,7 @@ var NavController = class {
|
|
|
31051
31051
|
this.cancelPersistTimer();
|
|
31052
31052
|
this.persistTimer = setTimeout(() => {
|
|
31053
31053
|
this.persistTimer = null;
|
|
31054
|
-
import("./trpc-
|
|
31054
|
+
import("./trpc-BQ6eyI7t.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
|
|
31055
31055
|
key: this.storageKey,
|
|
31056
31056
|
value: {
|
|
31057
31057
|
mainTabs: this.state.mainTabs,
|
|
@@ -39116,6 +39116,8 @@ unionType([objectType({
|
|
|
39116
39116
|
"ready"
|
|
39117
39117
|
]),
|
|
39118
39118
|
missingArtifacts: arrayType(stringType()).optional(),
|
|
39119
|
+
missingPrerequisites: arrayType(stringType()).optional(),
|
|
39120
|
+
warnings: arrayType(stringType()).optional(),
|
|
39119
39121
|
instruction: stringType(),
|
|
39120
39122
|
references: arrayType(CliReferenceIndexEntrySchema).optional(),
|
|
39121
39123
|
context: stringType().optional(),
|
|
@@ -39144,23 +39146,109 @@ var CliValidationTotalsSchema = objectType({
|
|
|
39144
39146
|
passed: numberType(),
|
|
39145
39147
|
failed: numberType()
|
|
39146
39148
|
}).passthrough();
|
|
39149
|
+
/** One bulk Validate item: verdict, full issue array, and runtime-dependent duration. */
|
|
39150
|
+
var CliValidateItemSchema = objectType({
|
|
39151
|
+
id: stringType(),
|
|
39152
|
+
type: enumType(["change", "spec"]),
|
|
39153
|
+
valid: booleanType(),
|
|
39154
|
+
issues: arrayType(CliValidationIssueSchema),
|
|
39155
|
+
durationMs: numberType()
|
|
39156
|
+
}).passthrough();
|
|
39157
|
+
/** Shared Validate summary: full-run totals plus per-type totals, never the filtered view. */
|
|
39158
|
+
var CliValidateSummarySchema = objectType({
|
|
39159
|
+
totals: CliValidationTotalsSchema,
|
|
39160
|
+
byType: recordType(CliValidationTotalsSchema)
|
|
39161
|
+
}).passthrough();
|
|
39147
39162
|
/** Typed ordinary Validate report, also used by 1.9 `validate --archived --json`. */
|
|
39148
39163
|
var CliValidateReportSchema = objectType({
|
|
39149
|
-
items: arrayType(
|
|
39150
|
-
|
|
39151
|
-
type: enumType(["change", "spec"]),
|
|
39152
|
-
valid: booleanType(),
|
|
39153
|
-
issues: arrayType(CliValidationIssueSchema),
|
|
39154
|
-
durationMs: numberType()
|
|
39155
|
-
}).passthrough()),
|
|
39156
|
-
summary: objectType({
|
|
39157
|
-
totals: CliValidationTotalsSchema,
|
|
39158
|
-
byType: recordType(CliValidationTotalsSchema)
|
|
39159
|
-
}).passthrough(),
|
|
39164
|
+
items: arrayType(CliValidateItemSchema),
|
|
39165
|
+
summary: CliValidateSummarySchema,
|
|
39160
39166
|
version: stringType(),
|
|
39161
39167
|
root: CliRootSchema
|
|
39162
39168
|
}).passthrough();
|
|
39163
39169
|
unionType([CliValidateReportSchema, CliDiagnosticFailureSchema]);
|
|
39170
|
+
/**
|
|
39171
|
+
* Typed OpenSpec 1.12 `validate --report findings` document.
|
|
39172
|
+
*
|
|
39173
|
+
* The findings report is a filtered evidence transport beside the full report, never the
|
|
39174
|
+
* validation truth: `itemFindings` carries only items with issues, while `summary` and
|
|
39175
|
+
* `root` stay the full-run values the CLI computed over every item in scope.
|
|
39176
|
+
* `report.returnedItems`/`report.totalItems` distinguish the filtered view from the run
|
|
39177
|
+
* size, and the process exit code keeps the full-run rule (`failed > 0 -> 1`), so decoding
|
|
39178
|
+
* never consults it. An empty scope is the success document
|
|
39179
|
+
* `{ returnedItems: 0, totalItems: 0, itemFindings: [] }`, not a failure sum type.
|
|
39180
|
+
*
|
|
39181
|
+
* Two upstream-guaranteed invariants are decode-level facts (pinned v1.12.0
|
|
39182
|
+
* `projectValidationFindings`): every `itemFindings` entry carries at least one issue
|
|
39183
|
+
* (upstream filters `item.issues.length > 0`), and `returnedItems` never exceeds
|
|
39184
|
+
* `totalItems` (the filtered view is a subset of the full run). Upstream also happens to
|
|
39185
|
+
* set `returnedItems === itemFindings.length` today; that equality stays unasserted so a
|
|
39186
|
+
* future patch-level count adjustment inside the admitted range cannot fabricate a
|
|
39187
|
+
* contract error out of otherwise well-formed CLI evidence.
|
|
39188
|
+
*/
|
|
39189
|
+
var CliValidateFindingsSchema = objectType({
|
|
39190
|
+
report: objectType({
|
|
39191
|
+
kind: literalType("validation-findings"),
|
|
39192
|
+
version: stringType(),
|
|
39193
|
+
scope: enumType([
|
|
39194
|
+
"all",
|
|
39195
|
+
"changes",
|
|
39196
|
+
"specs",
|
|
39197
|
+
"archived"
|
|
39198
|
+
]),
|
|
39199
|
+
returnedItems: numberType(),
|
|
39200
|
+
totalItems: numberType()
|
|
39201
|
+
}).passthrough(),
|
|
39202
|
+
itemFindings: arrayType(CliValidateItemSchema),
|
|
39203
|
+
summary: CliValidateSummarySchema,
|
|
39204
|
+
root: CliRootSchema
|
|
39205
|
+
}).passthrough().superRefine((document, ctx) => {
|
|
39206
|
+
if (document.report.returnedItems > document.report.totalItems) ctx.addIssue({
|
|
39207
|
+
code: ZodIssueCode.custom,
|
|
39208
|
+
path: ["report", "returnedItems"],
|
|
39209
|
+
message: `returnedItems (${document.report.returnedItems}) must not exceed totalItems (${document.report.totalItems}).`
|
|
39210
|
+
});
|
|
39211
|
+
document.itemFindings.forEach((finding, index) => {
|
|
39212
|
+
if (finding.issues.length === 0) ctx.addIssue({
|
|
39213
|
+
code: ZodIssueCode.custom,
|
|
39214
|
+
path: [
|
|
39215
|
+
"itemFindings",
|
|
39216
|
+
index,
|
|
39217
|
+
"issues"
|
|
39218
|
+
],
|
|
39219
|
+
message: "Every findings item must carry at least one issue."
|
|
39220
|
+
});
|
|
39221
|
+
});
|
|
39222
|
+
});
|
|
39223
|
+
/**
|
|
39224
|
+
* Typed findings or request-failure result of `validate --report findings --json`.
|
|
39225
|
+
*
|
|
39226
|
+
* Invalid requests (no bulk scope, an item name, archived+active mixing, or an unknown
|
|
39227
|
+
* report value) produce the shared status-array failure envelope with code
|
|
39228
|
+
* `invalid_validation_report_request`, decoded here through the shared diagnostic
|
|
39229
|
+
* failure schema including its optional `fix` string.
|
|
39230
|
+
*/
|
|
39231
|
+
var CliValidateFindingsResultSchema = unionType([CliValidateFindingsSchema, CliDiagnosticFailureSchema]);
|
|
39232
|
+
/**
|
|
39233
|
+
* Whether a findings result is the findings document rather than the request-failure
|
|
39234
|
+
* envelope. Passthrough tolerance means a failure envelope may legally carry unknown
|
|
39235
|
+
* keys, so mere `report`-key presence cannot discriminate the union: the guard validates
|
|
39236
|
+
* the upstream discriminator shape — `report` is an object whose `kind` is the
|
|
39237
|
+
* `validation-findings` literal and whose count fields are numbers.
|
|
39238
|
+
*
|
|
39239
|
+
* The input is deliberately `unknown`: route and evidence consumers receive the union
|
|
39240
|
+
* of every validate transport (`CliValidate | CliValidateFindingsResult | null`), so the
|
|
39241
|
+
* guard must accept the consumed boundary, not only the already-narrowed findings union.
|
|
39242
|
+
* It stays a cheap shape check, never a second decode: schema-level invariants
|
|
39243
|
+
* (issue presence, count bounds) belong to `CliValidateFindingsSchema` alone.
|
|
39244
|
+
*/
|
|
39245
|
+
function isCliValidateFindings(result) {
|
|
39246
|
+
if (typeof result !== "object" || result === null) return false;
|
|
39247
|
+
const report = result.report;
|
|
39248
|
+
if (typeof report !== "object" || report === null) return false;
|
|
39249
|
+
const { kind, returnedItems, totalItems } = report;
|
|
39250
|
+
return kind === "validation-findings" && typeof returnedItems === "number" && typeof totalItems === "number";
|
|
39251
|
+
}
|
|
39164
39252
|
var CliArchiveTotalsSchema = objectType({
|
|
39165
39253
|
added: numberType(),
|
|
39166
39254
|
modified: numberType(),
|
|
@@ -43257,15 +43345,19 @@ function createApplyInstructionProgress(input, trackedTaskProgress) {
|
|
|
43257
43345
|
//#endregion
|
|
43258
43346
|
//#region ../core/src/opsx-types.ts
|
|
43259
43347
|
/**
|
|
43260
|
-
* Orthogonal intents (updated 2026-
|
|
43348
|
+
* Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
|
|
43261
43349
|
* 1. Publish runtime schemas for final Projection Work payloads, including transformed Apply progress.
|
|
43262
43350
|
* 2. Keep isPlanningComplete as the authoritative planning fact over any local tracked alias.
|
|
43263
43351
|
* 3. Carry CLI status evidence, diagnostics, and per-artifact requires as typed facts.
|
|
43264
43352
|
* 4. Preserve root-context and store projections as browser-safe contracts.
|
|
43265
43353
|
* 5. Keep projection notices distinct from payload data so failures never masquerade as results.
|
|
43354
|
+
* 6. Project the OpenSpec 1.13 Apply `warnings` and `missingPrerequisites` fields through the
|
|
43355
|
+
* input and final projection schemas verbatim: optional everywhere, never defaulted to
|
|
43356
|
+
* empty arrays, and never allowed to alter state/progress/tasks semantics.
|
|
43266
43357
|
*
|
|
43267
43358
|
* Original request (2026-07-15): "为内核载荷建立强类型。"
|
|
43268
43359
|
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
43360
|
+
* Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
|
|
43269
43361
|
*/
|
|
43270
43362
|
/** Runtime schema for one JSON value retained from a CLI Status stdout document. */
|
|
43271
43363
|
var OpsxCliJsonValueSchema = lazyType(() => unionType([
|
|
@@ -43359,6 +43451,8 @@ var ApplyInstructionsInputSchema = objectType({
|
|
|
43359
43451
|
"ready"
|
|
43360
43452
|
]),
|
|
43361
43453
|
missingArtifacts: arrayType(stringType()).optional(),
|
|
43454
|
+
missingPrerequisites: arrayType(stringType()).optional(),
|
|
43455
|
+
warnings: arrayType(stringType()).optional(),
|
|
43362
43456
|
instruction: stringType(),
|
|
43363
43457
|
references: arrayType(CliReferenceIndexEntrySchema).optional(),
|
|
43364
43458
|
context: stringType().optional(),
|
|
@@ -43408,6 +43502,8 @@ var ApplyInstructionsProjectionSchema = objectType({
|
|
|
43408
43502
|
"ready"
|
|
43409
43503
|
]),
|
|
43410
43504
|
missingArtifacts: arrayType(stringType()).optional(),
|
|
43505
|
+
missingPrerequisites: arrayType(stringType()).optional(),
|
|
43506
|
+
warnings: arrayType(stringType()).optional(),
|
|
43411
43507
|
instruction: stringType(),
|
|
43412
43508
|
references: arrayType(CliReferenceIndexEntrySchema).optional(),
|
|
43413
43509
|
context: stringType().optional(),
|
|
@@ -46880,6 +46976,32 @@ var ListChecks = createLucideIcon("ListChecks", [
|
|
|
46880
46976
|
key: "oe0vm4"
|
|
46881
46977
|
}]
|
|
46882
46978
|
]);
|
|
46979
|
+
var ListOrdered = createLucideIcon("ListOrdered", [
|
|
46980
|
+
["path", {
|
|
46981
|
+
d: "M10 12h11",
|
|
46982
|
+
key: "6m4ad9"
|
|
46983
|
+
}],
|
|
46984
|
+
["path", {
|
|
46985
|
+
d: "M10 18h11",
|
|
46986
|
+
key: "11hvi2"
|
|
46987
|
+
}],
|
|
46988
|
+
["path", {
|
|
46989
|
+
d: "M10 6h11",
|
|
46990
|
+
key: "c7qv1k"
|
|
46991
|
+
}],
|
|
46992
|
+
["path", {
|
|
46993
|
+
d: "M4 10h2",
|
|
46994
|
+
key: "16xx2s"
|
|
46995
|
+
}],
|
|
46996
|
+
["path", {
|
|
46997
|
+
d: "M4 6h1v4",
|
|
46998
|
+
key: "cnovpq"
|
|
46999
|
+
}],
|
|
47000
|
+
["path", {
|
|
47001
|
+
d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1",
|
|
47002
|
+
key: "m9a95d"
|
|
47003
|
+
}]
|
|
47004
|
+
]);
|
|
46883
47005
|
var ListTodo = createLucideIcon("ListTodo", [
|
|
46884
47006
|
["rect", {
|
|
46885
47007
|
x: "3",
|
|
@@ -47051,6 +47173,20 @@ var Moon = createLucideIcon("Moon", [["path", {
|
|
|
47051
47173
|
d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z",
|
|
47052
47174
|
key: "a7tn18"
|
|
47053
47175
|
}]]);
|
|
47176
|
+
var OctagonAlert = createLucideIcon("OctagonAlert", [
|
|
47177
|
+
["path", {
|
|
47178
|
+
d: "M12 16h.01",
|
|
47179
|
+
key: "1drbdi"
|
|
47180
|
+
}],
|
|
47181
|
+
["path", {
|
|
47182
|
+
d: "M12 8v4",
|
|
47183
|
+
key: "1got3b"
|
|
47184
|
+
}],
|
|
47185
|
+
["path", {
|
|
47186
|
+
d: "M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z",
|
|
47187
|
+
key: "1fd625"
|
|
47188
|
+
}]
|
|
47189
|
+
]);
|
|
47054
47190
|
var PackageOpen = createLucideIcon("PackageOpen", [
|
|
47055
47191
|
["path", {
|
|
47056
47192
|
d: "M12 22v-9",
|
|
@@ -71180,7 +71316,7 @@ var browserExt = {
|
|
|
71180
71316
|
},
|
|
71181
71317
|
test: () => true,
|
|
71182
71318
|
load: async () => {
|
|
71183
|
-
await import("./browserAll-
|
|
71319
|
+
await import("./browserAll-BoaMSEnC.js");
|
|
71184
71320
|
}
|
|
71185
71321
|
};
|
|
71186
71322
|
//#endregion
|
|
@@ -71193,7 +71329,7 @@ var webworkerExt = {
|
|
|
71193
71329
|
},
|
|
71194
71330
|
test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
|
|
71195
71331
|
load: async () => {
|
|
71196
|
-
await import("./webworkerAll-
|
|
71332
|
+
await import("./webworkerAll-bAKoC1FD.js");
|
|
71197
71333
|
}
|
|
71198
71334
|
};
|
|
71199
71335
|
//#endregion
|
|
@@ -73787,7 +73923,7 @@ async function autoDetectRenderer(options) {
|
|
|
73787
73923
|
for (let i = 0; i < preferredOrder.length; i++) {
|
|
73788
73924
|
const rendererType = preferredOrder[i];
|
|
73789
73925
|
if (rendererType === "webgpu" && await isWebGPUSupported()) {
|
|
73790
|
-
const { WebGPURenderer } = await import("./WebGPURenderer-
|
|
73926
|
+
const { WebGPURenderer } = await import("./WebGPURenderer-BaTRp8M6.js");
|
|
73791
73927
|
RendererClass = WebGPURenderer;
|
|
73792
73928
|
finalOptions = {
|
|
73793
73929
|
...options,
|
|
@@ -73795,7 +73931,7 @@ async function autoDetectRenderer(options) {
|
|
|
73795
73931
|
};
|
|
73796
73932
|
break;
|
|
73797
73933
|
} else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
|
|
73798
|
-
const { WebGLRenderer } = await import("./WebGLRenderer-
|
|
73934
|
+
const { WebGLRenderer } = await import("./WebGLRenderer-ZTMKqKjr.js");
|
|
73799
73935
|
RendererClass = WebGLRenderer;
|
|
73800
73936
|
finalOptions = {
|
|
73801
73937
|
...options,
|
|
@@ -73803,7 +73939,7 @@ async function autoDetectRenderer(options) {
|
|
|
73803
73939
|
};
|
|
73804
73940
|
break;
|
|
73805
73941
|
} else if (rendererType === "canvas") {
|
|
73806
|
-
const { CanvasRenderer } = await import("./CanvasRenderer-
|
|
73942
|
+
const { CanvasRenderer } = await import("./CanvasRenderer-CvVvHnla.js");
|
|
73807
73943
|
RendererClass = CanvasRenderer;
|
|
73808
73944
|
finalOptions = {
|
|
73809
73945
|
...options,
|
|
@@ -97552,7 +97688,7 @@ var TerminalController = class {
|
|
|
97552
97688
|
if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
|
|
97553
97689
|
this.configPersistTimer = setTimeout(() => {
|
|
97554
97690
|
this.configPersistTimer = null;
|
|
97555
|
-
import("./trpc-
|
|
97691
|
+
import("./trpc-BQ6eyI7t.js").then(({ trpcClient }) => {
|
|
97556
97692
|
trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
|
|
97557
97693
|
}).catch(() => {});
|
|
97558
97694
|
}, CONFIG_PERSIST_DEBOUNCE);
|
|
@@ -108113,7 +108249,7 @@ var languages = [
|
|
|
108113
108249
|
name: "CSS",
|
|
108114
108250
|
extensions: ["css"],
|
|
108115
108251
|
load() {
|
|
108116
|
-
return import("./dist-
|
|
108252
|
+
return import("./dist-fy1m8mbf.js").then((m) => m.css());
|
|
108117
108253
|
}
|
|
108118
108254
|
}),
|
|
108119
108255
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108133,7 +108269,7 @@ var languages = [
|
|
|
108133
108269
|
"hbs"
|
|
108134
108270
|
],
|
|
108135
108271
|
load() {
|
|
108136
|
-
return import("./dist-
|
|
108272
|
+
return import("./dist-C4EXY8oH.js").then((m) => m.html());
|
|
108137
108273
|
}
|
|
108138
108274
|
}),
|
|
108139
108275
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108167,7 +108303,7 @@ var languages = [
|
|
|
108167
108303
|
"jinja2"
|
|
108168
108304
|
],
|
|
108169
108305
|
load() {
|
|
108170
|
-
return import("./dist-
|
|
108306
|
+
return import("./dist-BTp4dJw4.js").then((m) => m.jinja());
|
|
108171
108307
|
}
|
|
108172
108308
|
}),
|
|
108173
108309
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108175,7 +108311,7 @@ var languages = [
|
|
|
108175
108311
|
alias: ["json5"],
|
|
108176
108312
|
extensions: ["json", "map"],
|
|
108177
108313
|
load() {
|
|
108178
|
-
return import("./dist-
|
|
108314
|
+
return import("./dist-DAIXBI5T.js").then((m) => m.json());
|
|
108179
108315
|
}
|
|
108180
108316
|
}),
|
|
108181
108317
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108189,14 +108325,14 @@ var languages = [
|
|
|
108189
108325
|
name: "LESS",
|
|
108190
108326
|
extensions: ["less"],
|
|
108191
108327
|
load() {
|
|
108192
|
-
return import("./dist-
|
|
108328
|
+
return import("./dist-DQpyDhfS.js").then((m) => m.less());
|
|
108193
108329
|
}
|
|
108194
108330
|
}),
|
|
108195
108331
|
/* @__PURE__ */ LanguageDescription.of({
|
|
108196
108332
|
name: "Liquid",
|
|
108197
108333
|
extensions: ["liquid"],
|
|
108198
108334
|
load() {
|
|
108199
|
-
return import("./dist-
|
|
108335
|
+
return import("./dist-CHiBYKhO.js").then((m) => m.liquid());
|
|
108200
108336
|
}
|
|
108201
108337
|
}),
|
|
108202
108338
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108213,7 +108349,7 @@ var languages = [
|
|
|
108213
108349
|
"mkd"
|
|
108214
108350
|
],
|
|
108215
108351
|
load() {
|
|
108216
|
-
return import("./dist-
|
|
108352
|
+
return import("./dist-DVnu9zoA.js").then((m) => m.markdown());
|
|
108217
108353
|
}
|
|
108218
108354
|
}),
|
|
108219
108355
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108239,7 +108375,7 @@ var languages = [
|
|
|
108239
108375
|
"phtml"
|
|
108240
108376
|
],
|
|
108241
108377
|
load() {
|
|
108242
|
-
return import("./dist-
|
|
108378
|
+
return import("./dist-CUmPwPDw.js").then((m) => m.php());
|
|
108243
108379
|
}
|
|
108244
108380
|
}),
|
|
108245
108381
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108279,14 +108415,14 @@ var languages = [
|
|
|
108279
108415
|
name: "Sass",
|
|
108280
108416
|
extensions: ["sass"],
|
|
108281
108417
|
load() {
|
|
108282
|
-
return import("./dist-
|
|
108418
|
+
return import("./dist-Bi2hyX2D.js").then((m) => m.sass({ indented: true }));
|
|
108283
108419
|
}
|
|
108284
108420
|
}),
|
|
108285
108421
|
/* @__PURE__ */ LanguageDescription.of({
|
|
108286
108422
|
name: "SCSS",
|
|
108287
108423
|
extensions: ["scss"],
|
|
108288
108424
|
load() {
|
|
108289
|
-
return import("./dist-
|
|
108425
|
+
return import("./dist-Bi2hyX2D.js").then((m) => m.sass());
|
|
108290
108426
|
}
|
|
108291
108427
|
}),
|
|
108292
108428
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108353,7 +108489,7 @@ var languages = [
|
|
|
108353
108489
|
alias: ["yml"],
|
|
108354
108490
|
extensions: ["yaml", "yml"],
|
|
108355
108491
|
load() {
|
|
108356
|
-
return import("./dist-
|
|
108492
|
+
return import("./dist-CIVGOe5c.js").then((m) => m.yaml());
|
|
108357
108493
|
}
|
|
108358
108494
|
}),
|
|
108359
108495
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -109240,13 +109376,13 @@ var languages = [
|
|
|
109240
109376
|
name: "Vue",
|
|
109241
109377
|
extensions: ["vue"],
|
|
109242
109378
|
load() {
|
|
109243
|
-
return import("./dist-
|
|
109379
|
+
return import("./dist-D_mnjXV3.js").then((m) => m.vue());
|
|
109244
109380
|
}
|
|
109245
109381
|
}),
|
|
109246
109382
|
/* @__PURE__ */ LanguageDescription.of({
|
|
109247
109383
|
name: "Angular Template",
|
|
109248
109384
|
load() {
|
|
109249
|
-
return import("./dist-
|
|
109385
|
+
return import("./dist-CLOFOKCn.js").then((m) => m.angular());
|
|
109250
109386
|
}
|
|
109251
109387
|
})
|
|
109252
109388
|
];
|
|
@@ -169958,6 +170094,36 @@ function ChangeRowChevron() {
|
|
|
169958
170094
|
});
|
|
169959
170095
|
}
|
|
169960
170096
|
//#endregion
|
|
170097
|
+
//#region src/lib/change-display-title.ts
|
|
170098
|
+
/**
|
|
170099
|
+
* Orthogonal intents (created 2026-09-12 Asia/Shanghai):
|
|
170100
|
+
* 1. Derive one shared display title for a Change across list, dashboard, and detail surfaces.
|
|
170101
|
+
* 2. Treat the proposal H1 as a human-readable title only when it is informative.
|
|
170102
|
+
* 3. Fall back to the change id (the CLI's own canonical name) otherwise.
|
|
170103
|
+
*
|
|
170104
|
+
* Original request (2026-09-12): Owner walkthrough: the Changes list showed the generic proposal
|
|
170105
|
+
* heading "Proposal" as the row title while Change Detail showed the change id — unify the scheme.
|
|
170106
|
+
*/
|
|
170107
|
+
/**
|
|
170108
|
+
* Heading texts that carry no identity information. `openspec new change` scaffolds proposals with
|
|
170109
|
+
* the bare heading "# Proposal"; showing it as a row title reads as a parsing bug rather than a name.
|
|
170110
|
+
*/
|
|
170111
|
+
var GENERIC_PROPOSAL_HEADINGS = new Set(["proposal"]);
|
|
170112
|
+
/**
|
|
170113
|
+
* One display title for a Change, identical on every surface.
|
|
170114
|
+
*
|
|
170115
|
+
* `name` is the legacy parser's proposal H1 (absent for parser-less custom schemas); the change id
|
|
170116
|
+
* is the CLI-owned canonical identity (`openspec list --json` names changes by directory). The H1
|
|
170117
|
+
* wins only when it is a real, differentiated title; generic headings and the id itself fall back
|
|
170118
|
+
* to the id, so no surface ever shows two different titles for the same Change.
|
|
170119
|
+
*/
|
|
170120
|
+
function changeDisplayTitle(changeId, name) {
|
|
170121
|
+
const trimmed = name?.trim();
|
|
170122
|
+
if (!trimmed || trimmed === changeId) return changeId;
|
|
170123
|
+
if (GENERIC_PROPOSAL_HEADINGS.has(trimmed.toLowerCase())) return changeId;
|
|
170124
|
+
return trimmed;
|
|
170125
|
+
}
|
|
170126
|
+
//#endregion
|
|
169961
170127
|
//#region src/lib/change-workflow-phase.ts
|
|
169962
170128
|
function classifyChangeWorkflowPhase(params) {
|
|
169963
170129
|
if (params.hasStatus && params.trackedArtifactStatus === "blocked") return {
|
|
@@ -170080,6 +170246,8 @@ function useChangeListContinuity(incomingChanges, containerRef) {
|
|
|
170080
170246
|
* Original request (2026-07-21): "Changes页面的右上角没有 New,你要不要快速补一个"
|
|
170081
170247
|
|
|
170082
170248
|
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
170249
|
+
* Original request (2026-09-12): Owner walkthrough: unify the Change display title — generic
|
|
170250
|
+
* "# Proposal" headings fall back to the change id on every surface.
|
|
170083
170251
|
*/
|
|
170084
170252
|
function buildStatusMap(statuses) {
|
|
170085
170253
|
return new Map((statuses ?? []).map((status) => [status.changeName, status]));
|
|
@@ -170229,7 +170397,7 @@ function ChangeList() {
|
|
|
170229
170397
|
__vtHandoff: {
|
|
170230
170398
|
family: "changes",
|
|
170231
170399
|
entityId: change.id,
|
|
170232
|
-
title: change.name,
|
|
170400
|
+
title: changeDisplayTitle(change.id, change.name),
|
|
170233
170401
|
subtitle: change.id
|
|
170234
170402
|
}
|
|
170235
170403
|
}),
|
|
@@ -170240,7 +170408,7 @@ function ChangeList() {
|
|
|
170240
170408
|
className: "flex items-center gap-3",
|
|
170241
170409
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
|
|
170242
170410
|
changeId: change.id,
|
|
170243
|
-
name: change.name,
|
|
170411
|
+
name: changeDisplayTitle(change.id, change.name),
|
|
170244
170412
|
phase,
|
|
170245
170413
|
updatedAt: change.updatedAt,
|
|
170246
170414
|
formatTime: formatRelativeTime,
|
|
@@ -171286,16 +171454,27 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
|
|
|
171286
171454
|
//#endregion
|
|
171287
171455
|
//#region src/components/apply-progress-notice.tsx
|
|
171288
171456
|
/**
|
|
171289
|
-
* Orthogonal intents (updated 2026-
|
|
171457
|
+
* Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
|
|
171290
171458
|
* 1. Attribute Apply instruction counts to the upstream Apply command.
|
|
171291
171459
|
* 2. Compress agreement to one subtitle badge; keep divergence a direct blocker.
|
|
171292
171460
|
* 3. Keep divergence's two objective source counts side by side with their causes.
|
|
171293
171461
|
* 4. Keep tooltips as the keyboard-reachable explanation for every compact count.
|
|
171462
|
+
* 5. Render OpenSpec 1.13 Apply `warnings`/`missingPrerequisites` as ONE always-visible summary
|
|
171463
|
+
* row (count + build-order chain, CLI attribution) whose verbatim evidence is one explicit
|
|
171464
|
+
* expansion away on the same direct plane — advisory guidance must stay discoverable without
|
|
171465
|
+
* consuming the page; a Tooltip-only surface remains forbidden.
|
|
171466
|
+
* 6. Keep `missingPrerequisites` visually and semantically distinct from blockers (status
|
|
171467
|
+
* semantics), including when the Apply state is already `ready`.
|
|
171468
|
+
* 7. Degrade to the previous presentation when either 1.13 field is absent — absent keys
|
|
171469
|
+
* are the upstream encoding for "none", so no empty state is ever synthesized.
|
|
171294
171470
|
*
|
|
171295
171471
|
* Original request (2026-07-15): "与 tracked glob 进度分歧时各自归因展示。"
|
|
171296
171472
|
* Original request (2026-07-28): supporting 6.x evidence should use Badge + Tooltip or Accordion.
|
|
171297
171473
|
* Original request (2026-08-15): Owner walkthrough: agreement is one badge in the subtitle row,
|
|
171298
171474
|
* not a two-line block; only divergence owns a notice.
|
|
171475
|
+
* Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
|
|
171476
|
+
* Original request (2026-09-12): Owner walkthrough: the always-expanded warning/build-order blocks
|
|
171477
|
+
* consumed the page; collapse them behind one summary row while keeping direct-plane discovery.
|
|
171299
171478
|
*/
|
|
171300
171479
|
/**
|
|
171301
171480
|
* One compact, source-attributed Apply progress badge for the Change subtitle row.
|
|
@@ -171316,54 +171495,143 @@ function ApplyProgressBadge({ applyInstructionProgress }) {
|
|
|
171316
171495
|
]
|
|
171317
171496
|
});
|
|
171318
171497
|
}
|
|
171498
|
+
/** Upstream command that owns every fact rendered by these notices. */
|
|
171499
|
+
var APPLY_COMMAND_ATTRIBUTION = "openspec instructions apply";
|
|
171500
|
+
var GUIDANCE_DETAIL_ID = "apply-readiness-guidance-detail";
|
|
171319
171501
|
/**
|
|
171320
|
-
* Render the Apply/tracked divergence as one direct, source-attributed blocker
|
|
171321
|
-
*
|
|
171322
|
-
*
|
|
171502
|
+
* Render the Apply/tracked divergence as one direct, source-attributed blocker, plus the
|
|
171503
|
+
* OpenSpec 1.13 `warnings` and `missingPrerequisites` evidence as one collapsible summary row:
|
|
171504
|
+
* the row itself names the warning count and the build-order chain (discovery needs no hover),
|
|
171505
|
+
* and expanding reveals the verbatim upstream evidence on the same direct plane.
|
|
171506
|
+
* Returns null when none apply — the agreement case lives in the subtitle badge row via
|
|
171507
|
+
* {@link ApplyProgressBadge}, and absent 1.13 keys render nothing.
|
|
171323
171508
|
*/
|
|
171324
|
-
function ApplyProgressNotice({ applyInstructionProgress }) {
|
|
171509
|
+
function ApplyProgressNotice({ applyInstructionProgress, warnings, missingPrerequisites }) {
|
|
171325
171510
|
const divergence = applyInstructionProgress.divergence;
|
|
171326
|
-
|
|
171327
|
-
|
|
171328
|
-
|
|
171329
|
-
|
|
171330
|
-
|
|
171331
|
-
|
|
171332
|
-
|
|
171333
|
-
|
|
171334
|
-
|
|
171335
|
-
|
|
171511
|
+
const hasWarnings = (warnings?.length ?? 0) > 0;
|
|
171512
|
+
const hasPrerequisites = (missingPrerequisites?.length ?? 0) > 0;
|
|
171513
|
+
const [expanded, setExpanded] = (0, import_react.useState)(false);
|
|
171514
|
+
if (!divergence && !hasWarnings && !hasPrerequisites) return null;
|
|
171515
|
+
const guidanceSummaryParts = [];
|
|
171516
|
+
if (hasWarnings) {
|
|
171517
|
+
const count = warnings.length;
|
|
171518
|
+
guidanceSummaryParts.push(`${count} apply warning${count > 1 ? "s" : ""}`);
|
|
171519
|
+
}
|
|
171520
|
+
if (hasPrerequisites) guidanceSummaryParts.push(`next in build order: ${missingPrerequisites.join(" → ")}`);
|
|
171521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
171522
|
+
hasWarnings || hasPrerequisites ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171523
|
+
role: "status",
|
|
171524
|
+
"data-apply-notice": "summary",
|
|
171525
|
+
"aria-label": `Apply readiness guidance from ${APPLY_COMMAND_ATTRIBUTION}`,
|
|
171526
|
+
className: hasWarnings ? "flex min-w-0 items-center gap-2 border border-amber-300 bg-amber-50 px-3 py-1.5 text-xs text-amber-950 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100" : "text-muted-foreground flex min-w-0 items-center gap-2 rounded-md border px-3 py-1.5 text-xs",
|
|
171336
171527
|
children: [
|
|
171337
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
171338
|
-
className: "
|
|
171339
|
-
|
|
171528
|
+
hasWarnings ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
171529
|
+
className: "h-4 w-4 shrink-0",
|
|
171530
|
+
"aria-hidden": "true"
|
|
171531
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListOrdered, {
|
|
171532
|
+
className: "h-4 w-4 shrink-0",
|
|
171533
|
+
"aria-hidden": "true"
|
|
171340
171534
|
}),
|
|
171341
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
171342
|
-
|
|
171343
|
-
|
|
171344
|
-
|
|
171345
|
-
|
|
171346
|
-
|
|
171347
|
-
|
|
171348
|
-
|
|
171349
|
-
|
|
171350
|
-
|
|
171351
|
-
|
|
171352
|
-
]
|
|
171353
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171354
|
-
ariaLabel: `Tracked artifact glob progress ${divergence.tracked.completed} of ${divergence.tracked.total}`,
|
|
171355
|
-
tooltip: "Progress computed from the workflow's tracked task artifact glob.",
|
|
171356
|
-
children: [
|
|
171357
|
-
"Tracked ",
|
|
171358
|
-
divergence.tracked.completed,
|
|
171359
|
-
"/",
|
|
171360
|
-
divergence.tracked.total
|
|
171361
|
-
]
|
|
171535
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
171536
|
+
type: "button",
|
|
171537
|
+
onClick: () => setExpanded((value) => !value),
|
|
171538
|
+
"aria-expanded": expanded,
|
|
171539
|
+
"aria-controls": GUIDANCE_DETAIL_ID,
|
|
171540
|
+
className: "flex min-w-0 flex-1 cursor-pointer items-center gap-2 text-left",
|
|
171541
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171542
|
+
className: "truncate font-medium",
|
|
171543
|
+
children: guidanceSummaryParts.join(" · ")
|
|
171544
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
171545
|
+
className: "text-muted-foreground shrink-0 font-normal",
|
|
171546
|
+
children: ["— ", APPLY_COMMAND_ATTRIBUTION]
|
|
171362
171547
|
})]
|
|
171548
|
+
}),
|
|
171549
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {
|
|
171550
|
+
className: "h-4 w-4 shrink-0",
|
|
171551
|
+
"aria-hidden": "true"
|
|
171552
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, {
|
|
171553
|
+
className: "h-4 w-4 shrink-0",
|
|
171554
|
+
"aria-hidden": "true"
|
|
171363
171555
|
})
|
|
171364
171556
|
]
|
|
171365
|
-
})
|
|
171366
|
-
|
|
171557
|
+
}) : null,
|
|
171558
|
+
expanded && (hasWarnings || hasPrerequisites) ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171559
|
+
id: GUIDANCE_DETAIL_ID,
|
|
171560
|
+
className: "text-muted-foreground space-y-2 rounded-md border px-3 py-2 text-xs",
|
|
171561
|
+
children: [hasWarnings ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171562
|
+
"data-apply-notice": "warnings",
|
|
171563
|
+
className: "min-w-0 space-y-1",
|
|
171564
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171565
|
+
className: "text-foreground font-medium",
|
|
171566
|
+
children: ["Apply warnings — reported by ", APPLY_COMMAND_ATTRIBUTION]
|
|
171567
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
171568
|
+
className: "space-y-1",
|
|
171569
|
+
children: warnings?.map((warning) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
|
|
171570
|
+
className: "break-words",
|
|
171571
|
+
children: warning
|
|
171572
|
+
}, warning))
|
|
171573
|
+
})]
|
|
171574
|
+
}) : null, hasPrerequisites ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171575
|
+
"data-apply-notice": "build-order",
|
|
171576
|
+
className: "min-w-0 space-y-1",
|
|
171577
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171578
|
+
className: "text-foreground font-medium",
|
|
171579
|
+
children: ["Next in build order — reported by ", APPLY_COMMAND_ATTRIBUTION]
|
|
171580
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171581
|
+
className: "flex flex-wrap items-center gap-1",
|
|
171582
|
+
children: missingPrerequisites?.map((artifactId, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171583
|
+
className: "text-muted-foreground/70",
|
|
171584
|
+
"aria-hidden": "true",
|
|
171585
|
+
children: "→"
|
|
171586
|
+
}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171587
|
+
className: "bg-muted break-words rounded border px-1 py-0.5 font-mono [overflow-wrap:anywhere]",
|
|
171588
|
+
children: artifactId
|
|
171589
|
+
})] }, artifactId))
|
|
171590
|
+
})]
|
|
171591
|
+
}) : null]
|
|
171592
|
+
}) : null,
|
|
171593
|
+
divergence ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171594
|
+
role: "status",
|
|
171595
|
+
"data-apply-notice": "divergence",
|
|
171596
|
+
"aria-label": "Task progress source divergence",
|
|
171597
|
+
className: "flex min-w-0 items-start gap-2 border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",
|
|
171598
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
171599
|
+
className: "mt-0.5 h-4 w-4 shrink-0",
|
|
171600
|
+
"aria-hidden": "true"
|
|
171601
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171602
|
+
className: "min-w-0 space-y-2",
|
|
171603
|
+
children: [
|
|
171604
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171605
|
+
className: "font-medium",
|
|
171606
|
+
children: "Upstream task progress divergence"
|
|
171607
|
+
}),
|
|
171608
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: divergence.message }),
|
|
171609
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171610
|
+
className: "flex flex-wrap gap-1.5",
|
|
171611
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171612
|
+
ariaLabel: `Apply instructions progress ${applyInstructionProgress.complete} of ${applyInstructionProgress.total}`,
|
|
171613
|
+
tooltip: "Progress reported by openspec instructions apply.",
|
|
171614
|
+
children: [
|
|
171615
|
+
"Apply ",
|
|
171616
|
+
applyInstructionProgress.complete,
|
|
171617
|
+
"/",
|
|
171618
|
+
applyInstructionProgress.total
|
|
171619
|
+
]
|
|
171620
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171621
|
+
ariaLabel: `Tracked artifact glob progress ${divergence.tracked.completed} of ${divergence.tracked.total}`,
|
|
171622
|
+
tooltip: "Progress computed from the workflow's tracked task artifact glob.",
|
|
171623
|
+
children: [
|
|
171624
|
+
"Tracked ",
|
|
171625
|
+
divergence.tracked.completed,
|
|
171626
|
+
"/",
|
|
171627
|
+
divergence.tracked.total
|
|
171628
|
+
]
|
|
171629
|
+
})]
|
|
171630
|
+
})
|
|
171631
|
+
]
|
|
171632
|
+
})]
|
|
171633
|
+
}) : null
|
|
171634
|
+
] });
|
|
171367
171635
|
}
|
|
171368
171636
|
//#endregion
|
|
171369
171637
|
//#region src/components/change-context-summary.tsx
|
|
@@ -171483,17 +171751,31 @@ function ChangeReferenceFailureNotice({ referenceEvidence }) {
|
|
|
171483
171751
|
});
|
|
171484
171752
|
}
|
|
171485
171753
|
//#endregion
|
|
171754
|
+
//#region src/components/evidence-layer-header.tsx
|
|
171755
|
+
function EvidenceLayerHeader({ title, summary }) {
|
|
171756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
|
|
171757
|
+
className: "border-border mb-4 flex min-w-0 flex-wrap items-baseline justify-between gap-x-3 gap-y-1 border-b py-2.5",
|
|
171758
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
|
|
171759
|
+
className: "min-w-0 text-sm font-semibold tracking-tight",
|
|
171760
|
+
children: title
|
|
171761
|
+
}), summary ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171762
|
+
className: "text-muted-foreground min-w-0 text-[11px]",
|
|
171763
|
+
children: summary
|
|
171764
|
+
}) : null]
|
|
171765
|
+
});
|
|
171766
|
+
}
|
|
171767
|
+
//#endregion
|
|
171486
171768
|
//#region ../core/src/openspec-compat.ts
|
|
171487
|
-
var OPENSPEC_CLI_TARGET_SERIES = "1.
|
|
171488
|
-
var OPENSPEC_CLI_SUPPORTED_SERIES = ["1.
|
|
171489
|
-
var OPENSPEC_CLI_ACCEPTED_RANGE = ">=1.
|
|
171769
|
+
var OPENSPEC_CLI_TARGET_SERIES = "1.13";
|
|
171770
|
+
var OPENSPEC_CLI_SUPPORTED_SERIES = ["1.13"];
|
|
171771
|
+
var OPENSPEC_CLI_ACCEPTED_RANGE = ">=1.13.0 <1.14.0";
|
|
171490
171772
|
/**
|
|
171491
171773
|
* Derive command capabilities from one parsed CLI version.
|
|
171492
171774
|
*
|
|
171493
171775
|
* Only an admitted version — stable inside the accepted range — can select version-specific
|
|
171494
|
-
* capabilities. Unsupported forms (prereleases, >=1.
|
|
171776
|
+
* capabilities. Unsupported forms (prereleases, >=1.14, below-range) and unparseable output
|
|
171495
171777
|
* keep their mismatch evidence and expose no capability, so a page-level version bypass can
|
|
171496
|
-
* never manufacture a 1.
|
|
171778
|
+
* never manufacture a 1.13 command surface for a CLI the release line does not admit.
|
|
171497
171779
|
*/
|
|
171498
171780
|
function deriveOpenSpecCliCapabilities(version) {
|
|
171499
171781
|
if (!isAdmittedVersion(version)) return {
|
|
@@ -171501,7 +171783,8 @@ function deriveOpenSpecCliCapabilities(version) {
|
|
|
171501
171783
|
archivedValidation: false,
|
|
171502
171784
|
initLanguage: false,
|
|
171503
171785
|
batchStatus: false,
|
|
171504
|
-
requirementDiff: false
|
|
171786
|
+
requirementDiff: false,
|
|
171787
|
+
findingsReport: false
|
|
171505
171788
|
};
|
|
171506
171789
|
const onTargetSeries = isSeries(version, OPENSPEC_CLI_TARGET_SERIES);
|
|
171507
171790
|
return {
|
|
@@ -171509,7 +171792,8 @@ function deriveOpenSpecCliCapabilities(version) {
|
|
|
171509
171792
|
archivedValidation: true,
|
|
171510
171793
|
initLanguage: true,
|
|
171511
171794
|
batchStatus: onTargetSeries,
|
|
171512
|
-
requirementDiff: onTargetSeries
|
|
171795
|
+
requirementDiff: onTargetSeries,
|
|
171796
|
+
findingsReport: onTargetSeries
|
|
171513
171797
|
};
|
|
171514
171798
|
}
|
|
171515
171799
|
function parseOpenSpecCliVersion(raw) {
|
|
@@ -171533,7 +171817,7 @@ function isStable(version) {
|
|
|
171533
171817
|
/** True only for stable versions inside the accepted range (current or supported non-current). */
|
|
171534
171818
|
function isAdmittedVersion(version) {
|
|
171535
171819
|
if (!version || !isStable(version)) return false;
|
|
171536
|
-
return isSeries(version, "1.
|
|
171820
|
+
return isSeries(version, "1.13") || isSupportedNonCurrentSeries(version);
|
|
171537
171821
|
}
|
|
171538
171822
|
function isSupportedNonCurrentSeries(version) {
|
|
171539
171823
|
return OPENSPEC_CLI_SUPPORTED_SERIES.filter((series) => series !== OPENSPEC_CLI_TARGET_SERIES).some((series) => isSeries(version, series));
|
|
@@ -171541,12 +171825,12 @@ function isSupportedNonCurrentSeries(version) {
|
|
|
171541
171825
|
//#endregion
|
|
171542
171826
|
//#region src/components/archived-validation-evidence.tsx
|
|
171543
171827
|
/**
|
|
171544
|
-
* Orthogonal intents (updated 2026-
|
|
171828
|
+
* Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
|
|
171545
171829
|
* 1. Present OpenSpec `validate --archived --json` as typed CLI evidence.
|
|
171546
171830
|
* 2. Preserve item issues, totals, root, and exit/failure evidence without repair actions.
|
|
171547
171831
|
* 3. Identify the evidence as unavailable in static snapshots instead of fabricating it.
|
|
171548
|
-
* 4. Derive the capability from the detected admitted CLI;
|
|
171549
|
-
*
|
|
171832
|
+
* 4. Derive the capability from the detected admitted CLI; the admitted 1.13 line declares
|
|
171833
|
+
* it, so the unavailable branch names the accepted range, not one series.
|
|
171550
171834
|
* 5. Validate report payloads with the Core contract schema, never shallow shape guards.
|
|
171551
171835
|
* 6. Mount directly inside the Evidence workspace detail pane: the Accordion shell is gone, the
|
|
171552
171836
|
* section header keeps the title and summary facts, and `onChip` reports only derived facts
|
|
@@ -171555,6 +171839,9 @@ function isSupportedNonCurrentSeries(version) {
|
|
|
171555
171839
|
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
171556
171840
|
* Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。"
|
|
171557
171841
|
* Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
|
|
171842
|
+
* Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
|
|
171843
|
+
* Owner walkthrough correction (2026-09-04): every Evidence detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding); this replaces each layer's local weak header.
|
|
171844
|
+
* Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
|
|
171558
171845
|
*/
|
|
171559
171846
|
function parseValidationReport$1(value) {
|
|
171560
171847
|
const parsed = CliValidateReportSchema.safeParse(value);
|
|
@@ -171586,7 +171873,7 @@ function IssueList$1({ issues }) {
|
|
|
171586
171873
|
}, index))
|
|
171587
171874
|
});
|
|
171588
171875
|
}
|
|
171589
|
-
function RunButton$
|
|
171876
|
+
function RunButton$2({ pending, label, onRun }) {
|
|
171590
171877
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
171591
171878
|
type: "button",
|
|
171592
171879
|
onClick: onRun,
|
|
@@ -171612,17 +171899,11 @@ function ArchivedValidationSection({ summary, children }) {
|
|
|
171612
171899
|
"data-evidence-section": "archived-validation",
|
|
171613
171900
|
"aria-label": "Archived validation",
|
|
171614
171901
|
className: "min-w-0",
|
|
171615
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.
|
|
171616
|
-
|
|
171617
|
-
|
|
171618
|
-
className: "min-w-0 text-xs font-semibold",
|
|
171619
|
-
children: "Archived validation"
|
|
171620
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171621
|
-
className: "text-muted-foreground min-w-0 text-[11px]",
|
|
171622
|
-
children: summary
|
|
171623
|
-
})]
|
|
171902
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
|
|
171903
|
+
title: "Archived validation",
|
|
171904
|
+
summary
|
|
171624
171905
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171625
|
-
className: "min-w-0
|
|
171906
|
+
className: "min-w-0 text-xs",
|
|
171626
171907
|
children
|
|
171627
171908
|
})]
|
|
171628
171909
|
});
|
|
@@ -171716,7 +171997,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
|
|
|
171716
171997
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
171717
171998
|
className: "text-muted-foreground",
|
|
171718
171999
|
children: "Run the official CLI's archived-task validation and keep its typed report as evidence. OpenSpecUI never repairs or archives from here."
|
|
171719
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$
|
|
172000
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$2, {
|
|
171720
172001
|
pending,
|
|
171721
172002
|
label: "Validate archived tasks",
|
|
171722
172003
|
onRun: () => void run()
|
|
@@ -171744,7 +172025,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
|
|
|
171744
172025
|
className: "min-w-0 break-all",
|
|
171745
172026
|
children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The archived validation command failed."
|
|
171746
172027
|
})]
|
|
171747
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$
|
|
172028
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$2, {
|
|
171748
172029
|
pending,
|
|
171749
172030
|
label: "Rerun",
|
|
171750
172031
|
onRun: () => void run()
|
|
@@ -171812,7 +172093,7 @@ function ArchivedValidationEvidence({ onChip } = {}) {
|
|
|
171812
172093
|
})]
|
|
171813
172094
|
}, item.id))
|
|
171814
172095
|
}),
|
|
171815
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$
|
|
172096
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$2, {
|
|
171816
172097
|
pending,
|
|
171817
172098
|
label: "Rerun",
|
|
171818
172099
|
onRun: () => void run()
|
|
@@ -171824,12 +172105,13 @@ function ArchivedValidationEvidence({ onChip } = {}) {
|
|
|
171824
172105
|
//#endregion
|
|
171825
172106
|
//#region src/components/change-diff-evidence.tsx
|
|
171826
172107
|
/**
|
|
171827
|
-
* Orthogonal intents (updated 2026-
|
|
172108
|
+
* Orthogonal intents (updated 2026-09-03 Asia/Shanghai):
|
|
171828
172109
|
* 1. Present the CLI-provided MODIFIED-delta `diff`/`warning` fields as Change Detail evidence.
|
|
171829
172110
|
* 2. Color the unified diff body by line role (+/-/@@) without recomputing anything locally.
|
|
171830
172111
|
* 3. Render the exact upstream warning text beside its diff so a near-miss never swallows evidence.
|
|
171831
|
-
* 4. Gate the fetch on the detected admitted CLI's `requirementDiff` capability (
|
|
171832
|
-
* live mode: static snapshots and
|
|
172112
|
+
* 4. Gate the fetch on the detected admitted CLI's `requirementDiff` capability (the admitted
|
|
172113
|
+
* 1.12 line) and on live mode: static snapshots and retired sessions never issue the
|
|
172114
|
+
* transport call.
|
|
171833
172115
|
* 5. Degrade to the existing delta presentation when the fields are absent — no fabricated diff
|
|
171834
172116
|
* or warning may appear.
|
|
171835
172117
|
* 6. Mount directly inside the Evidence workspace detail pane: the Accordion shell is gone, the
|
|
@@ -171838,6 +172120,8 @@ function ArchivedValidationEvidence({ onChip } = {}) {
|
|
|
171838
172120
|
*
|
|
171839
172121
|
* Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。"
|
|
171840
172122
|
* Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
|
|
172123
|
+
* Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
|
|
172124
|
+
* Owner walkthrough correction (2026-09-04): every Evidence detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding); this replaces each layer's local weak header.
|
|
171841
172125
|
*/
|
|
171842
172126
|
function diffLineRole(line) {
|
|
171843
172127
|
if (line.startsWith("@@")) return "hunk";
|
|
@@ -171928,22 +172212,16 @@ function RequirementDiffsSection({ summary, children }) {
|
|
|
171928
172212
|
"data-evidence-section": "requirement-diffs",
|
|
171929
172213
|
"aria-label": "Requirement diffs",
|
|
171930
172214
|
className: "min-w-0",
|
|
171931
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.
|
|
171932
|
-
|
|
171933
|
-
|
|
171934
|
-
className: "min-w-0 text-xs font-semibold",
|
|
171935
|
-
children: "Requirement diffs"
|
|
171936
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171937
|
-
className: "text-muted-foreground min-w-0 text-[11px]",
|
|
171938
|
-
children: summary
|
|
171939
|
-
})]
|
|
172215
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
|
|
172216
|
+
title: "Requirement diffs",
|
|
172217
|
+
summary
|
|
171940
172218
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171941
|
-
className: "min-w-0
|
|
172219
|
+
className: "min-w-0 text-xs",
|
|
171942
172220
|
children
|
|
171943
172221
|
})]
|
|
171944
172222
|
});
|
|
171945
172223
|
}
|
|
171946
|
-
/** CLI MODIFIED-delta diff evidence for the Change Evidence workspace (live
|
|
172224
|
+
/** CLI MODIFIED-delta diff evidence for the Change Evidence workspace (admitted-line live sessions only). */
|
|
171947
172225
|
function ChangeDiffEvidence({ changeId, onChip }) {
|
|
171948
172226
|
const cli = useRootActionState().context?.cli;
|
|
171949
172227
|
const diffCapable = deriveOpenSpecCliCapabilities(cli?.available ? parseOpenSpecCliVersion(cli.version) : null).requirementDiff;
|
|
@@ -172017,9 +172295,13 @@ function ChangeDiffEvidence({ changeId, onChip }) {
|
|
|
172017
172295
|
if (!diffCapable) {
|
|
172018
172296
|
if (cli?.available !== true) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequirementDiffsSection, {
|
|
172019
172297
|
summary: "CLI diff evidence",
|
|
172020
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
172298
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
172021
172299
|
className: "text-muted-foreground",
|
|
172022
|
-
children:
|
|
172300
|
+
children: [
|
|
172301
|
+
"Requirement diff evidence from `show --diff` appears here on admitted OpenSpec CLI sessions (",
|
|
172302
|
+
OPENSPEC_CLI_ACCEPTED_RANGE,
|
|
172303
|
+
") once the CLI is detected."
|
|
172304
|
+
]
|
|
172023
172305
|
})
|
|
172024
172306
|
});
|
|
172025
172307
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequirementDiffsSection, {
|
|
@@ -172027,7 +172309,9 @@ function ChangeDiffEvidence({ changeId, onChip }) {
|
|
|
172027
172309
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
172028
172310
|
className: "text-muted-foreground",
|
|
172029
172311
|
children: [
|
|
172030
|
-
"Requirement diffs require an admitted OpenSpec CLI
|
|
172312
|
+
"Requirement diffs require an admitted OpenSpec CLI session (",
|
|
172313
|
+
OPENSPEC_CLI_ACCEPTED_RANGE,
|
|
172314
|
+
")",
|
|
172031
172315
|
cli.version ? ` (detected ${cli.version.trim()})` : "",
|
|
172032
172316
|
". This session's CLI does not declare the `show --diff` capability, so the delta presentation keeps using the captured local content."
|
|
172033
172317
|
]
|
|
@@ -172062,11 +172346,11 @@ function ChangeDiffEvidence({ changeId, onChip }) {
|
|
|
172062
172346
|
summary: "CLI diff evidence",
|
|
172063
172347
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
172064
172348
|
className: "text-muted-foreground",
|
|
172065
|
-
children: "Requirement diff evidence from `show --diff` appears here on
|
|
172349
|
+
children: "Requirement diff evidence from `show --diff` appears here on admitted CLI sessions."
|
|
172066
172350
|
})
|
|
172067
172351
|
});
|
|
172068
172352
|
if (evidence.kind !== "executed") {
|
|
172069
|
-
const detail = evidence.reason === "command-failed" ? evidence.detail : evidence.reason === "capability" ? "The detected OpenSpec CLI does not declare the
|
|
172353
|
+
const detail = evidence.reason === "command-failed" ? evidence.detail : evidence.reason === "capability" ? "The detected OpenSpec CLI does not declare the requirement-diff capability." : "The planning root is unavailable, so requirement-diff evidence cannot be fetched.";
|
|
172070
172354
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequirementDiffsSection, {
|
|
172071
172355
|
summary: "CLI evidence unavailable",
|
|
172072
172356
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -172149,6 +172433,7 @@ function ChangeDiffEvidence({ changeId, onChip }) {
|
|
|
172149
172433
|
*
|
|
172150
172434
|
* Original request (2026-08-03): use an Evidence tab to carry complete Change Detail information.
|
|
172151
172435
|
* Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
|
|
172436
|
+
* Owner walkthrough correction (2026-09-04): every Evidence detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding); this replaces each layer's local weak header.
|
|
172152
172437
|
*/
|
|
172153
172438
|
/** Shared section frame for the Evidence workspace detail pane; keeps the a11y heading. */
|
|
172154
172439
|
function WorkspaceSection({ id, title, summary, children, container = false }) {
|
|
@@ -172156,17 +172441,11 @@ function WorkspaceSection({ id, title, summary, children, container = false }) {
|
|
|
172156
172441
|
"data-evidence-section": id,
|
|
172157
172442
|
"aria-label": title,
|
|
172158
172443
|
className: container ? "@container min-w-0" : "min-w-0",
|
|
172159
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.
|
|
172160
|
-
|
|
172161
|
-
|
|
172162
|
-
className: "min-w-0 text-xs font-semibold",
|
|
172163
|
-
children: title
|
|
172164
|
-
}), summary ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
172165
|
-
className: "text-muted-foreground min-w-0 text-[11px]",
|
|
172166
|
-
children: summary
|
|
172167
|
-
}) : null]
|
|
172444
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
|
|
172445
|
+
title,
|
|
172446
|
+
summary
|
|
172168
172447
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
172169
|
-
className: "min-w-0
|
|
172448
|
+
className: "min-w-0 text-xs",
|
|
172170
172449
|
children
|
|
172171
172450
|
})]
|
|
172172
172451
|
});
|
|
@@ -172454,20 +172733,505 @@ function EvidenceList({ label, values }) {
|
|
|
172454
172733
|
});
|
|
172455
172734
|
}
|
|
172456
172735
|
//#endregion
|
|
172736
|
+
//#region src/components/validation-findings-evidence.tsx
|
|
172737
|
+
/**
|
|
172738
|
+
* Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
|
|
172739
|
+
* 1. Present the OpenSpec 1.12+ `validate --report findings` document (the admitted 1.13
|
|
172740
|
+
* line carries the capability) as typed CLI evidence.
|
|
172741
|
+
* 2. Attribute every item finding to its owning change: entries owned by the current change
|
|
172742
|
+
* render as the primary "This change" list, while entries owned by other active changes
|
|
172743
|
+
* stay in a clearly-labeled secondary disclosure with prominent change attribution — a
|
|
172744
|
+
* finding never presents as this change's finding just because the scope is shared.
|
|
172745
|
+
* 3. Render INFO as a first-class informational class, distinct from warnings and errors.
|
|
172746
|
+
* 4. Show the filtered view honestly: `returnedItems` beside the preserved full-run totals,
|
|
172747
|
+
* labeled as filtered, never presented as the complete validation result. Scope-level
|
|
172748
|
+
* counts are never filtered to the current change.
|
|
172749
|
+
* 5. Gate the affordance behind the admitted line's `findingsReport` capability: non-admitted
|
|
172750
|
+
* sessions get no findings action; static snapshots state the evidence is unavailable.
|
|
172751
|
+
* 6. Validate transport and findings payloads with the Core contract schemas, never shallow
|
|
172752
|
+
* guards, and keep the CLI-owned request-error envelope on the direct plane.
|
|
172753
|
+
*
|
|
172754
|
+
* Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
|
|
172755
|
+
* Owner walkthrough correction (2026-09-04): findings must attribute their owning change; the Evidence detail panel styling follows the vision review and every detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding) instead of a local weak header.
|
|
172756
|
+
* Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
|
|
172757
|
+
*/
|
|
172758
|
+
function parseFindingsPayload(value) {
|
|
172759
|
+
const parsed = CliValidateFindingsResultSchema.safeParse(value);
|
|
172760
|
+
if (parsed.success) return isCliValidateFindings(parsed.data) ? {
|
|
172761
|
+
kind: "findings",
|
|
172762
|
+
findings: parsed.data
|
|
172763
|
+
} : {
|
|
172764
|
+
kind: "request-failure",
|
|
172765
|
+
failure: parsed.data
|
|
172766
|
+
};
|
|
172767
|
+
const document = CliValidateFindingsSchema.safeParse(value);
|
|
172768
|
+
return {
|
|
172769
|
+
kind: "malformed",
|
|
172770
|
+
schemaIssues: (document.success ? parsed.error : document.error).issues.map((issue) => `${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`)
|
|
172771
|
+
};
|
|
172772
|
+
}
|
|
172773
|
+
/** Semantic level chip: box-radius geometry, distinct glyph per class, tinted never flooded. */
|
|
172774
|
+
var LEVEL_CHIP_CLASS = {
|
|
172775
|
+
INFO: "border-blue-600/40 bg-blue-500/5 text-blue-600 dark:text-blue-400",
|
|
172776
|
+
WARNING: "border-amber-600/40 bg-amber-500/5 text-amber-600 dark:text-amber-400",
|
|
172777
|
+
ERROR: "border-red-600/40 bg-red-500/5 text-red-600 dark:text-red-400"
|
|
172778
|
+
};
|
|
172779
|
+
var LEVEL_CHIP_GLYPH = {
|
|
172780
|
+
INFO: Info$1,
|
|
172781
|
+
WARNING: TriangleAlert,
|
|
172782
|
+
ERROR: OctagonAlert
|
|
172783
|
+
};
|
|
172784
|
+
function LevelChip({ level }) {
|
|
172785
|
+
const Glyph = LEVEL_CHIP_GLYPH[level];
|
|
172786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
172787
|
+
"data-findings-level": level,
|
|
172788
|
+
className: `inline-flex shrink-0 items-center gap-1 border px-1.5 py-0.5 text-[11px] font-semibold uppercase tracking-wide ${LEVEL_CHIP_CLASS[level]}`,
|
|
172789
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Glyph, {
|
|
172790
|
+
className: "h-3 w-3",
|
|
172791
|
+
"aria-hidden": true
|
|
172792
|
+
}), level]
|
|
172793
|
+
});
|
|
172794
|
+
}
|
|
172795
|
+
/**
|
|
172796
|
+
* One findings item as a header/body card. Each issue owns a header row (level chip, issue
|
|
172797
|
+
* path, item identity) and a neutral message body; multiple issues stack as divided rows.
|
|
172798
|
+
* The message itself never carries the level color — the chip is the only color carrier.
|
|
172799
|
+
*/
|
|
172800
|
+
function FindingCard({ item }) {
|
|
172801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("article", {
|
|
172802
|
+
"data-findings-item": item.id,
|
|
172803
|
+
className: "border-border bg-card min-w-0 overflow-hidden rounded border",
|
|
172804
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
172805
|
+
className: "border-border/60 m-0 list-none divide-y p-0",
|
|
172806
|
+
children: item.issues.map((issue, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
|
|
172807
|
+
"data-findings-issue": issue.level,
|
|
172808
|
+
className: "min-w-0",
|
|
172809
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
|
|
172810
|
+
className: "border-border flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 border-b px-2.5 py-1.5",
|
|
172811
|
+
children: [
|
|
172812
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LevelChip, { level: issue.level }),
|
|
172813
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
172814
|
+
className: "text-foreground min-w-0 flex-1 basis-[6rem] font-mono text-xs [overflow-wrap:anywhere]",
|
|
172815
|
+
children: issue.path
|
|
172816
|
+
}),
|
|
172817
|
+
index === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
172818
|
+
className: "text-muted-foreground max-w-full shrink-0 text-right font-mono text-[11px] [overflow-wrap:anywhere]",
|
|
172819
|
+
children: [
|
|
172820
|
+
item.id,
|
|
172821
|
+
" · ",
|
|
172822
|
+
item.type,
|
|
172823
|
+
" · ",
|
|
172824
|
+
item.valid ? "valid" : "invalid"
|
|
172825
|
+
]
|
|
172826
|
+
}) : null
|
|
172827
|
+
]
|
|
172828
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
172829
|
+
className: "text-foreground/90 px-2.5 py-2 text-xs leading-relaxed [overflow-wrap:anywhere]",
|
|
172830
|
+
children: issue.message
|
|
172831
|
+
})]
|
|
172832
|
+
}, index))
|
|
172833
|
+
})
|
|
172834
|
+
});
|
|
172835
|
+
}
|
|
172836
|
+
/** Compact count chip (box radius; pill geometry stays reserved for bare numeric counts). */
|
|
172837
|
+
function CountChip({ label, tone }) {
|
|
172838
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
172839
|
+
className: cn$1("inline-flex shrink-0 items-center rounded border px-1.5 py-0.5 text-xs font-medium", tone === "passed" && "border-emerald-600/40 bg-emerald-500/5 text-emerald-700 dark:text-emerald-400", tone === "failed" && "border-red-600/40 bg-red-500/5 text-red-600 dark:text-red-400", tone === "muted" && "border-border bg-muted/50 text-muted-foreground"),
|
|
172840
|
+
children: label
|
|
172841
|
+
});
|
|
172842
|
+
}
|
|
172843
|
+
function RunButton$1({ pending, label, onRun }) {
|
|
172844
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
172845
|
+
type: "button",
|
|
172846
|
+
onClick: onRun,
|
|
172847
|
+
disabled: pending,
|
|
172848
|
+
"aria-busy": pending || void 0,
|
|
172849
|
+
className: "border-border hover:bg-muted inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-xs disabled:opacity-50",
|
|
172850
|
+
children: [pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
|
|
172851
|
+
className: "h-3.5 w-3.5 animate-spin",
|
|
172852
|
+
"aria-hidden": true
|
|
172853
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCw, {
|
|
172854
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
172855
|
+
"aria-hidden": true
|
|
172856
|
+
}), label]
|
|
172857
|
+
});
|
|
172858
|
+
}
|
|
172859
|
+
/**
|
|
172860
|
+
* Structure-agnostic section frame for the Evidence workspace detail pane: heading plus
|
|
172861
|
+
* summary facts stay on the record; the workspace, not a disclosure, owns reveal behavior.
|
|
172862
|
+
* The header follows the workspace's one header contract: rule, baseline padding, margin.
|
|
172863
|
+
*/
|
|
172864
|
+
function ValidationFindingsSection({ summary, children }) {
|
|
172865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
172866
|
+
"data-evidence-section": "validation-findings",
|
|
172867
|
+
"aria-label": "Validation findings",
|
|
172868
|
+
className: "min-w-0",
|
|
172869
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceLayerHeader, {
|
|
172870
|
+
title: "Validation findings",
|
|
172871
|
+
summary
|
|
172872
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
172873
|
+
className: "min-w-0 text-xs",
|
|
172874
|
+
children
|
|
172875
|
+
})]
|
|
172876
|
+
});
|
|
172877
|
+
}
|
|
172878
|
+
/**
|
|
172879
|
+
* On-demand, read-only validation findings evidence for the Change Evidence workspace.
|
|
172880
|
+
*
|
|
172881
|
+
* The findings report is a filtered view — only items with issues — over the same full-run
|
|
172882
|
+
* totals the complete validation report carries, so the section always presents
|
|
172883
|
+
* `returnedItems` beside the preserved totals and never claims to be the complete result.
|
|
172884
|
+
* The report covers the whole changes scope, so every item finding is attributed: the
|
|
172885
|
+
* current change's entries render as the primary list and other changes' entries stay in a
|
|
172886
|
+
* labeled secondary disclosure with the owning change id prominent.
|
|
172887
|
+
*/
|
|
172888
|
+
function ValidationFindingsEvidence({ changeId, onChip }) {
|
|
172889
|
+
const [report, setReport] = (0, import_react.useState)(null);
|
|
172890
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
172891
|
+
const [pending, setPending] = (0, import_react.useState)(false);
|
|
172892
|
+
const cli = useRootActionState().context?.cli;
|
|
172893
|
+
const staticMode = isStaticMode();
|
|
172894
|
+
const capabilities = deriveOpenSpecCliCapabilities(cli?.available ? parseOpenSpecCliVersion(cli.version) : null);
|
|
172895
|
+
const chip = (0, import_react.useMemo)(() => {
|
|
172896
|
+
if (staticMode) return {
|
|
172897
|
+
label: "unavailable",
|
|
172898
|
+
tone: "unavailable"
|
|
172899
|
+
};
|
|
172900
|
+
if (cli?.available === true && !capabilities.findingsReport) return {
|
|
172901
|
+
label: "unavailable",
|
|
172902
|
+
tone: "unavailable"
|
|
172903
|
+
};
|
|
172904
|
+
if (!report && !error) return null;
|
|
172905
|
+
const parsed = report ? parseFindingsPayload(report.data) : null;
|
|
172906
|
+
if (error || !parsed || parsed.kind === "malformed") return {
|
|
172907
|
+
label: "fail",
|
|
172908
|
+
tone: "negative"
|
|
172909
|
+
};
|
|
172910
|
+
if (parsed.kind === "request-failure") return {
|
|
172911
|
+
label: "fail",
|
|
172912
|
+
tone: "negative"
|
|
172913
|
+
};
|
|
172914
|
+
const findings = parsed.findings;
|
|
172915
|
+
return findings.summary.totals.failed > 0 ? {
|
|
172916
|
+
label: `${findings.summary.totals.failed} failed`,
|
|
172917
|
+
tone: "negative"
|
|
172918
|
+
} : {
|
|
172919
|
+
label: `${findings.report.returnedItems} findings`,
|
|
172920
|
+
tone: "neutral"
|
|
172921
|
+
};
|
|
172922
|
+
}, [
|
|
172923
|
+
capabilities.findingsReport,
|
|
172924
|
+
cli?.available,
|
|
172925
|
+
error,
|
|
172926
|
+
report,
|
|
172927
|
+
staticMode
|
|
172928
|
+
]);
|
|
172929
|
+
(0, import_react.useEffect)(() => {
|
|
172930
|
+
onChip?.(chip);
|
|
172931
|
+
}, [chip, onChip]);
|
|
172932
|
+
if (staticMode) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
|
|
172933
|
+
summary: "Unavailable in static snapshot",
|
|
172934
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
172935
|
+
className: "text-muted-foreground",
|
|
172936
|
+
children: "Validation findings are live CLI evidence and are not captured in this static snapshot."
|
|
172937
|
+
})
|
|
172938
|
+
});
|
|
172939
|
+
if (cli?.available === true && !capabilities.findingsReport) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
|
|
172940
|
+
summary: "Unavailable on this CLI line",
|
|
172941
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
172942
|
+
className: "text-muted-foreground",
|
|
172943
|
+
children: [
|
|
172944
|
+
"Validation findings require the admitted OpenSpec CLI line (",
|
|
172945
|
+
OPENSPEC_CLI_ACCEPTED_RANGE,
|
|
172946
|
+
")",
|
|
172947
|
+
cli.version ? ` (detected ${cli.version.trim()})` : "",
|
|
172948
|
+
". This session's CLI does not declare the findings-report capability, so no command is offered."
|
|
172949
|
+
]
|
|
172950
|
+
})
|
|
172951
|
+
});
|
|
172952
|
+
const run = async () => {
|
|
172953
|
+
setPending(true);
|
|
172954
|
+
setError(null);
|
|
172955
|
+
setReport(null);
|
|
172956
|
+
try {
|
|
172957
|
+
const result = await trpcClient.cli.validate.mutate({
|
|
172958
|
+
kind: "findings",
|
|
172959
|
+
scope: "changes"
|
|
172960
|
+
});
|
|
172961
|
+
const transport = CliCommandTransportSchema.safeParse(result);
|
|
172962
|
+
if (transport.success) setReport({
|
|
172963
|
+
...transport.data,
|
|
172964
|
+
data: transport.data.data ?? null,
|
|
172965
|
+
payload: transport.data.payload ?? null
|
|
172966
|
+
});
|
|
172967
|
+
else setError("The validation findings transport returned an unrecognized result shape.");
|
|
172968
|
+
} catch (cause) {
|
|
172969
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
172970
|
+
} finally {
|
|
172971
|
+
setPending(false);
|
|
172972
|
+
}
|
|
172973
|
+
};
|
|
172974
|
+
if (!report && !error) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
|
|
172975
|
+
summary: "Not yet run",
|
|
172976
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
172977
|
+
className: "border-border bg-muted/20 max-w-[72ch] rounded-md border border-dashed p-6",
|
|
172978
|
+
children: pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
172979
|
+
className: "flex items-center gap-2",
|
|
172980
|
+
role: "status",
|
|
172981
|
+
"data-findings-running": "",
|
|
172982
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
|
|
172983
|
+
className: "text-muted-foreground h-4 w-4 animate-spin",
|
|
172984
|
+
"aria-hidden": true
|
|
172985
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
172986
|
+
className: "text-xs font-medium",
|
|
172987
|
+
children: "Running findings report…"
|
|
172988
|
+
})]
|
|
172989
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
172990
|
+
className: "space-y-3",
|
|
172991
|
+
children: [
|
|
172992
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
172993
|
+
className: "text-xs font-semibold",
|
|
172994
|
+
children: "No findings loaded"
|
|
172995
|
+
}),
|
|
172996
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
172997
|
+
className: "text-muted-foreground",
|
|
172998
|
+
children: "Load the official CLI's validation findings to see advisory issues reported for the active changes in this scope — including archive-merge advisories. This is read-only evidence; nothing is repaired from here."
|
|
172999
|
+
}),
|
|
173000
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {
|
|
173001
|
+
className: "border-border bg-muted rounded border px-1 py-0.5 font-mono text-[11px]",
|
|
173002
|
+
children: "openspec validate --report findings"
|
|
173003
|
+
}) }),
|
|
173004
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
|
|
173005
|
+
pending,
|
|
173006
|
+
label: "Load validation findings",
|
|
173007
|
+
onRun: () => void run()
|
|
173008
|
+
})
|
|
173009
|
+
]
|
|
173010
|
+
})
|
|
173011
|
+
})
|
|
173012
|
+
});
|
|
173013
|
+
const parsed = report ? parseFindingsPayload(report.data) : null;
|
|
173014
|
+
if (error || !parsed || parsed.kind === "malformed") {
|
|
173015
|
+
const schemaDiagnostic = parsed?.kind === "malformed" && parsed.schemaIssues.length > 0 ? parsed.schemaIssues.join("; ") : null;
|
|
173016
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
|
|
173017
|
+
summary: "CLI failure evidence",
|
|
173018
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173019
|
+
className: "space-y-2",
|
|
173020
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173021
|
+
className: "text-destructive flex items-start gap-2 break-words",
|
|
173022
|
+
role: "alert",
|
|
173023
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
173024
|
+
className: "mt-0.5 h-3.5 w-3.5 shrink-0",
|
|
173025
|
+
"aria-hidden": true
|
|
173026
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
173027
|
+
className: "min-w-0 [overflow-wrap:anywhere]",
|
|
173028
|
+
children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The validation findings command failed."
|
|
173029
|
+
})]
|
|
173030
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
|
|
173031
|
+
pending,
|
|
173032
|
+
label: "Rerun",
|
|
173033
|
+
onRun: () => void run()
|
|
173034
|
+
})]
|
|
173035
|
+
})
|
|
173036
|
+
});
|
|
173037
|
+
}
|
|
173038
|
+
if (parsed.kind === "request-failure") {
|
|
173039
|
+
const entries = parsed.failure.status;
|
|
173040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
|
|
173041
|
+
summary: "CLI request failure",
|
|
173042
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173043
|
+
className: "space-y-2",
|
|
173044
|
+
children: [
|
|
173045
|
+
entries.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173046
|
+
"data-findings-request-error": entry.code,
|
|
173047
|
+
className: "text-destructive flex items-start gap-2 break-words",
|
|
173048
|
+
role: "alert",
|
|
173049
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
173050
|
+
className: "mt-0.5 h-3.5 w-3.5 shrink-0",
|
|
173051
|
+
"aria-hidden": true
|
|
173052
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
173053
|
+
className: "min-w-0 [overflow-wrap:anywhere]",
|
|
173054
|
+
children: [
|
|
173055
|
+
entry.code,
|
|
173056
|
+
": ",
|
|
173057
|
+
entry.message
|
|
173058
|
+
]
|
|
173059
|
+
})]
|
|
173060
|
+
}, index)),
|
|
173061
|
+
entries.some((entry) => entry.fix !== void 0) ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
173062
|
+
className: "break-words",
|
|
173063
|
+
"data-findings-request-fix": true,
|
|
173064
|
+
children: ["CLI fix suggestion: ", entries.find((entry) => entry.fix !== void 0)?.fix]
|
|
173065
|
+
}) : null,
|
|
173066
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
|
|
173067
|
+
pending,
|
|
173068
|
+
label: "Rerun",
|
|
173069
|
+
onRun: () => void run()
|
|
173070
|
+
})
|
|
173071
|
+
]
|
|
173072
|
+
})
|
|
173073
|
+
});
|
|
173074
|
+
}
|
|
173075
|
+
const findings = parsed.findings;
|
|
173076
|
+
const totals = findings.summary.totals;
|
|
173077
|
+
const ownFindings = findings.itemFindings.filter((item) => item.id === changeId);
|
|
173078
|
+
const otherFindings = findings.itemFindings.filter((item) => item.id !== changeId);
|
|
173079
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsSection, {
|
|
173080
|
+
summary: `Filtered view · ${findings.report.returnedItems} of ${findings.report.totalItems} items with findings`,
|
|
173081
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173082
|
+
className: "space-y-3",
|
|
173083
|
+
children: [
|
|
173084
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
173085
|
+
className: "text-muted-foreground",
|
|
173086
|
+
"data-findings-filtered-note": true,
|
|
173087
|
+
children: "Filtered CLI evidence: only items that reported issues are listed. The complete validation result remains the full report; totals below are the full-run values the CLI preserved."
|
|
173088
|
+
}),
|
|
173089
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
|
|
173090
|
+
"data-findings-provenance": "",
|
|
173091
|
+
className: "@[28rem]:grid-cols-[150px_1fr] grid min-w-0 grid-cols-1 gap-x-3 gap-y-1",
|
|
173092
|
+
children: [
|
|
173093
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
173094
|
+
className: "text-muted-foreground",
|
|
173095
|
+
children: "Root"
|
|
173096
|
+
}),
|
|
173097
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
|
|
173098
|
+
className: "min-w-0 font-mono text-xs [overflow-wrap:anywhere]",
|
|
173099
|
+
children: findings.root.path
|
|
173100
|
+
}),
|
|
173101
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
173102
|
+
className: "text-muted-foreground",
|
|
173103
|
+
children: "Exit status"
|
|
173104
|
+
}),
|
|
173105
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
|
|
173106
|
+
className: "min-w-0 font-mono text-xs",
|
|
173107
|
+
children: report?.exitCode === null || report?.exitCode === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
173108
|
+
className: "text-muted-foreground",
|
|
173109
|
+
children: "—"
|
|
173110
|
+
}) : report.exitCode
|
|
173111
|
+
}),
|
|
173112
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
173113
|
+
className: "text-muted-foreground",
|
|
173114
|
+
children: "Items with findings"
|
|
173115
|
+
}),
|
|
173116
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dd", {
|
|
173117
|
+
className: "min-w-0 font-mono text-xs",
|
|
173118
|
+
children: [
|
|
173119
|
+
findings.report.returnedItems,
|
|
173120
|
+
" of ",
|
|
173121
|
+
findings.report.totalItems,
|
|
173122
|
+
" (",
|
|
173123
|
+
findings.report.scope,
|
|
173124
|
+
" ",
|
|
173125
|
+
"scope)"
|
|
173126
|
+
]
|
|
173127
|
+
})
|
|
173128
|
+
]
|
|
173129
|
+
}),
|
|
173130
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173131
|
+
className: "space-y-1.5",
|
|
173132
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
173133
|
+
className: "text-muted-foreground text-[11px]",
|
|
173134
|
+
children: "Full-run totals"
|
|
173135
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173136
|
+
className: "flex flex-wrap gap-1.5",
|
|
173137
|
+
"data-findings-totals": "",
|
|
173138
|
+
children: [
|
|
173139
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountChip, {
|
|
173140
|
+
label: `${totals.passed} passed`,
|
|
173141
|
+
tone: "passed"
|
|
173142
|
+
}),
|
|
173143
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountChip, {
|
|
173144
|
+
label: `${totals.failed} failed`,
|
|
173145
|
+
tone: totals.failed > 0 ? "failed" : "muted"
|
|
173146
|
+
}),
|
|
173147
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountChip, {
|
|
173148
|
+
label: `${totals.items} items`,
|
|
173149
|
+
tone: "muted"
|
|
173150
|
+
})
|
|
173151
|
+
]
|
|
173152
|
+
})]
|
|
173153
|
+
}),
|
|
173154
|
+
findings.itemFindings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
173155
|
+
className: "text-muted-foreground",
|
|
173156
|
+
children: "No item in this scope reported an issue. This filtered view lists issues only — it is not the complete validation result."
|
|
173157
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173158
|
+
className: "space-y-2",
|
|
173159
|
+
"data-findings-own": "",
|
|
173160
|
+
children: [
|
|
173161
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", {
|
|
173162
|
+
className: "text-xs font-semibold",
|
|
173163
|
+
children: "This change"
|
|
173164
|
+
}),
|
|
173165
|
+
ownFindings.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FindingCard, { item }, item.id)),
|
|
173166
|
+
ownFindings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
173167
|
+
className: "text-muted-foreground",
|
|
173168
|
+
"data-findings-own-empty": "",
|
|
173169
|
+
children: "No findings for this change in the filtered scope. Other entries below belong to other active changes."
|
|
173170
|
+
}) : null
|
|
173171
|
+
]
|
|
173172
|
+
}), otherFindings.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", {
|
|
173173
|
+
"data-findings-other": "",
|
|
173174
|
+
className: "border-border rounded border",
|
|
173175
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", {
|
|
173176
|
+
className: "cursor-pointer select-none px-2.5 py-2 text-xs font-medium",
|
|
173177
|
+
children: [
|
|
173178
|
+
"Findings from other active changes (",
|
|
173179
|
+
otherFindings.length,
|
|
173180
|
+
")"
|
|
173181
|
+
]
|
|
173182
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
173183
|
+
className: "border-border space-y-3 border-t px-2.5 py-2.5",
|
|
173184
|
+
children: otherFindings.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173185
|
+
className: "min-w-0 space-y-1",
|
|
173186
|
+
"data-findings-other-item": "",
|
|
173187
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
173188
|
+
className: "text-foreground font-mono text-xs font-medium",
|
|
173189
|
+
children: item.id
|
|
173190
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FindingCard, { item })]
|
|
173191
|
+
}, item.id))
|
|
173192
|
+
})]
|
|
173193
|
+
}) : null] }),
|
|
173194
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("footer", {
|
|
173195
|
+
className: "border-border mt-4 flex flex-wrap items-center justify-between gap-x-4 gap-y-2 border-t pt-3",
|
|
173196
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
173197
|
+
className: "text-muted-foreground font-mono text-[11px] [overflow-wrap:anywhere]",
|
|
173198
|
+
children: [
|
|
173199
|
+
"openspec validate --report findings · ",
|
|
173200
|
+
findings.report.scope,
|
|
173201
|
+
" scope"
|
|
173202
|
+
]
|
|
173203
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton$1, {
|
|
173204
|
+
pending,
|
|
173205
|
+
label: "Rerun",
|
|
173206
|
+
onRun: () => void run()
|
|
173207
|
+
})]
|
|
173208
|
+
})
|
|
173209
|
+
]
|
|
173210
|
+
})
|
|
173211
|
+
});
|
|
173212
|
+
}
|
|
173213
|
+
//#endregion
|
|
172457
173214
|
//#region src/components/evidence-workspace.tsx
|
|
172458
173215
|
/**
|
|
172459
|
-
* Orthogonal intents (
|
|
173216
|
+
* Orthogonal intents (updated 2026-09-04 Asia/Shanghai):
|
|
172460
173217
|
* 1. Own the Change Evidence tab's container-responsive list-detail workspace topology.
|
|
172461
173218
|
* 2. Preserve the decision-plane evidence layer order (summary/paths -> requirement diffs ->
|
|
172462
|
-
* archived validation -> CLI/raw payload) in keyboard-reachable
|
|
173219
|
+
* validation findings -> archived validation -> CLI/raw payload) in keyboard-reachable
|
|
173220
|
+
* list rows.
|
|
172463
173221
|
* 3. Derive row chips only from settled section facts; never fabricate counts or verdicts.
|
|
172464
173222
|
* 4. Keep the crowded drill presentational: the detail replaces the list with a back
|
|
172465
173223
|
* affordance, and back restores the list without unmounting settled evidence; focus
|
|
172466
173224
|
* follows the drill (row -> back affordance -> originating row) so keyboard users never
|
|
172467
173225
|
* land on a hidden element.
|
|
172468
173226
|
* 5. Keep sub-selection local runtime state — it never enters routes or browser storage.
|
|
173227
|
+
* 6. Separate the workspace planes visually: the list column is the muted rail and the
|
|
173228
|
+
* detail column is the card surface; detail prose caps its measure, and only the
|
|
173229
|
+
* selected row ever carries a row fill.
|
|
172469
173230
|
*
|
|
172470
173231
|
* Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
|
|
173232
|
+
* Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进"
|
|
173233
|
+
* Owner walkthrough correction (2026-09-04): findings must attribute their owning change; the Evidence detail panel styling follows the vision review and every detail layer renders the shared EvidenceLayerHeader contract (title dominant over body, house-standard border padding) instead of a local weak header.
|
|
173234
|
+
* Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
|
|
172471
173235
|
*/
|
|
172472
173236
|
/**
|
|
172473
173237
|
* Spacious threshold: below this inline size the workspace collapses to one column and the
|
|
@@ -172518,10 +173282,14 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
|
|
|
172518
173282
|
const pendingRestoreRowId = (0, import_react.useRef)(null);
|
|
172519
173283
|
const backHadFocus = (0, import_react.useRef)(false);
|
|
172520
173284
|
const [diffChip, setDiffChip] = (0, import_react.useState)(null);
|
|
173285
|
+
const [findingsChip, setFindingsChip] = (0, import_react.useState)(null);
|
|
172521
173286
|
const [validationChip, setValidationChip] = (0, import_react.useState)(null);
|
|
172522
173287
|
const handleDiffChip = (0, import_react.useCallback)((chip) => {
|
|
172523
173288
|
setDiffChip(chip);
|
|
172524
173289
|
}, []);
|
|
173290
|
+
const handleFindingsChip = (0, import_react.useCallback)((chip) => {
|
|
173291
|
+
setFindingsChip(chip);
|
|
173292
|
+
}, []);
|
|
172525
173293
|
const handleValidationChip = (0, import_react.useCallback)((chip) => {
|
|
172526
173294
|
setValidationChip(chip);
|
|
172527
173295
|
}, []);
|
|
@@ -172549,6 +173317,15 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
|
|
|
172549
173317
|
onChip: handleDiffChip
|
|
172550
173318
|
})
|
|
172551
173319
|
},
|
|
173320
|
+
{
|
|
173321
|
+
id: "validation-findings",
|
|
173322
|
+
label: "Validation findings",
|
|
173323
|
+
chip: findingsChip,
|
|
173324
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ValidationFindingsEvidence, {
|
|
173325
|
+
changeId,
|
|
173326
|
+
onChip: handleFindingsChip
|
|
173327
|
+
})
|
|
173328
|
+
},
|
|
172552
173329
|
{
|
|
172553
173330
|
id: "archived-validation",
|
|
172554
173331
|
label: "Archived validation",
|
|
@@ -172560,7 +173337,9 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
|
|
|
172560
173337
|
}, [
|
|
172561
173338
|
changeId,
|
|
172562
173339
|
diffChip,
|
|
173340
|
+
findingsChip,
|
|
172563
173341
|
handleDiffChip,
|
|
173342
|
+
handleFindingsChip,
|
|
172564
173343
|
handleValidationChip,
|
|
172565
173344
|
referenceEvidence,
|
|
172566
173345
|
status,
|
|
@@ -172608,7 +173387,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
|
|
|
172608
173387
|
"aria-label": "Evidence sections",
|
|
172609
173388
|
"data-evidence-pane": "list",
|
|
172610
173389
|
hidden: !showList || void 0,
|
|
172611
|
-
className: cn$1("scrollbar-thin scrollbar-track-transparent border-border
|
|
173390
|
+
className: cn$1("scrollbar-thin scrollbar-track-transparent bg-muted/40 border-border @[40rem]:border-r min-h-0 min-w-0 overflow-y-auto overflow-x-hidden overscroll-contain", !showList && "hidden"),
|
|
172612
173391
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
172613
173392
|
className: "divide-border/20 m-0 list-none divide-y p-0",
|
|
172614
173393
|
children: sections.map((section) => {
|
|
@@ -172639,7 +173418,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
|
|
|
172639
173418
|
"data-evidence-pane": "detail",
|
|
172640
173419
|
"data-change-evidence-scroll-owner": "",
|
|
172641
173420
|
hidden: !showDetail || void 0,
|
|
172642
|
-
className: cn$1("scrollbar-thin scrollbar-track-transparent min-h-0 min-w-0 overflow-y-auto overflow-x-hidden overscroll-contain", showDetail ? "flex flex-col" : "hidden"),
|
|
173421
|
+
className: cn$1("scrollbar-thin scrollbar-track-transparent bg-card min-h-0 min-w-0 overflow-y-auto overflow-x-hidden overscroll-contain", showDetail ? "flex flex-col" : "hidden"),
|
|
172643
173422
|
children: [!spacious && drilled ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
172644
173423
|
ref: backRef,
|
|
172645
173424
|
type: "button",
|
|
@@ -172652,7 +173431,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
|
|
|
172652
173431
|
backHadFocus.current = false;
|
|
172653
173432
|
},
|
|
172654
173433
|
onClick: backToList,
|
|
172655
|
-
className: "bg-
|
|
173434
|
+
className: "bg-card/95 border-border/60 text-muted-foreground hover:text-foreground focus-visible:ring-primary sticky top-0 z-10 flex min-h-9 w-full min-w-0 items-center gap-1.5 border-b px-3 text-xs outline-none backdrop-blur focus-visible:ring-2 focus-visible:ring-inset",
|
|
172656
173435
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, {
|
|
172657
173436
|
className: "h-3.5 w-3.5 shrink-0",
|
|
172658
173437
|
"aria-hidden": true
|
|
@@ -172660,7 +173439,7 @@ function EvidenceWorkspace({ changeId, status, referenceEvidence }) {
|
|
|
172660
173439
|
}) : null, sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
172661
173440
|
"data-evidence-detail": section.id,
|
|
172662
173441
|
hidden: section.id !== activeSection.id,
|
|
172663
|
-
className: "min-w-0 px-4 pb-
|
|
173442
|
+
className: "min-w-0 px-4 pb-6 pt-3 [&_p]:max-w-[88ch]",
|
|
172664
173443
|
children: section.content
|
|
172665
173444
|
}, section.id))]
|
|
172666
173445
|
})]
|
|
@@ -172903,13 +173682,14 @@ function RootActionNotice({ state }) {
|
|
|
172903
173682
|
//#endregion
|
|
172904
173683
|
//#region src/routes/change-view.tsx
|
|
172905
173684
|
/**
|
|
172906
|
-
* Orthogonal intents (updated 2026-
|
|
173685
|
+
* Orthogonal intents (updated 2026-09-12 Asia/Shanghai):
|
|
172907
173686
|
* 1. Render schema-aware change artifacts and source files while retaining terminal status errors.
|
|
172908
173687
|
* 2. Dispatch change workflows through routed compose/verify surfaces and the shared Operator launcher.
|
|
172909
173688
|
* 3. Lock every change workflow action behind current Root Context and Status projection authority.
|
|
172910
173689
|
* 4. Present Apply progress directly and expose project context/guidance through a Header Action Dialog.
|
|
172911
173690
|
* 5. Keep compact Change facts in subtitle badges while routing complete CLI evidence through a dedicated tab.
|
|
172912
173691
|
* 6. Mount the container-responsive list-detail Evidence workspace as the sole Evidence tab surface.
|
|
173692
|
+
* 7. Mount OpenSpec 1.13 Apply warnings and the build-order chain on the direct status plane.
|
|
172913
173693
|
*
|
|
172914
173694
|
* Original request (2026-07-15): "Root-dependent actions remain locked until root selection succeeds."
|
|
172915
173695
|
* Review request (2026-07-23): "代码已经提交,开始review。如果有问题,那么可更新change。"
|
|
@@ -172919,8 +173699,14 @@ function RootActionNotice({ state }) {
|
|
|
172919
173699
|
* Owner correction (2026-08-03): move Actions inline with the title, unify subtitle badges, and localize unavailable Tooltips.
|
|
172920
173700
|
* Original request (2026-08-15): 刷新/解析中状态收敛为副标题行内的 shiny 徽章,不再占据 statusRegion 块。
|
|
172921
173701
|
* Original request (2026-08-28): "直接将 0.10.0 和 0.11.0 一起适配,然后发布 v11。" — the Evidence
|
|
172922
|
-
* tab gains the
|
|
173702
|
+
* tab gains the capability-gated CLI MODIFIED-delta diff evidence beside the existing layers.
|
|
173703
|
+
* Original request (2026-09-03): "Openspec 1.12.0 刚刚放出来,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进" — the Evidence tab gains the findings evidence section.
|
|
172923
173704
|
* Original request (2026-08-28): "使用移动端的 list-detail 思维……分成两栏,左侧 list,右侧详情。这种结构替代手风琴会更好"
|
|
173705
|
+
* Original request (2026-09-12): "Openspec 1.13.0 释放了,你更新一下,调查变更内容,然后开始规划适配工作,我们将用标准工作流worktree来推进。让 codex 参与。"
|
|
173706
|
+
* Original request (2026-09-12): Owner walkthrough: unify the Change display title (generic "# Proposal"
|
|
173707
|
+
* headings fall back to the change id) and collapse Apply readiness guidance into one summary row.
|
|
173708
|
+
* — the status region gains the OpenSpec 1.13 Apply `warnings` and `missingPrerequisites`
|
|
173709
|
+
* direct-plane evidence beside the existing divergence notice.
|
|
172924
173710
|
*/
|
|
172925
173711
|
function ChangeView() {
|
|
172926
173712
|
const { changeId } = useParams({ from: "/changes/$changeId" });
|
|
@@ -172931,6 +173717,8 @@ function ChangeView() {
|
|
|
172931
173717
|
const { data: status, isLoading, error } = statusProjection;
|
|
172932
173718
|
const { data: applyInstructions } = useOpsxApplyInstructionsSubscription({ change: changeId });
|
|
172933
173719
|
const { data: files } = useChangeFilesSubscription(changeId);
|
|
173720
|
+
const changesRows = useChangesSubscription().data;
|
|
173721
|
+
const displayTitle = changeDisplayTitle(changeId, changesRows?.find((row) => row.id === changeId)?.name ?? status?.changeName);
|
|
172934
173722
|
const handleComposeAction = (0, import_react.useCallback)((actionId, artifactId) => {
|
|
172935
173723
|
if (actionId === "apply") {
|
|
172936
173724
|
launchApply({
|
|
@@ -173001,14 +173789,14 @@ function ChangeView() {
|
|
|
173001
173789
|
})
|
|
173002
173790
|
}] : [], [referenceEvidence, status]);
|
|
173003
173791
|
const hasReferenceFailures = referenceEvidence.state !== "unavailable" && referenceEvidence.references.some((reference) => reference.status.some((diagnostic) => diagnostic.severity === "error"));
|
|
173004
|
-
const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence);
|
|
173792
|
+
const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence) || (applyInstructions?.warnings?.length ?? 0) > 0 || (applyInstructions?.missingPrerequisites?.length ?? 0) > 0;
|
|
173005
173793
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OpsxEntityDetailView, {
|
|
173006
173794
|
entityId: changeId,
|
|
173007
173795
|
sharedFamily: "changes",
|
|
173008
173796
|
backTo: "/changes",
|
|
173009
173797
|
backTitle: "Back to Changes",
|
|
173010
173798
|
icon: GitBranch,
|
|
173011
|
-
title:
|
|
173799
|
+
title: displayTitle,
|
|
173012
173800
|
subtitle: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeContextSummary, {
|
|
173013
173801
|
status,
|
|
173014
173802
|
referenceEvidence,
|
|
@@ -173076,7 +173864,11 @@ function ChangeView() {
|
|
|
173076
173864
|
}) : null,
|
|
173077
173865
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootActionNotice, { state: rootAction }),
|
|
173078
173866
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeReferenceFailureNotice, { referenceEvidence }),
|
|
173079
|
-
applyInstructions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressNotice, {
|
|
173867
|
+
applyInstructions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressNotice, {
|
|
173868
|
+
applyInstructionProgress: applyInstructions.applyInstructionProgress,
|
|
173869
|
+
warnings: applyInstructions.warnings,
|
|
173870
|
+
missingPrerequisites: applyInstructions.missingPrerequisites
|
|
173871
|
+
}) : null
|
|
173080
173872
|
]
|
|
173081
173873
|
}) : null
|
|
173082
173874
|
});
|
|
@@ -173116,7 +173908,7 @@ var CONFIG_GUIDE_STAGE_META = {
|
|
|
173116
173908
|
//#region src/components/config/config-guide.tsx
|
|
173117
173909
|
var ConfigGuideContext = (0, import_react.createContext)(null);
|
|
173118
173910
|
(0, import_react.lazy)(async () => {
|
|
173119
|
-
return { default: (await import("./config-guide-presentation-
|
|
173911
|
+
return { default: (await import("./config-guide-presentation-B5oRLCcX.js")).ConfigGuidePresentationLayer };
|
|
173120
173912
|
});
|
|
173121
173913
|
/** Access the root-owned adaptive Guide runtime. */
|
|
173122
173914
|
function useConfigGuide() {
|
|
@@ -178158,6 +178950,8 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
|
|
|
178158
178950
|
* Original request (2026-07-31): "基于真实的布局去做骨架屏,或者说是直接让卡片自身去支持 Pending 样式"
|
|
178159
178951
|
* Original request (2026-07-31): "Code Git Snapshot 的 Other Worktrees 默认隐藏 (detached)。然后commitList这里默认显示5个就好"
|
|
178160
178952
|
* Original request (2026-07-31): "检查目前的这个 Code Git Snapshot,它非常慢,有时候甚至要十几秒"
|
|
178953
|
+
* Original request (2026-09-12): Owner walkthrough: unify the Change display title — generic
|
|
178954
|
+
* "# Proposal" headings fall back to the change id on every surface.
|
|
178161
178955
|
* Owner correction (2026-07-31): Hidden documents pause the timer; visibility resumes the remaining delay or refreshes once when the absolute deadline elapsed.
|
|
178162
178956
|
|
|
178163
178957
|
*/
|
|
@@ -178646,7 +179440,7 @@ function Dashboard() {
|
|
|
178646
179440
|
__vtHandoff: {
|
|
178647
179441
|
family: "changes",
|
|
178648
179442
|
entityId: change.id,
|
|
178649
|
-
title: change.name,
|
|
179443
|
+
title: changeDisplayTitle(change.id, change.name),
|
|
178650
179444
|
subtitle: change.id
|
|
178651
179445
|
}
|
|
178652
179446
|
}),
|
|
@@ -178663,7 +179457,7 @@ function Dashboard() {
|
|
|
178663
179457
|
className: "flex min-w-0 items-center gap-3",
|
|
178664
179458
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
|
|
178665
179459
|
changeId: change.id,
|
|
178666
|
-
name: change.name,
|
|
179460
|
+
name: changeDisplayTitle(change.id, change.name),
|
|
178667
179461
|
phase,
|
|
178668
179462
|
updatedAt: change.updatedAt,
|
|
178669
179463
|
formatTime: formatRelativeTime,
|