@openspecui/web 7.0.2 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/App-Bxg8Uu8T.css +1 -0
- package/dist/assets/{App-DZbK_VKF.js → App-CEbaO9p7.js} +158 -157
- package/dist/assets/{main-DvWl4ArY.js → main-MGKIORYy.js} +2 -2
- package/dist/assets/{trpc-CUrXyPaH.js → trpc-BVbs2EGH.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-DKZvKi_9.js +1 -0
- package/dist-ssg/client/assets/WebGLRenderer-Dct7rzs_.js +1 -0
- package/dist-ssg/client/assets/WebGPURenderer-DtpKkjmH.js +1 -0
- package/dist-ssg/client/assets/browserAll-CuNkItSE.js +1 -0
- package/dist-ssg/client/assets/{config-guide-presentation-PYNWYVfd.js → config-guide-presentation-C4Z-0SFk.js} +1 -1
- package/dist-ssg/client/assets/{dist-Cb1nIvKO.js → dist-B6W3pPHs.js} +1 -1
- package/dist-ssg/client/assets/{dist-C8koIGSO.js → dist-BKobWYD3.js} +1 -1
- package/dist-ssg/client/assets/{dist-BXD-ZTAM.js → dist-Bcjlb1bO.js} +1 -1
- package/dist-ssg/client/assets/dist-CWb-aAQf.js +1 -0
- package/dist-ssg/client/assets/dist-CYpiS1Zt.js +1 -0
- package/dist-ssg/client/assets/{dist-DZMoaNp9.js → dist-ClUVC_84.js} +1 -1
- package/dist-ssg/client/assets/{dist-B6_zeP9X.js → dist-D1Kgfdnc.js} +1 -1
- package/dist-ssg/client/assets/{dist-BxLfQE_c.js → dist-D64HT2KR.js} +1 -1
- package/dist-ssg/client/assets/dist-H38juOFW.js +1 -0
- package/dist-ssg/client/assets/{dist-n_0I1u31.js → dist-PiPP3-Ah.js} +1 -1
- package/dist-ssg/client/assets/{dist-f2vnkzi9.js → dist-k_96dSjT.js} +1 -1
- package/dist-ssg/client/assets/{dist-CD337m0H.js → dist-lYx3EWfZ.js} +1 -1
- package/dist-ssg/client/assets/{ghostty-web-DEm8ZrOM.js → ghostty-web-BIYzTj9q.js} +1 -1
- package/dist-ssg/client/assets/index-DqP4B4Rz.css +1 -0
- package/dist-ssg/client/assets/index.ssg-BtuMbAm3.js +1649 -0
- package/dist-ssg/client/assets/{init-mhU1_WMm.js → init-l-kQXEeR.js} +1 -1
- package/dist-ssg/client/assets/{trpc-DcBLtyHb.js → trpc-CHrTaCNa.js} +1 -1
- package/dist-ssg/client/assets/webworkerAll-BqQJxuyS.js +1 -0
- package/dist-ssg/client/index.ssg.html +2 -2
- package/dist-ssg/server/assets/CanvasRenderer-D5UXmqkQ.js +3 -0
- package/dist-ssg/server/assets/WebGLRenderer-CA7hgj6q.js +3 -0
- package/dist-ssg/server/assets/WebGPURenderer-CfV-9erK.js +3 -0
- package/dist-ssg/server/assets/{browserAll-C3TgySxy.js → browserAll-DmyvKJDK.js} +2 -2
- package/dist-ssg/server/assets/{config-guide-presentation-DluN0NgQ.js → config-guide-presentation-r59qmEkS.js} +1 -1
- package/dist-ssg/server/assets/{dist-DxUyXTq1.js → dist-0Gp0z2-n.js} +1 -1
- package/dist-ssg/server/assets/{dist-DukPjaq8.js → dist-BSrtv0FL.js} +1 -1
- package/dist-ssg/server/assets/{dist-C0UE33e7.js → dist-BaqegCo3.js} +1 -1
- package/dist-ssg/server/assets/dist-Bhwr_0k7.js +3 -0
- package/dist-ssg/server/assets/{dist-CcweeoW2.js → dist-DRkFTPqz.js} +1 -1
- package/dist-ssg/server/assets/{dist-BQopLPgi.js → dist-DfJANrLX.js} +1 -1
- package/dist-ssg/server/assets/{dist-BSYA61e0.js → dist-DgvOnKuT.js} +1 -1
- package/dist-ssg/server/assets/{dist-DHRASvmg.js → dist-DlZIJzsh.js} +1 -1
- package/dist-ssg/server/assets/dist-cgbXhCvj.js +3 -0
- package/dist-ssg/server/assets/dist-edAEd-k-.js +3 -0
- package/dist-ssg/server/assets/{dist-BQhB00FX.js → dist-jJpwOzat.js} +1 -1
- package/dist-ssg/server/assets/{dist-CqznyH3C.js → dist-rENGOe6I.js} +1 -1
- package/dist-ssg/server/assets/{entry-server-CByGxb_0.js → entry-server-BzFP1YY0.js} +687 -301
- package/dist-ssg/server/assets/{init-C33dwfW5.js → init-Bx_sRhIx.js} +1 -1
- package/dist-ssg/server/assets/trpc-BbV9JZTO.js +3 -0
- package/dist-ssg/server/assets/webworkerAll-didcaEA_.js +4 -0
- package/dist-ssg/server/ssr-entry-manifest.json +25 -25
- package/package.json +3 -3
- package/dist/assets/App-Ddx3wr17.css +0 -1
- package/dist-ssg/client/assets/CanvasRenderer-DbReVIDE.js +0 -1
- package/dist-ssg/client/assets/WebGLRenderer-DYji4Hjk.js +0 -1
- package/dist-ssg/client/assets/WebGPURenderer-DCzgl3HP.js +0 -1
- package/dist-ssg/client/assets/browserAll-DyJwsAsx.js +0 -1
- package/dist-ssg/client/assets/dist-DOqQmBHc.js +0 -1
- package/dist-ssg/client/assets/dist-DUhJ59_2.js +0 -1
- package/dist-ssg/client/assets/dist-osbHiFDv.js +0 -1
- package/dist-ssg/client/assets/index-Dcu2Vogo.css +0 -1
- package/dist-ssg/client/assets/index.ssg-5ak0Ru-F.js +0 -1648
- package/dist-ssg/client/assets/webworkerAll-BZhOzVEX.js +0 -1
- package/dist-ssg/server/assets/CanvasRenderer-2gUSLPR3.js +0 -3
- package/dist-ssg/server/assets/WebGLRenderer-VYeMuiRZ.js +0 -3
- package/dist-ssg/server/assets/WebGPURenderer-CzqH7K0F.js +0 -3
- package/dist-ssg/server/assets/dist-Cr2VaH_X.js +0 -3
- package/dist-ssg/server/assets/dist-CuufxmlH.js +0 -3
- package/dist-ssg/server/assets/dist-D-tZhX9W.js +0 -3
- package/dist-ssg/server/assets/trpc-BZ-LKmoQ.js +0 -3
- package/dist-ssg/server/assets/webworkerAll-jouzdRxg.js +0 -4
|
@@ -29590,13 +29590,13 @@ var CliDiagnosticFailureSchema = objectType({ status: arrayType(CliDiagnosticSch
|
|
|
29590
29590
|
*
|
|
29591
29591
|
* Original request (2026-07-26): "即便现在有正在的任务,界面上仍然可以读到缓存,但它也能知道这个缓存现在正在被更新中。"
|
|
29592
29592
|
*/
|
|
29593
|
-
var CliJsonValueSchema$
|
|
29593
|
+
var CliJsonValueSchema$2 = lazyType(() => unionType([
|
|
29594
29594
|
stringType(),
|
|
29595
29595
|
numberType(),
|
|
29596
29596
|
booleanType(),
|
|
29597
29597
|
nullType(),
|
|
29598
|
-
arrayType(CliJsonValueSchema$
|
|
29599
|
-
recordType(stringType(), CliJsonValueSchema$
|
|
29598
|
+
arrayType(CliJsonValueSchema$2),
|
|
29599
|
+
recordType(stringType(), CliJsonValueSchema$2)
|
|
29600
29600
|
]));
|
|
29601
29601
|
/** Complete CLI attempt evidence retained when a Projection Work command rejects. */
|
|
29602
29602
|
var CliProjectionCommandEvidenceSchema = objectType({
|
|
@@ -29604,7 +29604,7 @@ var CliProjectionCommandEvidenceSchema = objectType({
|
|
|
29604
29604
|
stdout: stringType(),
|
|
29605
29605
|
stderr: stringType(),
|
|
29606
29606
|
exitCode: numberType().int().nullable(),
|
|
29607
|
-
payload: CliJsonValueSchema$
|
|
29607
|
+
payload: CliJsonValueSchema$2.nullable(),
|
|
29608
29608
|
diagnostics: arrayType(CliDiagnosticSchema),
|
|
29609
29609
|
contractError: stringType().optional()
|
|
29610
29610
|
});
|
|
@@ -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-BbV9JZTO.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-BbV9JZTO.js").then(({ trpcClient }) => trpcClient.kv.set.mutate({
|
|
31055
31055
|
key: this.storageKey,
|
|
31056
31056
|
value: {
|
|
31057
31057
|
mainTabs: this.state.mainTabs,
|
|
@@ -38941,6 +38941,65 @@ function F$1(t) {
|
|
|
38941
38941
|
throw new I$2(t);
|
|
38942
38942
|
}
|
|
38943
38943
|
//#endregion
|
|
38944
|
+
//#region ../core/src/cli-contracts/command-result.ts
|
|
38945
|
+
/**
|
|
38946
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
38947
|
+
* 1. Preserve every process-level fact from an OpenSpec CLI invocation.
|
|
38948
|
+
* 2. Validate command payloads without discarding the raw JSON document.
|
|
38949
|
+
* 3. Surface contract drift separately from CLI command failure.
|
|
38950
|
+
* 4. Provide the runtime transport-envelope schema for browser evidence boundaries.
|
|
38951
|
+
*
|
|
38952
|
+
* Original request (2026-07-15): "对新增字段保持可扩展,对必需语义严格验证。"
|
|
38953
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
38954
|
+
*/
|
|
38955
|
+
/** Runtime schema for one JSON value retained verbatim from CLI stdout. */
|
|
38956
|
+
var CliJsonValueSchema$1 = lazyType(() => unionType([
|
|
38957
|
+
stringType(),
|
|
38958
|
+
numberType(),
|
|
38959
|
+
booleanType(),
|
|
38960
|
+
nullType(),
|
|
38961
|
+
arrayType(CliJsonValueSchema$1),
|
|
38962
|
+
recordType(stringType(), CliJsonValueSchema$1)
|
|
38963
|
+
]));
|
|
38964
|
+
/** Runtime transport envelope for one CLI command result. */
|
|
38965
|
+
var CliCommandTransportSchema = objectType({
|
|
38966
|
+
success: booleanType(),
|
|
38967
|
+
stdout: stringType(),
|
|
38968
|
+
stderr: stringType(),
|
|
38969
|
+
exitCode: numberType().int().nullable(),
|
|
38970
|
+
data: CliJsonValueSchema$1.nullable(),
|
|
38971
|
+
payload: CliJsonValueSchema$1.nullable(),
|
|
38972
|
+
diagnostics: arrayType(CliDiagnosticSchema),
|
|
38973
|
+
contractError: stringType().optional()
|
|
38974
|
+
});
|
|
38975
|
+
//#endregion
|
|
38976
|
+
//#region ../core/src/cli-contracts/schema-resolution.ts
|
|
38977
|
+
/**
|
|
38978
|
+
* Orthogonal intents (created 2026-08-15 Asia/Shanghai):
|
|
38979
|
+
* 1. Decode `schemas --json` as a success-array or selected-Root failure sum type.
|
|
38980
|
+
* 2. Keep the 1.9 failure envelope's diagnostics and absent Root distinct from an empty catalog.
|
|
38981
|
+
* 3. Reuse the shared SchemaInfo entry shape across success and failure envelopes.
|
|
38982
|
+
* 4. Keep the sum type importable from browser-safe Core consumers without workflow contracts.
|
|
38983
|
+
*
|
|
38984
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
38985
|
+
*/
|
|
38986
|
+
/** One workflow schema discovered by the CLI-selected OpenSpec runtime. */
|
|
38987
|
+
var CliSchemaInfoSchema = objectType({
|
|
38988
|
+
name: stringType(),
|
|
38989
|
+
description: stringType().optional(),
|
|
38990
|
+
artifacts: arrayType(stringType()),
|
|
38991
|
+
source: enumType([
|
|
38992
|
+
"project",
|
|
38993
|
+
"user",
|
|
38994
|
+
"package"
|
|
38995
|
+
])
|
|
38996
|
+
}).passthrough();
|
|
38997
|
+
unionType([arrayType(CliSchemaInfoSchema), objectType({
|
|
38998
|
+
schemas: arrayType(CliSchemaInfoSchema),
|
|
38999
|
+
root: nullType(),
|
|
39000
|
+
status: arrayType(CliDiagnosticSchema).min(1)
|
|
39001
|
+
}).passthrough()]);
|
|
39002
|
+
//#endregion
|
|
38944
39003
|
//#region ../core/src/cli-contracts/store.ts
|
|
38945
39004
|
/**
|
|
38946
39005
|
* Orthogonal intents (created 2026-07-15 Asia/Shanghai):
|
|
@@ -39088,18 +39147,6 @@ objectType({
|
|
|
39088
39147
|
root: CliRootSchema.nullable(),
|
|
39089
39148
|
status: arrayType(CliDiagnosticSchema).optional()
|
|
39090
39149
|
}).passthrough();
|
|
39091
|
-
/** One workflow schema discovered by the CLI-selected OpenSpec runtime. */
|
|
39092
|
-
var CliSchemaInfoSchema = objectType({
|
|
39093
|
-
name: stringType(),
|
|
39094
|
-
description: stringType().optional(),
|
|
39095
|
-
artifacts: arrayType(stringType()),
|
|
39096
|
-
source: enumType([
|
|
39097
|
-
"project",
|
|
39098
|
-
"user",
|
|
39099
|
-
"package"
|
|
39100
|
-
])
|
|
39101
|
-
}).passthrough();
|
|
39102
|
-
arrayType(CliSchemaInfoSchema);
|
|
39103
39150
|
/** CLI resolution for one schema, including lower-priority shadows. */
|
|
39104
39151
|
var CliSchemaShadowSchema = objectType({
|
|
39105
39152
|
source: enumType([
|
|
@@ -39189,7 +39236,8 @@ unionType([objectType({
|
|
|
39189
39236
|
planningHome: CliPlanningHomeSchema,
|
|
39190
39237
|
changeRoot: stringType(),
|
|
39191
39238
|
artifactPaths: recordType(CliArtifactPathSchema),
|
|
39192
|
-
|
|
39239
|
+
isPlanningComplete: booleanType(),
|
|
39240
|
+
isComplete: booleanType().optional(),
|
|
39193
39241
|
applyRequires: arrayType(stringType()),
|
|
39194
39242
|
nextSteps: arrayType(stringType()),
|
|
39195
39243
|
actionContext: CliActionContextSchema,
|
|
@@ -39272,7 +39320,8 @@ var CliValidationTotalsSchema = objectType({
|
|
|
39272
39320
|
passed: numberType(),
|
|
39273
39321
|
failed: numberType()
|
|
39274
39322
|
}).passthrough();
|
|
39275
|
-
|
|
39323
|
+
/** Typed ordinary Validate report, also used by 1.9 `validate --archived --json`. */
|
|
39324
|
+
var CliValidateReportSchema = objectType({
|
|
39276
39325
|
items: arrayType(objectType({
|
|
39277
39326
|
id: stringType(),
|
|
39278
39327
|
type: enumType(["change", "spec"]),
|
|
@@ -39286,7 +39335,8 @@ unionType([objectType({
|
|
|
39286
39335
|
}).passthrough(),
|
|
39287
39336
|
version: stringType(),
|
|
39288
39337
|
root: CliRootSchema
|
|
39289
|
-
}).passthrough()
|
|
39338
|
+
}).passthrough();
|
|
39339
|
+
unionType([CliValidateReportSchema, CliDiagnosticFailureSchema]);
|
|
39290
39340
|
var CliArchiveTotalsSchema = objectType({
|
|
39291
39341
|
added: numberType(),
|
|
39292
39342
|
modified: numberType(),
|
|
@@ -39299,7 +39349,8 @@ objectType({
|
|
|
39299
39349
|
archivedAs: stringType(),
|
|
39300
39350
|
path: stringType(),
|
|
39301
39351
|
specsUpdated: booleanType(),
|
|
39302
|
-
totals: CliArchiveTotalsSchema.optional()
|
|
39352
|
+
totals: CliArchiveTotalsSchema.optional(),
|
|
39353
|
+
warnings: arrayType(stringType()).optional()
|
|
39303
39354
|
}).passthrough().nullable(),
|
|
39304
39355
|
root: CliRootSchema.optional(),
|
|
39305
39356
|
status: arrayType(CliDiagnosticSchema).optional()
|
|
@@ -39993,7 +40044,7 @@ function buildChangeStatus(snapshot, change, preferredSchema) {
|
|
|
39993
40044
|
return {
|
|
39994
40045
|
changeName: change.id,
|
|
39995
40046
|
schemaName,
|
|
39996
|
-
|
|
40047
|
+
isPlanningComplete: artifacts.length > 0 && artifacts.every((artifact) => artifact.status === "done"),
|
|
39997
40048
|
applyRequires: schemaDetail.applyRequires ?? [],
|
|
39998
40049
|
artifacts,
|
|
39999
40050
|
provenance: { kind: "static" }
|
|
@@ -40180,6 +40231,7 @@ async function getDashboardOverview() {
|
|
|
40180
40231
|
id: change.id,
|
|
40181
40232
|
name: change.name,
|
|
40182
40233
|
trackedTaskProgress: change.trackedTaskProgress,
|
|
40234
|
+
cliTaskSummary: change.cliTaskSummary ?? null,
|
|
40183
40235
|
updatedAt: change.updatedAt
|
|
40184
40236
|
}));
|
|
40185
40237
|
const activeChanges = selectRecentDashboardItems(allActiveChanges);
|
|
@@ -40311,7 +40363,8 @@ async function getChanges() {
|
|
|
40311
40363
|
trackedTaskProgress: change.trackedTaskProgress,
|
|
40312
40364
|
documentChecklistSummary: change.documentChecklistSummary,
|
|
40313
40365
|
createdAt: change.createdAt,
|
|
40314
|
-
updatedAt: change.updatedAt
|
|
40366
|
+
updatedAt: change.updatedAt,
|
|
40367
|
+
cliTaskSummary: change.cliTaskSummary ?? null
|
|
40315
40368
|
}));
|
|
40316
40369
|
}
|
|
40317
40370
|
/**
|
|
@@ -40465,9 +40518,23 @@ async function getConfig$1() {
|
|
|
40465
40518
|
async function getOpsxProjectConfig() {
|
|
40466
40519
|
return (await loadSnapshot())?.opsx?.configYaml ?? null;
|
|
40467
40520
|
}
|
|
40521
|
+
/** Typed static projection error raised when the export captured a schemas-observation failure. */
|
|
40522
|
+
var StaticSchemasCaptureError = class extends Error {
|
|
40523
|
+
constructor(capture) {
|
|
40524
|
+
super(capture.diagnostics.length > 0 ? capture.diagnostics.map((diagnostic) => diagnostic.message).join("\n") : capture.stderr.trim() || "The static schemas observation failed.");
|
|
40525
|
+
this.capture = capture;
|
|
40526
|
+
this.name = "StaticSchemasCaptureError";
|
|
40527
|
+
}
|
|
40528
|
+
};
|
|
40529
|
+
/** Reject list and bundle reads when the export captured a schemas-observation failure. */
|
|
40530
|
+
function assertSchemasCaptureCaptured(snapshot) {
|
|
40531
|
+
const capture = snapshot?.opsx?.schemasCapture;
|
|
40532
|
+
if (capture && capture.ok === false) throw new StaticSchemasCaptureError(capture);
|
|
40533
|
+
}
|
|
40468
40534
|
/** Return the static Schema list together with its detail and resolution projections. */
|
|
40469
40535
|
async function getOpsxConfigBundle() {
|
|
40470
40536
|
const snapshot = await loadSnapshot();
|
|
40537
|
+
assertSchemasCaptureCaptured(snapshot);
|
|
40471
40538
|
return {
|
|
40472
40539
|
schemas: snapshot?.opsx?.schemas ?? [],
|
|
40473
40540
|
schemaDetails: snapshot?.opsx?.schemaDetails ?? {},
|
|
@@ -40477,6 +40544,7 @@ async function getOpsxConfigBundle() {
|
|
|
40477
40544
|
/** Return exported templates for the requested Schema, or the snapshot default Schema. */
|
|
40478
40545
|
async function getOpsxTemplates(schema) {
|
|
40479
40546
|
const snapshot = await loadSnapshot();
|
|
40547
|
+
assertSchemasCaptureCaptured(snapshot);
|
|
40480
40548
|
if (!snapshot?.opsx?.templates) return null;
|
|
40481
40549
|
if (!schema) {
|
|
40482
40550
|
const first = Object.keys(snapshot.opsx.templates)[0];
|
|
@@ -40497,6 +40565,7 @@ async function getOpsxTemplates(schema) {
|
|
|
40497
40565
|
/** Reconstruct the exported file tree for one Schema without enabling mutations. */
|
|
40498
40566
|
async function getOpsxSchemaFiles(name) {
|
|
40499
40567
|
const snapshot = await loadSnapshot();
|
|
40568
|
+
assertSchemasCaptureCaptured(snapshot);
|
|
40500
40569
|
if (!snapshot?.opsx) return null;
|
|
40501
40570
|
let schemaName = name;
|
|
40502
40571
|
if (!schemaName) schemaName = snapshot.opsx.schemas?.[0]?.name ?? Object.keys(snapshot.opsx.schemaDetails ?? {})[0];
|
|
@@ -40542,6 +40611,7 @@ async function getOpsxSchemaFiles(name) {
|
|
|
40542
40611
|
/** Return all exported template documents for the requested or default Schema. */
|
|
40543
40612
|
async function getOpsxTemplateContents(schema) {
|
|
40544
40613
|
const snapshot = await loadSnapshot();
|
|
40614
|
+
assertSchemasCaptureCaptured(snapshot);
|
|
40545
40615
|
if (!snapshot?.opsx) return null;
|
|
40546
40616
|
const targetSchema = schema ?? snapshot.opsx.schemas?.[0]?.name ?? Object.keys(snapshot.opsx.templates ?? {})[0] ?? null;
|
|
40547
40617
|
if (!targetSchema) return null;
|
|
@@ -43124,16 +43194,15 @@ function createApplyInstructionProgress(input, trackedTaskProgress) {
|
|
|
43124
43194
|
//#endregion
|
|
43125
43195
|
//#region ../core/src/opsx-types.ts
|
|
43126
43196
|
/**
|
|
43127
|
-
* Orthogonal intents (updated 2026-08-
|
|
43128
|
-
* 1.
|
|
43129
|
-
* 2.
|
|
43130
|
-
* 3.
|
|
43131
|
-
* 4.
|
|
43132
|
-
* 5.
|
|
43133
|
-
*
|
|
43134
|
-
* Original request (2026-07-15): "
|
|
43135
|
-
* Original request (2026-
|
|
43136
|
-
* Original request (2026-07-26): "展开全面的接口升级和内核升级和测试升级。"
|
|
43197
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
43198
|
+
* 1. Publish runtime schemas for final Projection Work payloads, including transformed Apply progress.
|
|
43199
|
+
* 2. Keep isPlanningComplete as the authoritative planning fact over any local tracked alias.
|
|
43200
|
+
* 3. Carry CLI status evidence, diagnostics, and per-artifact requires as typed facts.
|
|
43201
|
+
* 4. Preserve root-context and store projections as browser-safe contracts.
|
|
43202
|
+
* 5. Keep projection notices distinct from payload data so failures never masquerade as results.
|
|
43203
|
+
*
|
|
43204
|
+
* Original request (2026-07-15): "为内核载荷建立强类型。"
|
|
43205
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
43137
43206
|
*/
|
|
43138
43207
|
/** Runtime schema for one JSON value retained from a CLI Status stdout document. */
|
|
43139
43208
|
var OpsxCliJsonValueSchema = lazyType(() => unionType([
|
|
@@ -43183,7 +43252,7 @@ var ArtifactStatusSchema = objectType({
|
|
|
43183
43252
|
var ChangeStatusSchema = objectType({
|
|
43184
43253
|
changeName: stringType(),
|
|
43185
43254
|
schemaName: stringType(),
|
|
43186
|
-
|
|
43255
|
+
isPlanningComplete: booleanType(),
|
|
43187
43256
|
applyRequires: arrayType(stringType()),
|
|
43188
43257
|
artifacts: arrayType(ArtifactStatusSchema),
|
|
43189
43258
|
provenance: discriminatedUnionType("kind", [objectType({
|
|
@@ -43418,6 +43487,17 @@ var PlanningCliProjectionStateSchema = createCliProjectionStateSchema(discrimina
|
|
|
43418
43487
|
objectType({
|
|
43419
43488
|
kind: literalType("opsx-change-list"),
|
|
43420
43489
|
value: arrayType(stringType()),
|
|
43490
|
+
entries: arrayType(objectType({
|
|
43491
|
+
name: stringType(),
|
|
43492
|
+
completedTasks: numberType(),
|
|
43493
|
+
totalTasks: numberType(),
|
|
43494
|
+
lastModified: stringType(),
|
|
43495
|
+
status: enumType([
|
|
43496
|
+
"no-tasks",
|
|
43497
|
+
"complete",
|
|
43498
|
+
"in-progress"
|
|
43499
|
+
])
|
|
43500
|
+
})),
|
|
43421
43501
|
evidence: CliProjectionCommandEvidenceSchema
|
|
43422
43502
|
}),
|
|
43423
43503
|
objectType({
|
|
@@ -71019,7 +71099,7 @@ var browserExt = {
|
|
|
71019
71099
|
},
|
|
71020
71100
|
test: () => true,
|
|
71021
71101
|
load: async () => {
|
|
71022
|
-
await import("./browserAll-
|
|
71102
|
+
await import("./browserAll-DmyvKJDK.js");
|
|
71023
71103
|
}
|
|
71024
71104
|
};
|
|
71025
71105
|
//#endregion
|
|
@@ -71032,7 +71112,7 @@ var webworkerExt = {
|
|
|
71032
71112
|
},
|
|
71033
71113
|
test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
|
|
71034
71114
|
load: async () => {
|
|
71035
|
-
await import("./webworkerAll-
|
|
71115
|
+
await import("./webworkerAll-didcaEA_.js");
|
|
71036
71116
|
}
|
|
71037
71117
|
};
|
|
71038
71118
|
//#endregion
|
|
@@ -73626,7 +73706,7 @@ async function autoDetectRenderer(options) {
|
|
|
73626
73706
|
for (let i = 0; i < preferredOrder.length; i++) {
|
|
73627
73707
|
const rendererType = preferredOrder[i];
|
|
73628
73708
|
if (rendererType === "webgpu" && await isWebGPUSupported()) {
|
|
73629
|
-
const { WebGPURenderer } = await import("./WebGPURenderer-
|
|
73709
|
+
const { WebGPURenderer } = await import("./WebGPURenderer-CfV-9erK.js");
|
|
73630
73710
|
RendererClass = WebGPURenderer;
|
|
73631
73711
|
finalOptions = {
|
|
73632
73712
|
...options,
|
|
@@ -73634,7 +73714,7 @@ async function autoDetectRenderer(options) {
|
|
|
73634
73714
|
};
|
|
73635
73715
|
break;
|
|
73636
73716
|
} else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
|
|
73637
|
-
const { WebGLRenderer } = await import("./WebGLRenderer-
|
|
73717
|
+
const { WebGLRenderer } = await import("./WebGLRenderer-CA7hgj6q.js");
|
|
73638
73718
|
RendererClass = WebGLRenderer;
|
|
73639
73719
|
finalOptions = {
|
|
73640
73720
|
...options,
|
|
@@ -73642,7 +73722,7 @@ async function autoDetectRenderer(options) {
|
|
|
73642
73722
|
};
|
|
73643
73723
|
break;
|
|
73644
73724
|
} else if (rendererType === "canvas") {
|
|
73645
|
-
const { CanvasRenderer } = await import("./CanvasRenderer-
|
|
73725
|
+
const { CanvasRenderer } = await import("./CanvasRenderer-D5UXmqkQ.js");
|
|
73646
73726
|
RendererClass = CanvasRenderer;
|
|
73647
73727
|
finalOptions = {
|
|
73648
73728
|
...options,
|
|
@@ -97391,7 +97471,7 @@ var TerminalController = class {
|
|
|
97391
97471
|
if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
|
|
97392
97472
|
this.configPersistTimer = setTimeout(() => {
|
|
97393
97473
|
this.configPersistTimer = null;
|
|
97394
|
-
import("./trpc-
|
|
97474
|
+
import("./trpc-BbV9JZTO.js").then(({ trpcClient }) => {
|
|
97395
97475
|
trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
|
|
97396
97476
|
}).catch(() => {});
|
|
97397
97477
|
}, CONFIG_PERSIST_DEBOUNCE);
|
|
@@ -98960,6 +99040,42 @@ function ConfigFormSkeleton({ fields = 4 }) {
|
|
|
98960
99040
|
});
|
|
98961
99041
|
}
|
|
98962
99042
|
//#endregion
|
|
99043
|
+
//#region src/components/realtime/shiny-status.tsx
|
|
99044
|
+
/**
|
|
99045
|
+
* Orthogonal intents (created 2026-08-15 Asia/Shanghai):
|
|
99046
|
+
* 1. Animate normal-lifecycle text (loading/resolving/refreshing) with the shiny-text luminance language.
|
|
99047
|
+
* 2. Compose it into one keyboard-reachable Badge whose complete meaning lives in a Tooltip.
|
|
99048
|
+
* 3. Keep the polite live-region semantic for assistive tech without occupying layout space.
|
|
99049
|
+
*
|
|
99050
|
+
* Original request (2026-08-15): 刷新/解析中的块级 Alert 改为 Animated Shiny Text + Tooltip,不占界面空间。
|
|
99051
|
+
* Boundary: terminal errors/empty/block states are NOT normal lifecycle — they keep text notices.
|
|
99052
|
+
*/
|
|
99053
|
+
/** Normal-lifecycle text whose luminance sweep replaces a block-level loading notice. */
|
|
99054
|
+
function AnimatedShinyText({ children, className }) {
|
|
99055
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
99056
|
+
className: cn$1("rt-shiny-text", className),
|
|
99057
|
+
children
|
|
99058
|
+
});
|
|
99059
|
+
}
|
|
99060
|
+
/**
|
|
99061
|
+
* One inline lifecycle badge: shiny label + Tooltip message + hidden live region.
|
|
99062
|
+
* The accessible status carries the full message so `getByRole('status')` semantics survive.
|
|
99063
|
+
*/
|
|
99064
|
+
function ShinyStatusBadge({ label, message, className, ...badgeProps }) {
|
|
99065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tooltip, {
|
|
99066
|
+
content: message,
|
|
99067
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
99068
|
+
role: "note",
|
|
99069
|
+
tabIndex: 0,
|
|
99070
|
+
"aria-label": message,
|
|
99071
|
+
tone: "muted",
|
|
99072
|
+
className: cn$1("focus-visible:ring-primary cursor-help px-1.5 text-[11px] font-medium outline-none focus-visible:ring-2 focus-visible:ring-offset-2", className),
|
|
99073
|
+
...badgeProps,
|
|
99074
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AnimatedShinyText, { children: label })
|
|
99075
|
+
})
|
|
99076
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccessibleStatus, { children: message })] });
|
|
99077
|
+
}
|
|
99078
|
+
//#endregion
|
|
98963
99079
|
//#region src/lib/format-time.ts
|
|
98964
99080
|
/**
|
|
98965
99081
|
* Format a timestamp as relative time (e.g., "2 hours ago", "3 days ago")
|
|
@@ -107916,7 +108032,7 @@ var languages = [
|
|
|
107916
108032
|
name: "CSS",
|
|
107917
108033
|
extensions: ["css"],
|
|
107918
108034
|
load() {
|
|
107919
|
-
return import("./dist-
|
|
108035
|
+
return import("./dist-edAEd-k-.js").then((m) => m.css());
|
|
107920
108036
|
}
|
|
107921
108037
|
}),
|
|
107922
108038
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107936,7 +108052,7 @@ var languages = [
|
|
|
107936
108052
|
"hbs"
|
|
107937
108053
|
],
|
|
107938
108054
|
load() {
|
|
107939
|
-
return import("./dist-
|
|
108055
|
+
return import("./dist-DRkFTPqz.js").then((m) => m.html());
|
|
107940
108056
|
}
|
|
107941
108057
|
}),
|
|
107942
108058
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107970,7 +108086,7 @@ var languages = [
|
|
|
107970
108086
|
"jinja2"
|
|
107971
108087
|
],
|
|
107972
108088
|
load() {
|
|
107973
|
-
return import("./dist-
|
|
108089
|
+
return import("./dist-0Gp0z2-n.js").then((m) => m.jinja());
|
|
107974
108090
|
}
|
|
107975
108091
|
}),
|
|
107976
108092
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107978,7 +108094,7 @@ var languages = [
|
|
|
107978
108094
|
alias: ["json5"],
|
|
107979
108095
|
extensions: ["json", "map"],
|
|
107980
108096
|
load() {
|
|
107981
|
-
return import("./dist-
|
|
108097
|
+
return import("./dist-Bhwr_0k7.js").then((m) => m.json());
|
|
107982
108098
|
}
|
|
107983
108099
|
}),
|
|
107984
108100
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107992,14 +108108,14 @@ var languages = [
|
|
|
107992
108108
|
name: "LESS",
|
|
107993
108109
|
extensions: ["less"],
|
|
107994
108110
|
load() {
|
|
107995
|
-
return import("./dist-
|
|
108111
|
+
return import("./dist-BaqegCo3.js").then((m) => m.less());
|
|
107996
108112
|
}
|
|
107997
108113
|
}),
|
|
107998
108114
|
/* @__PURE__ */ LanguageDescription.of({
|
|
107999
108115
|
name: "Liquid",
|
|
108000
108116
|
extensions: ["liquid"],
|
|
108001
108117
|
load() {
|
|
108002
|
-
return import("./dist-
|
|
108118
|
+
return import("./dist-DfJANrLX.js").then((m) => m.liquid());
|
|
108003
108119
|
}
|
|
108004
108120
|
}),
|
|
108005
108121
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108016,7 +108132,7 @@ var languages = [
|
|
|
108016
108132
|
"mkd"
|
|
108017
108133
|
],
|
|
108018
108134
|
load() {
|
|
108019
|
-
return import("./dist-
|
|
108135
|
+
return import("./dist-DlZIJzsh.js").then((m) => m.markdown());
|
|
108020
108136
|
}
|
|
108021
108137
|
}),
|
|
108022
108138
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108042,7 +108158,7 @@ var languages = [
|
|
|
108042
108158
|
"phtml"
|
|
108043
108159
|
],
|
|
108044
108160
|
load() {
|
|
108045
|
-
return import("./dist-
|
|
108161
|
+
return import("./dist-rENGOe6I.js").then((m) => m.php());
|
|
108046
108162
|
}
|
|
108047
108163
|
}),
|
|
108048
108164
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108082,14 +108198,14 @@ var languages = [
|
|
|
108082
108198
|
name: "Sass",
|
|
108083
108199
|
extensions: ["sass"],
|
|
108084
108200
|
load() {
|
|
108085
|
-
return import("./dist-
|
|
108201
|
+
return import("./dist-BSrtv0FL.js").then((m) => m.sass({ indented: true }));
|
|
108086
108202
|
}
|
|
108087
108203
|
}),
|
|
108088
108204
|
/* @__PURE__ */ LanguageDescription.of({
|
|
108089
108205
|
name: "SCSS",
|
|
108090
108206
|
extensions: ["scss"],
|
|
108091
108207
|
load() {
|
|
108092
|
-
return import("./dist-
|
|
108208
|
+
return import("./dist-BSrtv0FL.js").then((m) => m.sass());
|
|
108093
108209
|
}
|
|
108094
108210
|
}),
|
|
108095
108211
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108156,7 +108272,7 @@ var languages = [
|
|
|
108156
108272
|
alias: ["yml"],
|
|
108157
108273
|
extensions: ["yaml", "yml"],
|
|
108158
108274
|
load() {
|
|
108159
|
-
return import("./dist-
|
|
108275
|
+
return import("./dist-cgbXhCvj.js").then((m) => m.yaml());
|
|
108160
108276
|
}
|
|
108161
108277
|
}),
|
|
108162
108278
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -109043,13 +109159,13 @@ var languages = [
|
|
|
109043
109159
|
name: "Vue",
|
|
109044
109160
|
extensions: ["vue"],
|
|
109045
109161
|
load() {
|
|
109046
|
-
return import("./dist-
|
|
109162
|
+
return import("./dist-DgvOnKuT.js").then((m) => m.vue());
|
|
109047
109163
|
}
|
|
109048
109164
|
}),
|
|
109049
109165
|
/* @__PURE__ */ LanguageDescription.of({
|
|
109050
109166
|
name: "Angular Template",
|
|
109051
109167
|
load() {
|
|
109052
|
-
return import("./dist-
|
|
109168
|
+
return import("./dist-jJpwOzat.js").then((m) => m.angular());
|
|
109053
109169
|
}
|
|
109054
109170
|
})
|
|
109055
109171
|
];
|
|
@@ -169249,8 +169365,7 @@ function ReadonlyKanban({ activeItems, archivedItems, activeCounts, archivedCoun
|
|
|
169249
169365
|
transition: { duration: .16 },
|
|
169250
169366
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReadonlyKanbanRow, {
|
|
169251
169367
|
item,
|
|
169252
|
-
laneId: lane.id
|
|
169253
|
-
compact
|
|
169368
|
+
laneId: lane.id
|
|
169254
169369
|
})
|
|
169255
169370
|
}, `${lane.id}:${item.id}`))
|
|
169256
169371
|
}), rows.length === 0 && count === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
@@ -169269,15 +169384,13 @@ function ReadonlyKanban({ activeItems, archivedItems, activeCounts, archivedCoun
|
|
|
169269
169384
|
})
|
|
169270
169385
|
});
|
|
169271
169386
|
}
|
|
169272
|
-
function ReadonlyKanbanRow({ item, laneId
|
|
169387
|
+
function ReadonlyKanbanRow({ item, laneId }) {
|
|
169273
169388
|
const archived = laneId === "archived";
|
|
169274
169389
|
const sharedDescriptor = {
|
|
169275
169390
|
family: archived ? "archive" : "changes",
|
|
169276
169391
|
entityId: item.id
|
|
169277
169392
|
};
|
|
169278
|
-
|
|
169279
|
-
const percent = progress.total > 0 ? Math.round(progress.completed / progress.total * 100) : 0;
|
|
169280
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(VTLink, {
|
|
169393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VTLink, {
|
|
169281
169394
|
to: archived ? "/archive/$changeId" : "/changes/$changeId",
|
|
169282
169395
|
params: { changeId: item.id },
|
|
169283
169396
|
state: (previous) => ({
|
|
@@ -169291,38 +169404,20 @@ function ReadonlyKanbanRow({ item, laneId, compact }) {
|
|
|
169291
169404
|
vt: { sharedElements: sharedDescriptor },
|
|
169292
169405
|
...getSharedElementBinding(sharedDescriptor, "container"),
|
|
169293
169406
|
className: "border-border/70 bg-card hover:bg-muted/50 block min-w-0 rounded-md border px-2.5 py-2",
|
|
169294
|
-
children:
|
|
169407
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169295
169408
|
className: "flex min-w-0 items-start gap-2",
|
|
169296
|
-
children: [
|
|
169297
|
-
|
|
169298
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
169299
|
-
|
|
169300
|
-
|
|
169301
|
-
|
|
169302
|
-
|
|
169303
|
-
|
|
169304
|
-
|
|
169305
|
-
|
|
169306
|
-
|
|
169307
|
-
|
|
169308
|
-
}),
|
|
169309
|
-
!archived ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
169310
|
-
className: "text-muted-foreground shrink-0 font-mono text-[10px]",
|
|
169311
|
-
children: [
|
|
169312
|
-
progress.completed,
|
|
169313
|
-
"/",
|
|
169314
|
-
progress.total
|
|
169315
|
-
]
|
|
169316
|
-
}) : null
|
|
169317
|
-
]
|
|
169318
|
-
}), !archived && !compact ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169319
|
-
className: "bg-muted mt-2 h-1 rounded-full",
|
|
169320
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(motion.div, {
|
|
169321
|
-
className: "bg-primary h-full rounded-full",
|
|
169322
|
-
initial: false,
|
|
169323
|
-
animate: { width: `${percent}%` }
|
|
169324
|
-
})
|
|
169325
|
-
}) : null]
|
|
169409
|
+
children: [archived ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Archive, { className: "text-muted-foreground mt-0.5 h-3.5 w-3.5 shrink-0" }) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169410
|
+
className: "min-w-0 flex-1",
|
|
169411
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169412
|
+
...getSharedElementBinding(sharedDescriptor, "title"),
|
|
169413
|
+
className: "truncate text-xs font-medium",
|
|
169414
|
+
children: item.name
|
|
169415
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169416
|
+
className: "text-muted-foreground truncate text-[11px]",
|
|
169417
|
+
children: archived ? formatDate(getKanbanArchiveTimestamp(item)) : item.updatedAt > 0 ? formatRelativeTime(item.updatedAt) : item.id
|
|
169418
|
+
})]
|
|
169419
|
+
})]
|
|
169420
|
+
})
|
|
169326
169421
|
});
|
|
169327
169422
|
}
|
|
169328
169423
|
//#endregion
|
|
@@ -169673,27 +169768,93 @@ function Board() {
|
|
|
169673
169768
|
});
|
|
169674
169769
|
}
|
|
169675
169770
|
//#endregion
|
|
169771
|
+
//#region src/components/change-row.tsx
|
|
169772
|
+
/**
|
|
169773
|
+
* Orthogonal intents (created 2026-08-15 Asia/Shanghai):
|
|
169774
|
+
* 1. Render one Change row with a grid: icon, title/subtitle, and a right rail.
|
|
169775
|
+
* 2. Keep the phase badge vertically centered while the time anchors the rail bottom.
|
|
169776
|
+
* 3. Share the exact row vocabulary between the Changes list and Dashboard.
|
|
169777
|
+
* 4. Preserve shared-element bindings for View Transition continuity.
|
|
169778
|
+
* 5. Keep the phase badge a planning/artifact signal; Apply progress belongs to Change Detail.
|
|
169779
|
+
*
|
|
169780
|
+
* Original request (2026-08-15): Owner walkthrough: grid layout, subtitle facts, badge
|
|
169781
|
+
* centered with time at the bottom, one atomic row component across pages.
|
|
169782
|
+
*/
|
|
169783
|
+
/** Shared Change-row layout: icon | title+subtitle | badge(time) | chevron. */
|
|
169784
|
+
function ChangeRow({ changeId, name, subtitle, phase, updatedAt, formatTime, sharedFamily = "changes", className = "", containerProps, titleProps, iconProps }) {
|
|
169785
|
+
const sharedDescriptor = {
|
|
169786
|
+
family: sharedFamily,
|
|
169787
|
+
entityId: changeId
|
|
169788
|
+
};
|
|
169789
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169790
|
+
...containerProps,
|
|
169791
|
+
...getSharedElementBinding(sharedDescriptor, "container"),
|
|
169792
|
+
className: `grid grid-cols-[auto_minmax(0,1fr)_auto] items-stretch gap-x-3 ${className}`,
|
|
169793
|
+
children: [
|
|
169794
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169795
|
+
className: "flex items-center",
|
|
169796
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitBranch, {
|
|
169797
|
+
...iconProps,
|
|
169798
|
+
...getSharedElementBinding(sharedDescriptor, "icon"),
|
|
169799
|
+
className: "text-muted-foreground h-5 w-5 shrink-0"
|
|
169800
|
+
})
|
|
169801
|
+
}),
|
|
169802
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169803
|
+
className: "flex min-w-0 flex-col justify-center gap-0.5 py-0.5",
|
|
169804
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169805
|
+
...titleProps,
|
|
169806
|
+
...getSharedElementBinding(sharedDescriptor, "title"),
|
|
169807
|
+
className: "truncate font-medium",
|
|
169808
|
+
children: name
|
|
169809
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169810
|
+
className: "text-muted-foreground truncate text-xs",
|
|
169811
|
+
children: subtitle
|
|
169812
|
+
})]
|
|
169813
|
+
}),
|
|
169814
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169815
|
+
className: "flex flex-col items-end justify-between gap-1 text-right",
|
|
169816
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169817
|
+
className: "flex flex-1 items-center",
|
|
169818
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
169819
|
+
tone: "custom",
|
|
169820
|
+
size: "sm",
|
|
169821
|
+
shape: "box",
|
|
169822
|
+
className: `border ${phase.toneClass}`,
|
|
169823
|
+
children: phase.label
|
|
169824
|
+
})
|
|
169825
|
+
}), updatedAt > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
169826
|
+
className: "text-muted-foreground shrink-0 text-xs",
|
|
169827
|
+
children: formatTime(updatedAt)
|
|
169828
|
+
}) : null]
|
|
169829
|
+
})
|
|
169830
|
+
]
|
|
169831
|
+
});
|
|
169832
|
+
}
|
|
169833
|
+
/** Chevron affordance kept outside the grid so row layouts stay composable. */
|
|
169834
|
+
function ChangeRowChevron() {
|
|
169835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, {
|
|
169836
|
+
className: "text-muted-foreground h-4 w-4 shrink-0",
|
|
169837
|
+
"aria-hidden": true
|
|
169838
|
+
});
|
|
169839
|
+
}
|
|
169840
|
+
//#endregion
|
|
169676
169841
|
//#region src/lib/change-workflow-phase.ts
|
|
169677
169842
|
function classifyChangeWorkflowPhase(params) {
|
|
169678
169843
|
if (!params.hasStatus) return {
|
|
169679
169844
|
label: "Unknown",
|
|
169680
169845
|
toneClass: "border-border text-muted-foreground"
|
|
169681
169846
|
};
|
|
169682
|
-
if (params.isComplete && params.trackedTaskPhase === "complete") return {
|
|
169683
|
-
label: "Workflow Complete",
|
|
169684
|
-
toneClass: "border-emerald-500/40 text-emerald-700 dark:text-emerald-300"
|
|
169685
|
-
};
|
|
169686
169847
|
if (params.trackedArtifactStatus === "blocked") return {
|
|
169687
169848
|
label: "Draft",
|
|
169688
169849
|
toneClass: "border-amber-500/40 text-amber-700 dark:text-amber-300"
|
|
169689
169850
|
};
|
|
169690
|
-
if (params.
|
|
169691
|
-
label: "
|
|
169692
|
-
toneClass: "border-
|
|
169851
|
+
if (params.isPlanningComplete) return {
|
|
169852
|
+
label: "Planning Complete",
|
|
169853
|
+
toneClass: "border-sky-500/40 text-sky-700 dark:text-sky-300"
|
|
169693
169854
|
};
|
|
169694
169855
|
return {
|
|
169695
|
-
label: "
|
|
169696
|
-
toneClass: "border-
|
|
169856
|
+
label: "Planning",
|
|
169857
|
+
toneClass: "border-border text-muted-foreground"
|
|
169697
169858
|
};
|
|
169698
169859
|
}
|
|
169699
169860
|
function inferTrackedArtifactStatus(artifactStatuses) {
|
|
@@ -169780,9 +169941,9 @@ function useChangeListContinuity(incomingChanges, containerRef) {
|
|
|
169780
169941
|
//#endregion
|
|
169781
169942
|
//#region src/routes/change-list.tsx
|
|
169782
169943
|
/**
|
|
169783
|
-
* Orthogonal intents (updated 2026-
|
|
169944
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
169784
169945
|
* 1. List only active Changes from the current writable Planning root.
|
|
169785
|
-
* 2. Derive
|
|
169946
|
+
* 2. Derive planning/artifact state and terminal evidence from CLI Status only.
|
|
169786
169947
|
* 3. Preserve ChangeList row continuity and stale display together with collision-safe detail navigation.
|
|
169787
169948
|
* 4. Keep the advanced New Change command reachable from the page header.
|
|
169788
169949
|
* 5. Defer aggregate workflow Status until a primary Change row is renderable; preserve explicit failures.
|
|
@@ -169793,6 +169954,8 @@ function useChangeListContinuity(incomingChanges, containerRef) {
|
|
|
169793
169954
|
*
|
|
169794
169955
|
* Original request (2026-07-15): "One project backend has one launch project and one CLI-selected writable planning root."
|
|
169795
169956
|
* Original request (2026-07-21): "Changes页面的右上角没有 New,你要不要快速补一个"
|
|
169957
|
+
|
|
169958
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
169796
169959
|
*/
|
|
169797
169960
|
function buildStatusMap(statuses) {
|
|
169798
169961
|
return new Map((statuses ?? []).map((status) => [status.changeName, status]));
|
|
@@ -169915,16 +170078,14 @@ function ChangeList() {
|
|
|
169915
170078
|
const totalArtifacts = status?.artifacts.length ?? 0;
|
|
169916
170079
|
const phase = classifyChangeWorkflowPhase({
|
|
169917
170080
|
hasStatus: Boolean(status),
|
|
169918
|
-
|
|
169919
|
-
trackedTaskPhase: change.trackedTaskProgress.phase,
|
|
170081
|
+
isPlanningComplete: status?.isPlanningComplete ?? false,
|
|
169920
170082
|
trackedArtifactStatus: inferTrackedArtifactStatus(status?.artifacts.map((artifact) => artifact.status) ?? [])
|
|
169921
170083
|
});
|
|
169922
|
-
const taskPercent = change.trackedTaskProgress.total > 0 ? Math.round(change.trackedTaskProgress.completed / change.trackedTaskProgress.total * 100) : 0;
|
|
169923
170084
|
const sharedDescriptor = {
|
|
169924
170085
|
family: "changes",
|
|
169925
170086
|
entityId: change.id
|
|
169926
170087
|
};
|
|
169927
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
170088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VTLink, {
|
|
169928
170089
|
to: "/changes/$changeId",
|
|
169929
170090
|
params: { changeId: change.id },
|
|
169930
170091
|
state: (prev) => ({
|
|
@@ -169939,74 +170100,25 @@ function ChangeList() {
|
|
|
169939
170100
|
vt: { sharedElements: sharedDescriptor },
|
|
169940
170101
|
...getSharedElementBinding(sharedDescriptor, "container"),
|
|
169941
170102
|
className: "hover:bg-muted/50 block px-4 py-3",
|
|
169942
|
-
children:
|
|
169943
|
-
|
|
169944
|
-
|
|
169945
|
-
|
|
169946
|
-
|
|
169947
|
-
|
|
169948
|
-
|
|
169949
|
-
|
|
169950
|
-
|
|
169951
|
-
|
|
169952
|
-
|
|
169953
|
-
|
|
169954
|
-
|
|
169955
|
-
|
|
169956
|
-
|
|
169957
|
-
|
|
169958
|
-
|
|
169959
|
-
|
|
169960
|
-
|
|
169961
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169962
|
-
className: "flex items-center gap-3",
|
|
169963
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169964
|
-
className: "flex flex-col items-end gap-1 text-right text-sm",
|
|
169965
|
-
children: [
|
|
169966
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
169967
|
-
tone: "custom",
|
|
169968
|
-
size: "sm",
|
|
169969
|
-
shape: "box",
|
|
169970
|
-
className: `border ${phase.toneClass}`,
|
|
169971
|
-
children: phase.label
|
|
169972
|
-
}),
|
|
169973
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169974
|
-
className: "font-medium",
|
|
169975
|
-
children: [
|
|
169976
|
-
change.trackedTaskProgress.completed,
|
|
169977
|
-
"/",
|
|
169978
|
-
change.trackedTaskProgress.total
|
|
169979
|
-
]
|
|
169980
|
-
}),
|
|
169981
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169982
|
-
className: "text-muted-foreground text-xs",
|
|
169983
|
-
children: "tasks"
|
|
169984
|
-
})
|
|
169985
|
-
]
|
|
169986
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "text-muted-foreground h-4 w-4 shrink-0" })]
|
|
169987
|
-
})]
|
|
169988
|
-
}),
|
|
169989
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169990
|
-
className: "bg-muted h-1.5 rounded-full",
|
|
169991
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169992
|
-
className: "bg-primary h-full rounded-full transition-all",
|
|
169993
|
-
style: { width: `${taskPercent}%` }
|
|
169994
|
-
})
|
|
169995
|
-
}),
|
|
169996
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169997
|
-
className: "text-muted-foreground mt-2 flex flex-wrap items-center justify-between gap-2 text-xs",
|
|
169998
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: change.trackedTaskProgress.phase === "no-tasks" ? "No tracked tasks" : `${taskPercent}% task completion` }), !statusError && status ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
169999
|
-
className: "truncate",
|
|
170000
|
-
children: [
|
|
170001
|
-
doneArtifacts,
|
|
170002
|
-
"/",
|
|
170003
|
-
totalArtifacts,
|
|
170004
|
-
" artifacts · ",
|
|
170005
|
-
status.schemaName
|
|
170006
|
-
]
|
|
170007
|
-
}) : !statusError && statuses === void 0 && isStatusLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RealtimeSkeletonLine, { className: "w-28" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Workflow status unavailable" })]
|
|
170008
|
-
})
|
|
170009
|
-
]
|
|
170103
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
170104
|
+
className: "flex items-center gap-3",
|
|
170105
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
|
|
170106
|
+
changeId: change.id,
|
|
170107
|
+
name: change.name,
|
|
170108
|
+
phase,
|
|
170109
|
+
updatedAt: change.updatedAt,
|
|
170110
|
+
formatTime: formatRelativeTime,
|
|
170111
|
+
className: "min-w-0 flex-1",
|
|
170112
|
+
titleProps: { ...change.id !== change.name ? {} : null },
|
|
170113
|
+
subtitle: !statusError && status ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
170114
|
+
doneArtifacts,
|
|
170115
|
+
"/",
|
|
170116
|
+
totalArtifacts,
|
|
170117
|
+
" artifacts · ",
|
|
170118
|
+
status.schemaName
|
|
170119
|
+
] }) : !statusError && statuses === void 0 && isStatusLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RealtimeSkeletonLine, { className: "w-28" }) : "Workflow status unavailable"
|
|
170120
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRowChevron, {})]
|
|
170121
|
+
})
|
|
170010
170122
|
}, change.id);
|
|
170011
170123
|
}), hasCurrentEmptyChanges && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
170012
170124
|
className: "text-muted-foreground p-4 text-center",
|
|
@@ -171034,15 +171146,41 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
|
|
|
171034
171146
|
//#endregion
|
|
171035
171147
|
//#region src/components/apply-progress-notice.tsx
|
|
171036
171148
|
/**
|
|
171037
|
-
* Orthogonal intents (updated 2026-
|
|
171149
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
171038
171150
|
* 1. Attribute Apply instruction counts to the upstream Apply command.
|
|
171039
|
-
* 2.
|
|
171040
|
-
* 3. Keep divergence
|
|
171151
|
+
* 2. Compress agreement to one subtitle badge; keep divergence a direct blocker.
|
|
171152
|
+
* 3. Keep divergence's two objective source counts side by side with their causes.
|
|
171153
|
+
* 4. Keep tooltips as the keyboard-reachable explanation for every compact count.
|
|
171041
171154
|
*
|
|
171042
171155
|
* Original request (2026-07-15): "与 tracked glob 进度分歧时各自归因展示。"
|
|
171043
171156
|
* Original request (2026-07-28): supporting 6.x evidence should use Badge + Tooltip or Accordion.
|
|
171157
|
+
* Original request (2026-08-15): Owner walkthrough: agreement is one badge in the subtitle row,
|
|
171158
|
+
* not a two-line block; only divergence owns a notice.
|
|
171159
|
+
*/
|
|
171160
|
+
/**
|
|
171161
|
+
* One compact, source-attributed Apply progress badge for the Change subtitle row.
|
|
171162
|
+
* The Apply instruction result is the only visible implementation progress authority, so
|
|
171163
|
+
* this stays rendered whenever instructions exist — agreement is not a reason to hide the
|
|
171164
|
+
* CLI's own count, but it needs no separate block.
|
|
171165
|
+
*/
|
|
171166
|
+
function ApplyProgressBadge({ applyInstructionProgress }) {
|
|
171167
|
+
const { complete, total, remaining } = applyInstructionProgress;
|
|
171168
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171169
|
+
ariaLabel: `Apply instructions progress ${complete} of ${total}`,
|
|
171170
|
+
tooltip: `Progress reported by openspec instructions apply — ${complete} of ${total} tasks applied, ${remaining} remaining.`,
|
|
171171
|
+
children: [
|
|
171172
|
+
"Apply ",
|
|
171173
|
+
complete,
|
|
171174
|
+
"/",
|
|
171175
|
+
total
|
|
171176
|
+
]
|
|
171177
|
+
});
|
|
171178
|
+
}
|
|
171179
|
+
/**
|
|
171180
|
+
* Render the Apply/tracked divergence as one direct, source-attributed blocker. Returns
|
|
171181
|
+
* null when the sources agree — the agreement case lives in the subtitle badge row via
|
|
171182
|
+
* {@link ApplyProgressBadge}.
|
|
171044
171183
|
*/
|
|
171045
|
-
/** Render source-attributed Apply progress and any tracked-progress divergence. */
|
|
171046
171184
|
function ApplyProgressNotice({ applyInstructionProgress }) {
|
|
171047
171185
|
const divergence = applyInstructionProgress.divergence;
|
|
171048
171186
|
if (!divergence) return null;
|
|
@@ -171064,13 +171202,13 @@ function ApplyProgressNotice({ applyInstructionProgress }) {
|
|
|
171064
171202
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171065
171203
|
className: "flex flex-wrap gap-1.5",
|
|
171066
171204
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171067
|
-
ariaLabel: `Apply instructions progress ${
|
|
171205
|
+
ariaLabel: `Apply instructions progress ${applyInstructionProgress.complete} of ${applyInstructionProgress.total}`,
|
|
171068
171206
|
tooltip: "Progress reported by openspec instructions apply.",
|
|
171069
171207
|
children: [
|
|
171070
171208
|
"Apply ",
|
|
171071
|
-
|
|
171209
|
+
applyInstructionProgress.complete,
|
|
171072
171210
|
"/",
|
|
171073
|
-
|
|
171211
|
+
applyInstructionProgress.total
|
|
171074
171212
|
]
|
|
171075
171213
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171076
171214
|
ariaLabel: `Tracked artifact glob progress ${divergence.tracked.completed} of ${divergence.tracked.total}`,
|
|
@@ -171087,16 +171225,284 @@ function ApplyProgressNotice({ applyInstructionProgress }) {
|
|
|
171087
171225
|
})]
|
|
171088
171226
|
});
|
|
171089
171227
|
}
|
|
171228
|
+
var OPENSPEC_CLI_SUPPORTED_SERIES = ["1.8", "1.9"];
|
|
171229
|
+
/**
|
|
171230
|
+
* Derive command capabilities from one parsed CLI version.
|
|
171231
|
+
*
|
|
171232
|
+
* Only an admitted version — stable inside the accepted range — can select version-specific
|
|
171233
|
+
* capabilities. Unsupported forms (prereleases, >=1.10, below-range) and unparseable output
|
|
171234
|
+
* keep their mismatch evidence and expose no capability, so a page-level version bypass can
|
|
171235
|
+
* never manufacture a 1.9 command surface for a CLI the release line does not admit.
|
|
171236
|
+
*/
|
|
171237
|
+
function deriveOpenSpecCliCapabilities(version) {
|
|
171238
|
+
if (!isAdmittedVersion(version)) return {
|
|
171239
|
+
schemasRootSelector: false,
|
|
171240
|
+
archivedValidation: false
|
|
171241
|
+
};
|
|
171242
|
+
const onTargetSeries = isSeries(version, "1.9");
|
|
171243
|
+
return {
|
|
171244
|
+
schemasRootSelector: onTargetSeries,
|
|
171245
|
+
archivedValidation: onTargetSeries
|
|
171246
|
+
};
|
|
171247
|
+
}
|
|
171248
|
+
function parseOpenSpecCliVersion(raw) {
|
|
171249
|
+
if (!raw) return null;
|
|
171250
|
+
const match = raw.match(/(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/);
|
|
171251
|
+
if (!match) return null;
|
|
171252
|
+
return {
|
|
171253
|
+
major: Number(match[1]),
|
|
171254
|
+
minor: Number(match[2]),
|
|
171255
|
+
patch: Number(match[3]),
|
|
171256
|
+
prerelease: match[4] ?? null
|
|
171257
|
+
};
|
|
171258
|
+
}
|
|
171259
|
+
function isSeries(version, series) {
|
|
171260
|
+
const [major, minor] = series.split(".").map((part) => Number(part));
|
|
171261
|
+
return version.major === major && version.minor === minor;
|
|
171262
|
+
}
|
|
171263
|
+
function isStable(version) {
|
|
171264
|
+
return version.prerelease === null;
|
|
171265
|
+
}
|
|
171266
|
+
/** True only for stable versions inside the accepted range (current or supported non-current). */
|
|
171267
|
+
function isAdmittedVersion(version) {
|
|
171268
|
+
if (!version || !isStable(version)) return false;
|
|
171269
|
+
return isSeries(version, "1.9") || isSupportedNonCurrentSeries(version);
|
|
171270
|
+
}
|
|
171271
|
+
function isSupportedNonCurrentSeries(version) {
|
|
171272
|
+
return OPENSPEC_CLI_SUPPORTED_SERIES.filter((series) => series !== "1.9").some((series) => isSeries(version, series));
|
|
171273
|
+
}
|
|
171274
|
+
//#endregion
|
|
171275
|
+
//#region src/components/archived-validation-evidence.tsx
|
|
171276
|
+
/**
|
|
171277
|
+
* Orthogonal intents (created 2026-08-15 Asia/Shanghai):
|
|
171278
|
+
* 1. Present OpenSpec 1.9 `validate --archived --json` as typed CLI evidence.
|
|
171279
|
+
* 2. Preserve item issues, totals, root, and exit/failure evidence without repair actions.
|
|
171280
|
+
* 3. Identify the evidence as unavailable in static snapshots instead of fabricating it.
|
|
171281
|
+
* 4. Derive the capability from the detected admitted CLI and hide the action on 1.8.
|
|
171282
|
+
* 5. Validate report payloads with the Core contract schema, never shallow shape guards.
|
|
171283
|
+
*
|
|
171284
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
171285
|
+
*/
|
|
171286
|
+
function parseValidationReport(value) {
|
|
171287
|
+
const parsed = CliValidateReportSchema.safeParse(value);
|
|
171288
|
+
if (parsed.success) return {
|
|
171289
|
+
report: parsed.data,
|
|
171290
|
+
schemaIssues: []
|
|
171291
|
+
};
|
|
171292
|
+
return {
|
|
171293
|
+
report: null,
|
|
171294
|
+
schemaIssues: parsed.error.issues.map((issue) => `${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`)
|
|
171295
|
+
};
|
|
171296
|
+
}
|
|
171297
|
+
function IssueList({ issues }) {
|
|
171298
|
+
if (issues.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
171299
|
+
className: "text-muted-foreground",
|
|
171300
|
+
children: "No CLI issue reported."
|
|
171301
|
+
});
|
|
171302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
171303
|
+
className: "text-muted-foreground space-y-0.5",
|
|
171304
|
+
children: issues.map((issue, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
|
|
171305
|
+
className: "break-words",
|
|
171306
|
+
children: [
|
|
171307
|
+
issue.level,
|
|
171308
|
+
" · ",
|
|
171309
|
+
issue.path,
|
|
171310
|
+
" · ",
|
|
171311
|
+
issue.message
|
|
171312
|
+
]
|
|
171313
|
+
}, index))
|
|
171314
|
+
});
|
|
171315
|
+
}
|
|
171316
|
+
function RunButton({ pending, label, onRun }) {
|
|
171317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
171318
|
+
type: "button",
|
|
171319
|
+
onClick: onRun,
|
|
171320
|
+
disabled: pending,
|
|
171321
|
+
"aria-busy": pending || void 0,
|
|
171322
|
+
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",
|
|
171323
|
+
children: [pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
|
|
171324
|
+
className: "h-3.5 w-3.5 animate-spin",
|
|
171325
|
+
"aria-hidden": true
|
|
171326
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCw, {
|
|
171327
|
+
className: "h-3.5 w-3.5",
|
|
171328
|
+
"aria-hidden": true
|
|
171329
|
+
}), label]
|
|
171330
|
+
});
|
|
171331
|
+
}
|
|
171332
|
+
/** On-demand, read-only archived-task validation evidence for the Change Evidence tab. */
|
|
171333
|
+
function ArchivedValidationEvidence() {
|
|
171334
|
+
const [report, setReport] = (0, import_react.useState)(null);
|
|
171335
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
171336
|
+
const [pending, setPending] = (0, import_react.useState)(false);
|
|
171337
|
+
const cli = useRootActionState().context?.cli;
|
|
171338
|
+
const capabilities = deriveOpenSpecCliCapabilities(cli?.available ? parseOpenSpecCliVersion(cli.version) : null);
|
|
171339
|
+
if (isStaticMode()) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171340
|
+
title: "Archived validation",
|
|
171341
|
+
summary: "Unavailable in static snapshot",
|
|
171342
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
171343
|
+
className: "text-muted-foreground",
|
|
171344
|
+
children: "Archived-task validation is live CLI evidence and is not captured in this static snapshot."
|
|
171345
|
+
})
|
|
171346
|
+
});
|
|
171347
|
+
if (cli?.available === true && !capabilities.archivedValidation) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171348
|
+
title: "Archived validation",
|
|
171349
|
+
summary: "Unavailable on this CLI line",
|
|
171350
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
171351
|
+
className: "text-muted-foreground",
|
|
171352
|
+
children: [
|
|
171353
|
+
"Archived-task validation requires the OpenSpec 1.9 line",
|
|
171354
|
+
cli.version ? ` (detected ${cli.version.trim()})` : "",
|
|
171355
|
+
". This session's CLI does not declare the capability, so no command is offered."
|
|
171356
|
+
]
|
|
171357
|
+
})
|
|
171358
|
+
});
|
|
171359
|
+
const run = async () => {
|
|
171360
|
+
setPending(true);
|
|
171361
|
+
setError(null);
|
|
171362
|
+
setReport(null);
|
|
171363
|
+
try {
|
|
171364
|
+
const result = await trpcClient.cli.validate.mutate({ kind: "archived" });
|
|
171365
|
+
const transport = CliCommandTransportSchema.safeParse(result);
|
|
171366
|
+
if (transport.success) setReport({
|
|
171367
|
+
...transport.data,
|
|
171368
|
+
data: transport.data.data ?? null,
|
|
171369
|
+
payload: transport.data.payload ?? null
|
|
171370
|
+
});
|
|
171371
|
+
else setError("The archived validation transport returned an unrecognized result shape.");
|
|
171372
|
+
} catch (cause) {
|
|
171373
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
171374
|
+
} finally {
|
|
171375
|
+
setPending(false);
|
|
171376
|
+
}
|
|
171377
|
+
};
|
|
171378
|
+
if (!report && !error) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171379
|
+
title: "Archived validation",
|
|
171380
|
+
summary: "OpenSpec 1.9 archived-task validation",
|
|
171381
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171382
|
+
className: "space-y-2",
|
|
171383
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
171384
|
+
className: "text-muted-foreground",
|
|
171385
|
+
children: "Run the official CLI's archived-task validation and keep its typed report as evidence. OpenSpecUI never repairs or archives from here."
|
|
171386
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
|
|
171387
|
+
pending,
|
|
171388
|
+
label: "Validate archived tasks",
|
|
171389
|
+
onRun: () => void run()
|
|
171390
|
+
})]
|
|
171391
|
+
})
|
|
171392
|
+
});
|
|
171393
|
+
const parsed = report ? parseValidationReport(report.data) : {
|
|
171394
|
+
report: null,
|
|
171395
|
+
schemaIssues: []
|
|
171396
|
+
};
|
|
171397
|
+
const validationReport = parsed.report;
|
|
171398
|
+
if (error || !validationReport) {
|
|
171399
|
+
const schemaDiagnostic = parsed.schemaIssues.length > 0 ? parsed.schemaIssues.join("; ") : null;
|
|
171400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171401
|
+
title: "Archived validation",
|
|
171402
|
+
summary: "CLI failure evidence",
|
|
171403
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171404
|
+
className: "space-y-2",
|
|
171405
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171406
|
+
className: "text-destructive flex items-start gap-2 break-words",
|
|
171407
|
+
role: "alert",
|
|
171408
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
171409
|
+
className: "mt-0.5 h-3.5 w-3.5 shrink-0",
|
|
171410
|
+
"aria-hidden": true
|
|
171411
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171412
|
+
className: "min-w-0 break-all",
|
|
171413
|
+
children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The archived validation command failed."
|
|
171414
|
+
})]
|
|
171415
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
|
|
171416
|
+
pending,
|
|
171417
|
+
label: "Rerun",
|
|
171418
|
+
onRun: () => void run()
|
|
171419
|
+
})]
|
|
171420
|
+
})
|
|
171421
|
+
});
|
|
171422
|
+
}
|
|
171423
|
+
const validation = validationReport;
|
|
171424
|
+
const failed = validation.summary.totals.failed;
|
|
171425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171426
|
+
title: "Archived validation",
|
|
171427
|
+
summary: `${validation.summary.totals.passed} passed · ${failed} failed`,
|
|
171428
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171429
|
+
className: "space-y-3",
|
|
171430
|
+
children: [
|
|
171431
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
|
|
171432
|
+
className: "@[32rem]:grid-cols-[auto_minmax(0,1fr)] grid min-w-0 gap-x-3 gap-y-1",
|
|
171433
|
+
children: [
|
|
171434
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
171435
|
+
className: "text-muted-foreground",
|
|
171436
|
+
children: "Root"
|
|
171437
|
+
}),
|
|
171438
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
|
|
171439
|
+
className: "min-w-0 break-all font-mono",
|
|
171440
|
+
children: validation.root.path
|
|
171441
|
+
}),
|
|
171442
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
171443
|
+
className: "text-muted-foreground",
|
|
171444
|
+
children: "Exit"
|
|
171445
|
+
}),
|
|
171446
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: report?.exitCode ?? "unknown" }),
|
|
171447
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
171448
|
+
className: "text-muted-foreground",
|
|
171449
|
+
children: "Totals"
|
|
171450
|
+
}),
|
|
171451
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dd", { children: [
|
|
171452
|
+
validation.summary.totals.passed,
|
|
171453
|
+
" passed · ",
|
|
171454
|
+
failed,
|
|
171455
|
+
" failed ·",
|
|
171456
|
+
" ",
|
|
171457
|
+
validation.summary.totals.items,
|
|
171458
|
+
" archived changes"
|
|
171459
|
+
] })
|
|
171460
|
+
]
|
|
171461
|
+
}),
|
|
171462
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171463
|
+
className: "space-y-2",
|
|
171464
|
+
children: validation.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171465
|
+
className: "border-border/60 rounded border p-2",
|
|
171466
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171467
|
+
className: "flex min-w-0 items-center gap-2",
|
|
171468
|
+
children: [item.valid ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleCheck, {
|
|
171469
|
+
className: "h-3.5 w-3.5 shrink-0 text-emerald-600",
|
|
171470
|
+
"aria-hidden": true
|
|
171471
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
171472
|
+
className: "h-3.5 w-3.5 shrink-0 text-amber-600",
|
|
171473
|
+
"aria-hidden": true
|
|
171474
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171475
|
+
className: "min-w-0 break-all font-mono text-[11px]",
|
|
171476
|
+
children: item.id
|
|
171477
|
+
})]
|
|
171478
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171479
|
+
className: "mt-1",
|
|
171480
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IssueList, { issues: item.issues })
|
|
171481
|
+
})]
|
|
171482
|
+
}, item.id))
|
|
171483
|
+
}),
|
|
171484
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
|
|
171485
|
+
pending,
|
|
171486
|
+
label: "Rerun",
|
|
171487
|
+
onRun: () => void run()
|
|
171488
|
+
})
|
|
171489
|
+
]
|
|
171490
|
+
})
|
|
171491
|
+
});
|
|
171492
|
+
}
|
|
171090
171493
|
//#endregion
|
|
171091
171494
|
//#region src/components/change-context-summary.tsx
|
|
171092
171495
|
/**
|
|
171093
|
-
* Orthogonal intents (
|
|
171496
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
171094
171497
|
* 1. Project compact Schema, artifact progress, Root, Store, and Reference subtitle badges.
|
|
171095
|
-
* 2.
|
|
171096
|
-
* 3.
|
|
171498
|
+
* 2. Carry the Apply instruction count as one subtitle badge — the progress authority.
|
|
171499
|
+
* 3. Preserve current, retained, unavailable, and static authority distinctions.
|
|
171500
|
+
* 4. Keep Reference failures directly visible without owning subscriptions or mutations.
|
|
171097
171501
|
*
|
|
171098
171502
|
* Original request (2026-08-03): keep only necessary Change evidence in the default decision plane.
|
|
171099
171503
|
* Owner correction (2026-08-03): unify Change scan Tooltips in the subtitle and keep failures below the Header.
|
|
171504
|
+
* Original request (2026-08-15): Owner walkthrough: merge Apply progress into the subtitle badge row.
|
|
171505
|
+
* Original request (2026-08-15): 刷新/解析中的 lifecycle 锁收敛为副标题行内的 shiny 徽章 + Tooltip。
|
|
171100
171506
|
*/
|
|
171101
171507
|
function summarizeReferences(references) {
|
|
171102
171508
|
return references.reduce((counts, reference) => {
|
|
@@ -171117,7 +171523,7 @@ function referenceErrorLabels(references) {
|
|
|
171117
171523
|
});
|
|
171118
171524
|
}
|
|
171119
171525
|
/** Compact source-attributed facts that share the Change Header subtitle. */
|
|
171120
|
-
function ChangeContextSummary({ status, referenceEvidence }) {
|
|
171526
|
+
function ChangeContextSummary({ status, referenceEvidence, applyInstructionProgress, statusRefreshing = null, rootChecking = null }) {
|
|
171121
171527
|
const provenance = status.provenance;
|
|
171122
171528
|
const references = referenceEvidence.state === "unavailable" ? null : referenceEvidence.references;
|
|
171123
171529
|
const referenceCounts = references ? summarizeReferences(references) : null;
|
|
@@ -171143,6 +171549,7 @@ function ChangeContextSummary({ status, referenceEvidence }) {
|
|
|
171143
171549
|
" artifacts"
|
|
171144
171550
|
]
|
|
171145
171551
|
}),
|
|
171552
|
+
applyInstructionProgress ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressBadge, { applyInstructionProgress }) : null,
|
|
171146
171553
|
provenance.kind === "static" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InformationBadge, {
|
|
171147
171554
|
ariaLabel: "Static Change context has no live backend provenance",
|
|
171148
171555
|
tooltip: "CLI Change context is unavailable in this static snapshot.",
|
|
@@ -171175,7 +171582,15 @@ function ChangeContextSummary({ status, referenceEvidence }) {
|
|
|
171175
171582
|
ariaLabel: "Reference evidence unavailable",
|
|
171176
171583
|
tooltip: referenceEvidence.state === "unavailable" && referenceEvidence.reason === "static" ? "Reference evidence is not published in this static snapshot." : "Reference evidence is unavailable until Root Context is observed.",
|
|
171177
171584
|
children: "References unavailable"
|
|
171178
|
-
})
|
|
171585
|
+
}),
|
|
171586
|
+
rootChecking ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShinyStatusBadge, {
|
|
171587
|
+
label: rootChecking.label,
|
|
171588
|
+
message: rootChecking.message
|
|
171589
|
+
}) : null,
|
|
171590
|
+
statusRefreshing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShinyStatusBadge, {
|
|
171591
|
+
label: statusRefreshing.label,
|
|
171592
|
+
message: statusRefreshing.message
|
|
171593
|
+
}) : null
|
|
171179
171594
|
]
|
|
171180
171595
|
});
|
|
171181
171596
|
}
|
|
@@ -171656,29 +172071,39 @@ function OperationInputsDialogAction({ title, context, operationGuidance }) {
|
|
|
171656
172071
|
//#endregion
|
|
171657
172072
|
//#region src/components/root-action-notice.tsx
|
|
171658
172073
|
/**
|
|
171659
|
-
* Orthogonal intents (updated 2026-
|
|
171660
|
-
* 1. Render root-action
|
|
171661
|
-
* 2.
|
|
171662
|
-
* 3. Keep
|
|
172074
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
172075
|
+
* 1. Render root-action blocked states with CLI-owned evidence as direct alerts.
|
|
172076
|
+
* 2. Render root-action checking states as one inline shiny badge for header/status rows.
|
|
172077
|
+
* 3. Keep blocker meaning direct while placing verbose CLI evidence in shared indirect space.
|
|
172078
|
+
* 4. Keep the notice reusable across OPSX compose and direct-action surfaces.
|
|
171663
172079
|
*
|
|
171664
172080
|
* Original request (2026-07-15): "Show CLI-owned failure evidence when root selection fails."
|
|
171665
172081
|
* Original request (2026-07-28): supporting 6.x evidence should use Badge + Tooltip or Accordion.
|
|
172082
|
+
* Original request (2026-08-15): 刷新/解析中的块级 Alert 改为 Animated Shiny Text + Tooltip。
|
|
171666
172083
|
*/
|
|
171667
|
-
/**
|
|
172084
|
+
/**
|
|
172085
|
+
* Normal lifecycle (resolving/refreshing) as visual language — one inline shiny badge
|
|
172086
|
+
* with no layout block. The complete lock reason stays available on hover/keyboard
|
|
172087
|
+
* focus via the Tooltip and the hidden polite live region.
|
|
172088
|
+
*/
|
|
172089
|
+
function RootCheckingBadge({ state }) {
|
|
172090
|
+
if (state.status !== "checking") return null;
|
|
172091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShinyStatusBadge, {
|
|
172092
|
+
label: state.title,
|
|
172093
|
+
message: state.message
|
|
172094
|
+
});
|
|
172095
|
+
}
|
|
172096
|
+
/** Render objective failure evidence that locks root-dependent actions; null otherwise. */
|
|
171668
172097
|
function RootActionNotice({ state }) {
|
|
171669
|
-
if (state.status
|
|
171670
|
-
const checking = state.status === "checking";
|
|
172098
|
+
if (state.status !== "blocked") return null;
|
|
171671
172099
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171672
|
-
role:
|
|
171673
|
-
"aria-live":
|
|
171674
|
-
className:
|
|
172100
|
+
role: "alert",
|
|
172101
|
+
"aria-live": "assertive",
|
|
172102
|
+
className: "border-destructive/40 bg-destructive/10 text-destructive rounded-md border p-3 text-sm",
|
|
171675
172103
|
children: [
|
|
171676
172104
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171677
172105
|
className: "flex items-center gap-2 font-medium",
|
|
171678
|
-
children: [
|
|
171679
|
-
className: "h-4 w-4 animate-spin",
|
|
171680
|
-
"aria-hidden": true
|
|
171681
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleAlert, {
|
|
172106
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleAlert, {
|
|
171682
172107
|
className: "h-4 w-4",
|
|
171683
172108
|
"aria-hidden": true
|
|
171684
172109
|
}), state.title]
|
|
@@ -171718,6 +172143,7 @@ function RootActionNotice({ state }) {
|
|
|
171718
172143
|
* Original request (2026-08-01): preserve OpenSpec 1.7 Apply operation inputs end to end.
|
|
171719
172144
|
* Original request (2026-08-03): move complete Change evidence into a dedicated tab page.
|
|
171720
172145
|
* Owner correction (2026-08-03): move Actions inline with the title, unify subtitle badges, and localize unavailable Tooltips.
|
|
172146
|
+
* Original request (2026-08-15): 刷新/解析中状态收敛为副标题行内的 shiny 徽章,不再占据 statusRegion 块。
|
|
171721
172147
|
*/
|
|
171722
172148
|
function ChangeView() {
|
|
171723
172149
|
const { changeId } = useParams({ from: "/changes/$changeId" });
|
|
@@ -171791,13 +172217,16 @@ function ChangeView() {
|
|
|
171791
172217
|
id: "evidence",
|
|
171792
172218
|
label: "Evidence",
|
|
171793
172219
|
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileSearch, { className: "h-4 w-4" }),
|
|
171794
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
171795
|
-
|
|
171796
|
-
|
|
172220
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
172221
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col",
|
|
172222
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeEvidencePanel, {
|
|
172223
|
+
status,
|
|
172224
|
+
referenceEvidence
|
|
172225
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArchivedValidationEvidence, {})]
|
|
171797
172226
|
})
|
|
171798
172227
|
}] : [], [referenceEvidence, status]);
|
|
171799
172228
|
const hasReferenceFailures = referenceEvidence.state !== "unavailable" && referenceEvidence.references.some((reference) => reference.status.some((diagnostic) => diagnostic.severity === "error"));
|
|
171800
|
-
const hasDirectStatus =
|
|
172229
|
+
const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence);
|
|
171801
172230
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OpsxEntityDetailView, {
|
|
171802
172231
|
entityId: changeId,
|
|
171803
172232
|
sharedFamily: "changes",
|
|
@@ -171807,7 +172236,16 @@ function ChangeView() {
|
|
|
171807
172236
|
title: status?.changeName,
|
|
171808
172237
|
subtitle: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeContextSummary, {
|
|
171809
172238
|
status,
|
|
171810
|
-
referenceEvidence
|
|
172239
|
+
referenceEvidence,
|
|
172240
|
+
applyInstructionProgress: applyInstructions?.applyInstructionProgress ?? null,
|
|
172241
|
+
statusRefreshing: statusCurrent ? null : {
|
|
172242
|
+
label: "Status refreshing",
|
|
172243
|
+
message: statusAuthorityMessage ?? ""
|
|
172244
|
+
},
|
|
172245
|
+
rootChecking: rootAction.status === "checking" ? {
|
|
172246
|
+
label: rootAction.title,
|
|
172247
|
+
message: rootAction.message
|
|
172248
|
+
} : null
|
|
171811
172249
|
}) : void 0,
|
|
171812
172250
|
headerActions: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeCommandBar, {
|
|
171813
172251
|
status,
|
|
@@ -171845,15 +172283,6 @@ function ChangeView() {
|
|
|
171845
172283
|
statusRegion: status && hasDirectStatus ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171846
172284
|
className: "flex min-w-0 flex-col gap-2",
|
|
171847
172285
|
children: [
|
|
171848
|
-
!statusCurrent && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171849
|
-
role: "status",
|
|
171850
|
-
"aria-live": "polite",
|
|
171851
|
-
className: "border-border bg-muted/30 text-muted-foreground flex items-center gap-2 rounded-md border px-3 py-2 text-xs",
|
|
171852
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCw, {
|
|
171853
|
-
className: "h-3.5 w-3.5 shrink-0",
|
|
171854
|
-
"aria-hidden": true
|
|
171855
|
-
}), statusAuthorityMessage]
|
|
171856
|
-
}) : null,
|
|
171857
172286
|
error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171858
172287
|
role: "alert",
|
|
171859
172288
|
"aria-live": "assertive",
|
|
@@ -171912,7 +172341,7 @@ var CONFIG_GUIDE_STAGE_META = {
|
|
|
171912
172341
|
//#region src/components/config/config-guide.tsx
|
|
171913
172342
|
var ConfigGuideContext = (0, import_react.createContext)(null);
|
|
171914
172343
|
(0, import_react.lazy)(async () => {
|
|
171915
|
-
return { default: (await import("./config-guide-presentation-
|
|
172344
|
+
return { default: (await import("./config-guide-presentation-r59qmEkS.js")).ConfigGuidePresentationLayer };
|
|
171916
172345
|
});
|
|
171917
172346
|
/** Access the root-owned adaptive Guide runtime. */
|
|
171918
172347
|
function useConfigGuide() {
|
|
@@ -173677,6 +174106,7 @@ function ActiveRootConfigSection({ isStatic }) {
|
|
|
173677
174106
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173678
174107
|
className: "flex flex-wrap items-center justify-end gap-2",
|
|
173679
174108
|
children: [
|
|
174109
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootCheckingBadge, { state: rootAction }),
|
|
173680
174110
|
(config.exists || isEditing) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
173681
174111
|
role: "tablist",
|
|
173682
174112
|
"aria-label": "Active Root editor mode",
|
|
@@ -174670,19 +175100,23 @@ function ConfigSchemaWorkspace({ onNavigate, schemaId }) {
|
|
|
174670
175100
|
]
|
|
174671
175101
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
174672
175102
|
className: "flex items-center gap-2",
|
|
174673
|
-
children: [
|
|
174674
|
-
|
|
174675
|
-
|
|
174676
|
-
|
|
174677
|
-
|
|
174678
|
-
|
|
174679
|
-
|
|
174680
|
-
|
|
174681
|
-
|
|
174682
|
-
|
|
174683
|
-
|
|
174684
|
-
|
|
174685
|
-
|
|
175103
|
+
children: [
|
|
175104
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootCheckingBadge, { state: rootAction }),
|
|
175105
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
175106
|
+
type: "button",
|
|
175107
|
+
onClick: handleAddSchema,
|
|
175108
|
+
disabled: !schemaCanEdit || createSchemaMutation.isPending,
|
|
175109
|
+
className: "border-border hover:bg-muted inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50",
|
|
175110
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Plus, { className: "h-3.5 w-3.5" }), "Add"]
|
|
175111
|
+
}),
|
|
175112
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
175113
|
+
type: "button",
|
|
175114
|
+
onClick: handleDeleteSchema,
|
|
175115
|
+
disabled: !schemaCanEdit || deleteSchemaMutation.isPending,
|
|
175116
|
+
className: "border-border hover:bg-muted inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50",
|
|
175117
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trash2, { className: "h-3.5 w-3.5" }), "Delete"]
|
|
175118
|
+
})
|
|
175119
|
+
]
|
|
174686
175120
|
})]
|
|
174687
175121
|
}),
|
|
174688
175122
|
!isStatic && rootAction.disabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootActionNotice, { state: rootAction }) : null,
|
|
@@ -176928,14 +177362,15 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
|
|
|
176928
177362
|
//#endregion
|
|
176929
177363
|
//#region src/routes/dashboard.tsx
|
|
176930
177364
|
/**
|
|
176931
|
-
* Orthogonal intents (updated 2026-
|
|
177365
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
176932
177366
|
* 1. Render independent Dashboard projections inside stable region-owned Pending geometry.
|
|
176933
177367
|
* 2. Keep Dashboard-owned readonly Code Git refresh bound to rendered provenance and separate from Planning-root mutation authority.
|
|
176934
177368
|
* 3. Curate Code Git activity while preserving binding-token detail handoff provenance.
|
|
176935
|
-
* 4.
|
|
176936
|
-
* 5.
|
|
177369
|
+
* 4. Show only objective planning and artifact facts, never tracked task completion.
|
|
177370
|
+
* 5. Retain stable regional snapshots beside their own loading, updating, and error evidence.
|
|
176937
177371
|
*
|
|
176938
177372
|
* Original request (2026-07-16): "接下来,你来接手后续工作"
|
|
177373
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
176939
177374
|
* Derived requirement (2026-07-19): Checkpoint 6.11 preserves Git handoff and action provenance.
|
|
176940
177375
|
* Original request (2026-07-23): "现在页面数据的加载数据非常慢(比如dashboard页面、changes页面都要等待非常久,页面刷新后,似乎后台没有缓存一样,也要加载很久。"
|
|
176941
177376
|
* Original request (2026-07-27): "统一修复所有类似的问题(我们也没不多,各个页面都检查一下,特别是app 那边新增的页面)"
|
|
@@ -176949,6 +177384,7 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
|
|
|
176949
177384
|
* Original request (2026-07-31): "Code Git Snapshot 的 Other Worktrees 默认隐藏 (detached)。然后commitList这里默认显示5个就好"
|
|
176950
177385
|
* Original request (2026-07-31): "检查目前的这个 Code Git Snapshot,它非常慢,有时候甚至要十几秒"
|
|
176951
177386
|
* Owner correction (2026-07-31): Hidden documents pause the timer; visibility resumes the remaining delay or refreshes once when the absolute deadline elapsed.
|
|
177387
|
+
|
|
176952
177388
|
*/
|
|
176953
177389
|
var GIT_AUTO_REFRESH_OPTIONS = [
|
|
176954
177390
|
{
|
|
@@ -177405,8 +177841,6 @@ function Dashboard() {
|
|
|
177405
177841
|
children: [
|
|
177406
177842
|
summaryPending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeListSkeleton, { count: 3 }) : null,
|
|
177407
177843
|
!summaryPending && activeChanges.map((change) => {
|
|
177408
|
-
const progress = change.trackedTaskProgress;
|
|
177409
|
-
const taskPercent = progress.total > 0 ? Math.round(progress.completed / progress.total * 100) : 0;
|
|
177410
177844
|
const status = activeStatuses.find((item) => item.changeName === change.id);
|
|
177411
177845
|
const doneArtifacts = status?.artifacts.filter((artifact) => artifact.status === "done").length ?? 0;
|
|
177412
177846
|
const totalArtifacts = status?.artifacts.length ?? 0;
|
|
@@ -177414,11 +177848,10 @@ function Dashboard() {
|
|
|
177414
177848
|
const trackedArtifactStatus = trackedArtifactId && status ? status.artifacts.find((artifact) => artifact.id === trackedArtifactId)?.status ?? inferTrackedArtifactStatus(status.artifacts.map((artifact) => artifact.status)) : inferTrackedArtifactStatus(status?.artifacts.map((artifact) => artifact.status) ?? []);
|
|
177415
177849
|
const phase = classifyChangeWorkflowPhase({
|
|
177416
177850
|
hasStatus: Boolean(status),
|
|
177417
|
-
|
|
177418
|
-
trackedTaskPhase: progress.phase,
|
|
177851
|
+
isPlanningComplete: status?.isPlanningComplete ?? false,
|
|
177419
177852
|
trackedArtifactStatus
|
|
177420
177853
|
});
|
|
177421
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
177854
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VTLink, {
|
|
177422
177855
|
to: "/changes/$changeId",
|
|
177423
177856
|
params: { changeId: change.id },
|
|
177424
177857
|
state: (prev) => ({
|
|
@@ -177439,71 +177872,24 @@ function Dashboard() {
|
|
|
177439
177872
|
entityId: change.id
|
|
177440
177873
|
}, "container"),
|
|
177441
177874
|
className: "hover:bg-muted/50 block min-w-0 px-4 py-3",
|
|
177442
|
-
children:
|
|
177443
|
-
|
|
177444
|
-
|
|
177445
|
-
|
|
177446
|
-
|
|
177447
|
-
|
|
177448
|
-
|
|
177449
|
-
|
|
177450
|
-
|
|
177451
|
-
|
|
177452
|
-
|
|
177453
|
-
|
|
177454
|
-
|
|
177455
|
-
|
|
177456
|
-
|
|
177457
|
-
|
|
177458
|
-
|
|
177459
|
-
|
|
177460
|
-
children: [
|
|
177461
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
177462
|
-
tone: "custom",
|
|
177463
|
-
size: "sm",
|
|
177464
|
-
shape: "box",
|
|
177465
|
-
className: `border ${phase.toneClass}`,
|
|
177466
|
-
children: phase.label
|
|
177467
|
-
}),
|
|
177468
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177469
|
-
className: "font-medium",
|
|
177470
|
-
children: [
|
|
177471
|
-
progress.completed,
|
|
177472
|
-
"/",
|
|
177473
|
-
progress.total
|
|
177474
|
-
]
|
|
177475
|
-
}),
|
|
177476
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
177477
|
-
className: "text-muted-foreground text-xs",
|
|
177478
|
-
children: "tasks"
|
|
177479
|
-
})
|
|
177480
|
-
]
|
|
177481
|
-
})]
|
|
177482
|
-
}),
|
|
177483
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
177484
|
-
className: "bg-muted h-1.5 rounded-full",
|
|
177485
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
177486
|
-
className: "bg-primary h-full rounded-full transition-all",
|
|
177487
|
-
style: { width: `${taskPercent}%` }
|
|
177488
|
-
})
|
|
177489
|
-
}),
|
|
177490
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177491
|
-
className: "text-muted-foreground mt-2 flex min-w-0 flex-wrap items-center justify-between gap-2 text-xs",
|
|
177492
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
177493
|
-
className: "shrink-0",
|
|
177494
|
-
children: [taskPercent, "% task completion"]
|
|
177495
|
-
}), status ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
177496
|
-
className: "min-w-0 truncate text-right",
|
|
177497
|
-
children: [
|
|
177498
|
-
doneArtifacts,
|
|
177499
|
-
"/",
|
|
177500
|
-
totalArtifacts,
|
|
177501
|
-
" artifacts · ",
|
|
177502
|
-
status.schemaName
|
|
177503
|
-
]
|
|
177504
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Artifacts status unavailable" })]
|
|
177505
|
-
})
|
|
177506
|
-
]
|
|
177875
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177876
|
+
className: "flex min-w-0 items-center gap-3",
|
|
177877
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
|
|
177878
|
+
changeId: change.id,
|
|
177879
|
+
name: change.name,
|
|
177880
|
+
phase,
|
|
177881
|
+
updatedAt: change.updatedAt,
|
|
177882
|
+
formatTime: formatRelativeTime,
|
|
177883
|
+
className: "min-w-0 flex-1",
|
|
177884
|
+
subtitle: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
177885
|
+
doneArtifacts,
|
|
177886
|
+
"/",
|
|
177887
|
+
totalArtifacts,
|
|
177888
|
+
" artifacts · ",
|
|
177889
|
+
status.schemaName
|
|
177890
|
+
] }) : "Artifacts status unavailable"
|
|
177891
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRowChevron, {})]
|
|
177892
|
+
})
|
|
177507
177893
|
}, change.id);
|
|
177508
177894
|
}),
|
|
177509
177895
|
!summaryPending && !hasChanges && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|