@openspecui/web 7.0.1 → 9.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-BvtmL_DV.css +1 -0
- package/dist/assets/{App-CdCpY5Oi.js → App-pfObbe6n.js} +158 -157
- package/dist/assets/{main-BJ6w67mJ.js → main-Bc_Hy41u.js} +2 -2
- package/dist/assets/{trpc-DkR_dtsV.js → trpc--JMUaLps.js} +1 -1
- package/dist/index.html +1 -1
- package/dist-ssg/client/.vite/ssr-manifest.json +99 -29
- package/dist-ssg/client/assets/CanvasRenderer-BFbMT1Ul.js +1 -0
- package/dist-ssg/client/assets/WebGLRenderer-C7eR_UnH.js +1 -0
- package/dist-ssg/client/assets/WebGPURenderer-BTQYx5S7.js +1 -0
- package/dist-ssg/client/assets/browserAll-C88S5YfV.js +1 -0
- package/dist-ssg/client/assets/{config-guide-presentation-m4L_6Aw1.js → config-guide-presentation-BOR0ydhm.js} +1 -1
- package/dist-ssg/client/assets/{dist-BINRJsSD.js → dist-0yxWvQWL.js} +1 -1
- package/dist-ssg/client/assets/dist-4fNILwqh.js +1 -0
- package/dist-ssg/client/assets/{dist-DaBfRE0W.js → dist-BXnglWxe.js} +1 -1
- package/dist-ssg/client/assets/{dist-Dy8gt0Ib.js → dist-CcTAgsaD.js} +1 -1
- package/dist-ssg/client/assets/dist-Cd3-dF0O.js +1 -0
- package/dist-ssg/client/assets/{dist-D_dL7IEq.js → dist-CqBkec9X.js} +1 -1
- package/dist-ssg/client/assets/{dist-BhVT4aPf.js → dist-Cqsy4GXU.js} +1 -1
- package/dist-ssg/client/assets/{dist-Bg_7PXKP.js → dist-DFrBPW6S.js} +1 -1
- package/dist-ssg/client/assets/{dist-D9y725wE.js → dist-DR4ycVu1.js} +1 -1
- package/dist-ssg/client/assets/{dist-JPSLeMZt.js → dist-DclbMTMt.js} +1 -1
- package/dist-ssg/client/assets/dist-DxTZTTY6.js +1 -0
- package/dist-ssg/client/assets/{dist-CQkg2GXo.js → dist-biv4iN0V.js} +1 -1
- package/dist-ssg/client/assets/{ghostty-web-BfmV5WPs.js → ghostty-web-D2QuMH_Q.js} +1 -1
- package/dist-ssg/client/assets/index-CrVhSCmS.css +1 -0
- package/dist-ssg/client/assets/index.ssg-JS2ceq7d.js +1649 -0
- package/dist-ssg/client/assets/{init-ExESwXkv.js → init-CHYK3_IX.js} +1 -1
- package/dist-ssg/client/assets/{trpc-aDW3YZC2.js → trpc-B-w8tA8C.js} +1 -1
- package/dist-ssg/client/assets/webworkerAll-DFRsQGYS.js +1 -0
- package/dist-ssg/client/index.ssg.html +2 -2
- package/dist-ssg/server/assets/CanvasRenderer-Cud3mH2M.js +3 -0
- package/dist-ssg/server/assets/WebGLRenderer-BG7MkvqA.js +3 -0
- package/dist-ssg/server/assets/WebGPURenderer--JR4o1Id.js +3 -0
- package/dist-ssg/server/assets/{browserAll-CbppWmmr.js → browserAll-BNHXRTWn.js} +2 -2
- package/dist-ssg/server/assets/{config-guide-presentation-BysIO8oY.js → config-guide-presentation-CmUNOJoP.js} +1 -1
- package/dist-ssg/server/assets/{dist-DLmT_-xD.js → dist-BTzm9CCH.js} +1 -1
- package/dist-ssg/server/assets/{dist-9eozfPDO.js → dist-BZwNiEjE.js} +1 -1
- package/dist-ssg/server/assets/{dist-BL9BN3bD.js → dist-Bg6kJ4lE.js} +1 -1
- package/dist-ssg/server/assets/{dist-Bxv0KpK2.js → dist-CD_P89TI.js} +1 -1
- package/dist-ssg/server/assets/{dist-C3YYTwOF.js → dist-CSnQ9MUZ.js} +1 -1
- package/dist-ssg/server/assets/{dist-BvJegMAu.js → dist-CkE7XypO.js} +1 -1
- package/dist-ssg/server/assets/dist-CpgxMd46.js +3 -0
- package/dist-ssg/server/assets/{dist-CBWX0qVQ.js → dist-CzfcaAEs.js} +1 -1
- package/dist-ssg/server/assets/{dist-CWgzRN8l.js → dist-TFBLKdTC.js} +1 -1
- package/dist-ssg/server/assets/dist-gfV2B0G7.js +3 -0
- package/dist-ssg/server/assets/{dist-uy4rKjdF.js → dist-tvIcsOn0.js} +1 -1
- package/dist-ssg/server/assets/dist-vPFtDCqy.js +3 -0
- package/dist-ssg/server/assets/{entry-server-C1flMDyD.js → entry-server-C_EGBt5m.js} +768 -253
- package/dist-ssg/server/assets/{init-CzleJ4fV.js → init-Ds70MQGb.js} +1 -1
- package/dist-ssg/server/assets/trpc-DMtttD_4.js +3 -0
- package/dist-ssg/server/assets/webworkerAll-6pG_bTSk.js +4 -0
- package/dist-ssg/server/ssr-entry-manifest.json +25 -25
- package/package.json +4 -4
- package/dist/assets/App-Ddx3wr17.css +0 -1
- package/dist-ssg/client/assets/CanvasRenderer-SxkLA4OO.js +0 -1
- package/dist-ssg/client/assets/WebGLRenderer-BlVqxY1i.js +0 -1
- package/dist-ssg/client/assets/WebGPURenderer-B3sn-S62.js +0 -1
- package/dist-ssg/client/assets/browserAll-Bq1Uo1-9.js +0 -1
- package/dist-ssg/client/assets/dist-Bh5C-oZl.js +0 -1
- package/dist-ssg/client/assets/dist-CzUl1_ZX.js +0 -1
- package/dist-ssg/client/assets/dist-Do7XHNay.js +0 -1
- package/dist-ssg/client/assets/index-Dcu2Vogo.css +0 -1
- package/dist-ssg/client/assets/index.ssg-CTvsWc75.js +0 -1648
- package/dist-ssg/client/assets/webworkerAll-DPGdqK5A.js +0 -1
- package/dist-ssg/server/assets/CanvasRenderer-CwiiSPbH.js +0 -3
- package/dist-ssg/server/assets/WebGLRenderer-DZq9g4pY.js +0 -3
- package/dist-ssg/server/assets/WebGPURenderer-CC9srvlc.js +0 -3
- package/dist-ssg/server/assets/dist-D3UkzXNJ.js +0 -3
- package/dist-ssg/server/assets/dist-X54KSZxt.js +0 -3
- package/dist-ssg/server/assets/dist-qBAal1ou.js +0 -3
- package/dist-ssg/server/assets/trpc-4lRaWiqp.js +0 -3
- package/dist-ssg/server/assets/webworkerAll-Boyd6QDj.js +0 -4
|
@@ -8,9 +8,9 @@ import { a as uniformParsers, c as ensureAttributes, d as localUniformBit, f as
|
|
|
8
8
|
import { $ as keymap, A as indentUnit, At as IterMode, B as Direction, C as foldNodeProp, Ct as Transaction, D as indentNodeProp, Dt as countColumn, E as getIndentation, Et as combineConfig, F as syntaxTree, Ft as Parser, G as drawSelection, H as ViewPlugin, I as Tag$1, It as Tree, K as dropCursor, L as styleTags, Lt as parseMixed, M as matchBrackets, Mt as NodeSet, Nt as NodeType, O as indentOnInput, Ot as findClusterBreak, P as syntaxHighlighting, Pt as NodeWeakMap, Q as hoverTooltip, R as tags$1, S as foldKeymap, St as Text$2, T as getIndentUnit, Tt as codePointSize, U as WidgetType, V as EditorView, W as crosshairCursor, X as highlightActiveLineGutter, Y as highlightActiveLine, Z as highlightSpecialChars, _ as defineLanguageFacet, a as HighlightStyle, at as showPanel, b as foldGutter, bt as StateEffect, c as Language, ct as Annotation, d as ParseContext, dt as CharCategory, et as lineNumbers, f as StreamLanguage, ft as EditorSelection, g as defaultHighlightStyle, gt as Prec, h as continuedIndent, i as LocalTokenGroup, it as runScopeHandlers, j as languageDataProp, jt as NodeProp, k as indentString, kt as fromCodePoint, l as LanguageDescription, lt as ChangeDesc, m as bracketMatchingHandle, mt as Facet, n as ExternalTokenizer, nt as placeholder, o as IndentContext, p as bracketMatching, pt as EditorState, q as getPanel, r as LRParser, rt as rectangularSelection, s as LRLanguage, st as crelt, t as ContextTracker, u as LanguageSupport, ut as ChangeSet, v as delimitedIndent, vt as RangeSetBuilder, w as foldService, wt as codePointAt, x as foldInside, xt as StateField, z as Decoration } from "./dist-5X8O7Rwc.js";
|
|
9
9
|
import { a as tsxLanguage, i as jsxLanguage, n as javascript, o as typescriptLanguage, r as javascriptLanguage } from "./dist-CCduGocE.js";
|
|
10
10
|
import { i as closeBracketsKeymap, n as autocompletion, o as completionKeymap, r as closeBrackets, t as CompletionContext } from "./dist-CxThVo3w.js";
|
|
11
|
+
import { fileURLToPath as urlToPath } from "node:url";
|
|
11
12
|
import minpath from "node:path";
|
|
12
13
|
import minproc from "node:process";
|
|
13
|
-
import { fileURLToPath as urlToPath } from "node:url";
|
|
14
14
|
//#region ../../node_modules/.pnpm/@tanstack+query-core@5.90.10/node_modules/@tanstack/query-core/build/modern/subscribable.js
|
|
15
15
|
var Subscribable = class {
|
|
16
16
|
constructor() {
|
|
@@ -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-DMtttD_4.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-DMtttD_4.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({
|
|
@@ -58360,6 +58440,12 @@ function DesktopSidebar() {
|
|
|
58360
58440
|
}
|
|
58361
58441
|
//#endregion
|
|
58362
58442
|
//#region src/lib/use-server-status.ts
|
|
58443
|
+
function directoryName(projectDir) {
|
|
58444
|
+
const normalized = projectDir.replace(/[\\/]+$/, "");
|
|
58445
|
+
if (!normalized) return projectDir;
|
|
58446
|
+
const segments = normalized.split(/[\\/]+/);
|
|
58447
|
+
return segments[segments.length - 1] || normalized;
|
|
58448
|
+
}
|
|
58363
58449
|
/**
|
|
58364
58450
|
* Hook to monitor server connection status and get project info
|
|
58365
58451
|
*/
|
|
@@ -58431,7 +58517,7 @@ function useServerStatus() {
|
|
|
58431
58517
|
onData: (data) => {
|
|
58432
58518
|
if (!isCurrentGeneration()) return;
|
|
58433
58519
|
const projectDir = data.projectDir;
|
|
58434
|
-
const dirName = projectDir
|
|
58520
|
+
const dirName = directoryName(projectDir);
|
|
58435
58521
|
const connected = wsStateRef.current === "pending";
|
|
58436
58522
|
setStatus((prev) => ({
|
|
58437
58523
|
...prev,
|
|
@@ -71013,7 +71099,7 @@ var browserExt = {
|
|
|
71013
71099
|
},
|
|
71014
71100
|
test: () => true,
|
|
71015
71101
|
load: async () => {
|
|
71016
|
-
await import("./browserAll-
|
|
71102
|
+
await import("./browserAll-BNHXRTWn.js");
|
|
71017
71103
|
}
|
|
71018
71104
|
};
|
|
71019
71105
|
//#endregion
|
|
@@ -71026,7 +71112,7 @@ var webworkerExt = {
|
|
|
71026
71112
|
},
|
|
71027
71113
|
test: () => typeof self !== "undefined" && self.WorkerGlobalScope !== void 0,
|
|
71028
71114
|
load: async () => {
|
|
71029
|
-
await import("./webworkerAll-
|
|
71115
|
+
await import("./webworkerAll-6pG_bTSk.js");
|
|
71030
71116
|
}
|
|
71031
71117
|
};
|
|
71032
71118
|
//#endregion
|
|
@@ -73620,7 +73706,7 @@ async function autoDetectRenderer(options) {
|
|
|
73620
73706
|
for (let i = 0; i < preferredOrder.length; i++) {
|
|
73621
73707
|
const rendererType = preferredOrder[i];
|
|
73622
73708
|
if (rendererType === "webgpu" && await isWebGPUSupported()) {
|
|
73623
|
-
const { WebGPURenderer } = await import("./WebGPURenderer
|
|
73709
|
+
const { WebGPURenderer } = await import("./WebGPURenderer--JR4o1Id.js");
|
|
73624
73710
|
RendererClass = WebGPURenderer;
|
|
73625
73711
|
finalOptions = {
|
|
73626
73712
|
...options,
|
|
@@ -73628,7 +73714,7 @@ async function autoDetectRenderer(options) {
|
|
|
73628
73714
|
};
|
|
73629
73715
|
break;
|
|
73630
73716
|
} else if (rendererType === "webgl" && isWebGLSupported(options.failIfMajorPerformanceCaveat ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat)) {
|
|
73631
|
-
const { WebGLRenderer } = await import("./WebGLRenderer-
|
|
73717
|
+
const { WebGLRenderer } = await import("./WebGLRenderer-BG7MkvqA.js");
|
|
73632
73718
|
RendererClass = WebGLRenderer;
|
|
73633
73719
|
finalOptions = {
|
|
73634
73720
|
...options,
|
|
@@ -73636,7 +73722,7 @@ async function autoDetectRenderer(options) {
|
|
|
73636
73722
|
};
|
|
73637
73723
|
break;
|
|
73638
73724
|
} else if (rendererType === "canvas") {
|
|
73639
|
-
const { CanvasRenderer } = await import("./CanvasRenderer-
|
|
73725
|
+
const { CanvasRenderer } = await import("./CanvasRenderer-Cud3mH2M.js");
|
|
73640
73726
|
RendererClass = CanvasRenderer;
|
|
73641
73727
|
finalOptions = {
|
|
73642
73728
|
...options,
|
|
@@ -93155,6 +93241,15 @@ function buildShortcutPages(platform) {
|
|
|
93155
93241
|
}
|
|
93156
93242
|
//#endregion
|
|
93157
93243
|
//#region ../xterm-input-panel/src/shortcut-tab.ts
|
|
93244
|
+
/**
|
|
93245
|
+
* Orthogonal intents (updated 2026-08-06 Asia/Shanghai):
|
|
93246
|
+
* 1. Render platform-aware shortcut pages through Pixi.
|
|
93247
|
+
* 2. Own shortcut page selection and command dispatch.
|
|
93248
|
+
* 3. Keep shortcut layout, resize, and theme projection synchronized.
|
|
93249
|
+
* 4. Retire late Pixi initialization after disconnect so detached render loops cannot survive.
|
|
93250
|
+
*
|
|
93251
|
+
* Original request (2026-08-04): "Make pnpm openspecui start and equivalent package scripts work on Windows, then handle similar portability failures."
|
|
93252
|
+
*/
|
|
93158
93253
|
var GRID_GAP = 8;
|
|
93159
93254
|
var GRID_PADDING = 10;
|
|
93160
93255
|
var CARD_RADIUS = 8;
|
|
@@ -93277,6 +93372,7 @@ var ShortcutTab = class extends i {
|
|
|
93277
93372
|
_resizeObserver = null;
|
|
93278
93373
|
_theme = resolvePixiTheme(this);
|
|
93279
93374
|
_unsubTheme = null;
|
|
93375
|
+
_connectionGeneration = 0;
|
|
93280
93376
|
_renderedItems = [];
|
|
93281
93377
|
constructor() {
|
|
93282
93378
|
super();
|
|
@@ -93285,6 +93381,7 @@ var ShortcutTab = class extends i {
|
|
|
93285
93381
|
}
|
|
93286
93382
|
async connectedCallback() {
|
|
93287
93383
|
super.connectedCallback();
|
|
93384
|
+
const connectionGeneration = ++this._connectionGeneration;
|
|
93288
93385
|
this._theme = resolvePixiTheme(this);
|
|
93289
93386
|
this._unsubTheme = onThemeChange((theme) => {
|
|
93290
93387
|
this._theme = theme;
|
|
@@ -93292,9 +93389,10 @@ var ShortcutTab = class extends i {
|
|
|
93292
93389
|
}, this);
|
|
93293
93390
|
this._ensureActivePage();
|
|
93294
93391
|
await this.updateComplete;
|
|
93295
|
-
await this._initPixi();
|
|
93392
|
+
await this._initPixi(connectionGeneration);
|
|
93296
93393
|
}
|
|
93297
93394
|
disconnectedCallback() {
|
|
93395
|
+
this._connectionGeneration += 1;
|
|
93298
93396
|
super.disconnectedCallback();
|
|
93299
93397
|
this._resizeObserver?.disconnect();
|
|
93300
93398
|
this._resizeObserver = null;
|
|
@@ -93329,7 +93427,7 @@ var ShortcutTab = class extends i {
|
|
|
93329
93427
|
if (!pages.length) return;
|
|
93330
93428
|
if (!pages.some((page) => page.id === this.activePageId)) this.activePageId = pages[0].id;
|
|
93331
93429
|
}
|
|
93332
|
-
async _initPixi() {
|
|
93430
|
+
async _initPixi(connectionGeneration) {
|
|
93333
93431
|
const host = this.shadowRoot?.querySelector(".pixi-host");
|
|
93334
93432
|
if (!host) return;
|
|
93335
93433
|
const app = new Application();
|
|
@@ -93339,6 +93437,10 @@ var ShortcutTab = class extends i {
|
|
|
93339
93437
|
resolution: window.devicePixelRatio || 1,
|
|
93340
93438
|
autoDensity: false
|
|
93341
93439
|
});
|
|
93440
|
+
if (!this.isConnected || connectionGeneration !== this._connectionGeneration) {
|
|
93441
|
+
app.destroy();
|
|
93442
|
+
return;
|
|
93443
|
+
}
|
|
93342
93444
|
host.appendChild(app.canvas);
|
|
93343
93445
|
this._app = app;
|
|
93344
93446
|
const canvas = app.canvas;
|
|
@@ -94001,6 +94103,15 @@ var LAYOUTS = {
|
|
|
94001
94103
|
};
|
|
94002
94104
|
//#endregion
|
|
94003
94105
|
//#region ../xterm-input-panel/src/virtual-keyboard-tab.ts
|
|
94106
|
+
/**
|
|
94107
|
+
* Orthogonal intents (updated 2026-08-06 Asia/Shanghai):
|
|
94108
|
+
* 1. Render the platform-aware Pixi virtual keyboard surface.
|
|
94109
|
+
* 2. Translate key, modifier, repeat, and swipe gestures into typed panel events.
|
|
94110
|
+
* 3. Keep layout, resize, and theme projection synchronized with the host element.
|
|
94111
|
+
* 4. Retire late Pixi initialization after disconnect so detached render loops cannot survive.
|
|
94112
|
+
*
|
|
94113
|
+
* Original request (2026-08-04): "Make pnpm openspecui start and equivalent package scripts work on Windows, then handle similar portability failures."
|
|
94114
|
+
*/
|
|
94004
94115
|
var KEY_PADDING = 3;
|
|
94005
94116
|
var KEY_RADIUS = 4;
|
|
94006
94117
|
var REPEAT_DELAY_MS = 400;
|
|
@@ -94039,6 +94150,7 @@ var VirtualKeyboardTab = class extends i {
|
|
|
94039
94150
|
_resizeObserver = null;
|
|
94040
94151
|
_theme = resolvePixiTheme(this);
|
|
94041
94152
|
_unsubTheme = null;
|
|
94153
|
+
_connectionGeneration = 0;
|
|
94042
94154
|
_repeatTimer = null;
|
|
94043
94155
|
_repeatInterval = null;
|
|
94044
94156
|
_activeKey = null;
|
|
@@ -94053,15 +94165,17 @@ var VirtualKeyboardTab = class extends i {
|
|
|
94053
94165
|
}
|
|
94054
94166
|
async connectedCallback() {
|
|
94055
94167
|
super.connectedCallback();
|
|
94168
|
+
const connectionGeneration = ++this._connectionGeneration;
|
|
94056
94169
|
this._theme = resolvePixiTheme(this);
|
|
94057
94170
|
this._unsubTheme = onThemeChange((theme) => {
|
|
94058
94171
|
this._theme = theme;
|
|
94059
94172
|
this._layoutKeys();
|
|
94060
94173
|
}, this);
|
|
94061
94174
|
await this.updateComplete;
|
|
94062
|
-
await this._initPixi();
|
|
94175
|
+
await this._initPixi(connectionGeneration);
|
|
94063
94176
|
}
|
|
94064
94177
|
disconnectedCallback() {
|
|
94178
|
+
this._connectionGeneration += 1;
|
|
94065
94179
|
super.disconnectedCallback();
|
|
94066
94180
|
this._cancelRepeat();
|
|
94067
94181
|
this._resizeObserver?.disconnect();
|
|
@@ -94080,7 +94194,7 @@ var VirtualKeyboardTab = class extends i {
|
|
|
94080
94194
|
getRows() {
|
|
94081
94195
|
return LAYOUTS[this._hostPlatform()];
|
|
94082
94196
|
}
|
|
94083
|
-
async _initPixi() {
|
|
94197
|
+
async _initPixi(connectionGeneration) {
|
|
94084
94198
|
const host = this.shadowRoot?.querySelector(".pixi-host");
|
|
94085
94199
|
if (!host) return;
|
|
94086
94200
|
const app = new Application();
|
|
@@ -94091,6 +94205,10 @@ var VirtualKeyboardTab = class extends i {
|
|
|
94091
94205
|
resolution: window.devicePixelRatio || 1,
|
|
94092
94206
|
autoDensity: false
|
|
94093
94207
|
});
|
|
94208
|
+
if (!this.isConnected || connectionGeneration !== this._connectionGeneration) {
|
|
94209
|
+
app.destroy();
|
|
94210
|
+
return;
|
|
94211
|
+
}
|
|
94094
94212
|
host.appendChild(app.canvas);
|
|
94095
94213
|
this._app = app;
|
|
94096
94214
|
const canvas = app.canvas;
|
|
@@ -94509,6 +94627,15 @@ var VirtualKeyboardTab = class extends i {
|
|
|
94509
94627
|
customElements.define("virtual-keyboard-tab", VirtualKeyboardTab);
|
|
94510
94628
|
//#endregion
|
|
94511
94629
|
//#region ../xterm-input-panel/src/virtual-trackpad-tab.ts
|
|
94630
|
+
/**
|
|
94631
|
+
* Orthogonal intents (updated 2026-08-06 Asia/Shanghai):
|
|
94632
|
+
* 1. Render the Pixi virtual trackpad and its gesture feedback.
|
|
94633
|
+
* 2. Translate pointer, touch, long-press, drag, scroll, and edge gestures into panel events.
|
|
94634
|
+
* 3. Keep trackpad layout, resize, accent, and theme projection synchronized.
|
|
94635
|
+
* 4. Retire late Pixi initialization after disconnect so detached render loops cannot survive.
|
|
94636
|
+
*
|
|
94637
|
+
* Original request (2026-08-04): "Make pnpm openspecui start and equivalent package scripts work on Windows, then handle similar portability failures."
|
|
94638
|
+
*/
|
|
94512
94639
|
var DRAG_THRESHOLD = 8;
|
|
94513
94640
|
var LONG_PRESS_MS = 500;
|
|
94514
94641
|
var DOUBLE_TAP_MS = 300;
|
|
@@ -94575,6 +94702,7 @@ var VirtualTrackpadTab = class extends i {
|
|
|
94575
94702
|
_resizeObserver = null;
|
|
94576
94703
|
_theme = resolvePixiTheme(this);
|
|
94577
94704
|
_unsubTheme = null;
|
|
94705
|
+
_connectionGeneration = 0;
|
|
94578
94706
|
_touchStart = null;
|
|
94579
94707
|
_isDragging = false;
|
|
94580
94708
|
_longPressTimer = null;
|
|
@@ -94591,6 +94719,7 @@ var VirtualTrackpadTab = class extends i {
|
|
|
94591
94719
|
_edgeSlideInterval = null;
|
|
94592
94720
|
async connectedCallback() {
|
|
94593
94721
|
super.connectedCallback();
|
|
94722
|
+
const connectionGeneration = ++this._connectionGeneration;
|
|
94594
94723
|
this._theme = resolvePixiTheme(this);
|
|
94595
94724
|
this._syncAccentRgb();
|
|
94596
94725
|
this._unsubTheme = onThemeChange((theme) => {
|
|
@@ -94599,9 +94728,10 @@ var VirtualTrackpadTab = class extends i {
|
|
|
94599
94728
|
this._drawSurface();
|
|
94600
94729
|
}, this);
|
|
94601
94730
|
await this.updateComplete;
|
|
94602
|
-
await this._initPixi();
|
|
94731
|
+
await this._initPixi(connectionGeneration);
|
|
94603
94732
|
}
|
|
94604
94733
|
disconnectedCallback() {
|
|
94734
|
+
this._connectionGeneration += 1;
|
|
94605
94735
|
super.disconnectedCallback();
|
|
94606
94736
|
if (this._longPressTimer) clearTimeout(this._longPressTimer);
|
|
94607
94737
|
this._stopEdgeSlide();
|
|
@@ -94618,7 +94748,7 @@ var VirtualTrackpadTab = class extends i {
|
|
|
94618
94748
|
const hex = this._theme.accent;
|
|
94619
94749
|
this._accentRgb = `${hex >> 16 & 255},${hex >> 8 & 255},${hex & 255}`;
|
|
94620
94750
|
}
|
|
94621
|
-
async _initPixi() {
|
|
94751
|
+
async _initPixi(connectionGeneration) {
|
|
94622
94752
|
const host = this.shadowRoot?.querySelector(".pixi-host");
|
|
94623
94753
|
if (!host) return;
|
|
94624
94754
|
this._edgeOverlay = this.shadowRoot?.querySelector(".edge-glow");
|
|
@@ -94630,6 +94760,10 @@ var VirtualTrackpadTab = class extends i {
|
|
|
94630
94760
|
resolution: window.devicePixelRatio || 1,
|
|
94631
94761
|
autoDensity: false
|
|
94632
94762
|
});
|
|
94763
|
+
if (!this.isConnected || connectionGeneration !== this._connectionGeneration) {
|
|
94764
|
+
app.destroy();
|
|
94765
|
+
return;
|
|
94766
|
+
}
|
|
94633
94767
|
host.appendChild(app.canvas);
|
|
94634
94768
|
this._app = app;
|
|
94635
94769
|
const canvas = app.canvas;
|
|
@@ -97337,7 +97471,7 @@ var TerminalController = class {
|
|
|
97337
97471
|
if (this.configPersistTimer) clearTimeout(this.configPersistTimer);
|
|
97338
97472
|
this.configPersistTimer = setTimeout(() => {
|
|
97339
97473
|
this.configPersistTimer = null;
|
|
97340
|
-
import("./trpc-
|
|
97474
|
+
import("./trpc-DMtttD_4.js").then(({ trpcClient }) => {
|
|
97341
97475
|
trpcClient.config.update.mutate({ terminal: { fontSize: this.config.fontSize } });
|
|
97342
97476
|
}).catch(() => {});
|
|
97343
97477
|
}, CONFIG_PERSIST_DEBOUNCE);
|
|
@@ -98906,6 +99040,42 @@ function ConfigFormSkeleton({ fields = 4 }) {
|
|
|
98906
99040
|
});
|
|
98907
99041
|
}
|
|
98908
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
|
|
98909
99079
|
//#region src/lib/format-time.ts
|
|
98910
99080
|
/**
|
|
98911
99081
|
* Format a timestamp as relative time (e.g., "2 hours ago", "3 days ago")
|
|
@@ -107862,7 +108032,7 @@ var languages = [
|
|
|
107862
108032
|
name: "CSS",
|
|
107863
108033
|
extensions: ["css"],
|
|
107864
108034
|
load() {
|
|
107865
|
-
return import("./dist-
|
|
108035
|
+
return import("./dist-CpgxMd46.js").then((m) => m.css());
|
|
107866
108036
|
}
|
|
107867
108037
|
}),
|
|
107868
108038
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107882,7 +108052,7 @@ var languages = [
|
|
|
107882
108052
|
"hbs"
|
|
107883
108053
|
],
|
|
107884
108054
|
load() {
|
|
107885
|
-
return import("./dist-
|
|
108055
|
+
return import("./dist-BZwNiEjE.js").then((m) => m.html());
|
|
107886
108056
|
}
|
|
107887
108057
|
}),
|
|
107888
108058
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107916,7 +108086,7 @@ var languages = [
|
|
|
107916
108086
|
"jinja2"
|
|
107917
108087
|
],
|
|
107918
108088
|
load() {
|
|
107919
|
-
return import("./dist-
|
|
108089
|
+
return import("./dist-CSnQ9MUZ.js").then((m) => m.jinja());
|
|
107920
108090
|
}
|
|
107921
108091
|
}),
|
|
107922
108092
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107924,7 +108094,7 @@ var languages = [
|
|
|
107924
108094
|
alias: ["json5"],
|
|
107925
108095
|
extensions: ["json", "map"],
|
|
107926
108096
|
load() {
|
|
107927
|
-
return import("./dist-
|
|
108097
|
+
return import("./dist-vPFtDCqy.js").then((m) => m.json());
|
|
107928
108098
|
}
|
|
107929
108099
|
}),
|
|
107930
108100
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107938,14 +108108,14 @@ var languages = [
|
|
|
107938
108108
|
name: "LESS",
|
|
107939
108109
|
extensions: ["less"],
|
|
107940
108110
|
load() {
|
|
107941
|
-
return import("./dist-
|
|
108111
|
+
return import("./dist-CD_P89TI.js").then((m) => m.less());
|
|
107942
108112
|
}
|
|
107943
108113
|
}),
|
|
107944
108114
|
/* @__PURE__ */ LanguageDescription.of({
|
|
107945
108115
|
name: "Liquid",
|
|
107946
108116
|
extensions: ["liquid"],
|
|
107947
108117
|
load() {
|
|
107948
|
-
return import("./dist-
|
|
108118
|
+
return import("./dist-TFBLKdTC.js").then((m) => m.liquid());
|
|
107949
108119
|
}
|
|
107950
108120
|
}),
|
|
107951
108121
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107962,7 +108132,7 @@ var languages = [
|
|
|
107962
108132
|
"mkd"
|
|
107963
108133
|
],
|
|
107964
108134
|
load() {
|
|
107965
|
-
return import("./dist-
|
|
108135
|
+
return import("./dist-tvIcsOn0.js").then((m) => m.markdown());
|
|
107966
108136
|
}
|
|
107967
108137
|
}),
|
|
107968
108138
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -107988,7 +108158,7 @@ var languages = [
|
|
|
107988
108158
|
"phtml"
|
|
107989
108159
|
],
|
|
107990
108160
|
load() {
|
|
107991
|
-
return import("./dist-
|
|
108161
|
+
return import("./dist-BTzm9CCH.js").then((m) => m.php());
|
|
107992
108162
|
}
|
|
107993
108163
|
}),
|
|
107994
108164
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108028,14 +108198,14 @@ var languages = [
|
|
|
108028
108198
|
name: "Sass",
|
|
108029
108199
|
extensions: ["sass"],
|
|
108030
108200
|
load() {
|
|
108031
|
-
return import("./dist-
|
|
108201
|
+
return import("./dist-Bg6kJ4lE.js").then((m) => m.sass({ indented: true }));
|
|
108032
108202
|
}
|
|
108033
108203
|
}),
|
|
108034
108204
|
/* @__PURE__ */ LanguageDescription.of({
|
|
108035
108205
|
name: "SCSS",
|
|
108036
108206
|
extensions: ["scss"],
|
|
108037
108207
|
load() {
|
|
108038
|
-
return import("./dist-
|
|
108208
|
+
return import("./dist-Bg6kJ4lE.js").then((m) => m.sass());
|
|
108039
108209
|
}
|
|
108040
108210
|
}),
|
|
108041
108211
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108102,7 +108272,7 @@ var languages = [
|
|
|
108102
108272
|
alias: ["yml"],
|
|
108103
108273
|
extensions: ["yaml", "yml"],
|
|
108104
108274
|
load() {
|
|
108105
|
-
return import("./dist-
|
|
108275
|
+
return import("./dist-gfV2B0G7.js").then((m) => m.yaml());
|
|
108106
108276
|
}
|
|
108107
108277
|
}),
|
|
108108
108278
|
/* @__PURE__ */ LanguageDescription.of({
|
|
@@ -108989,13 +109159,13 @@ var languages = [
|
|
|
108989
109159
|
name: "Vue",
|
|
108990
109160
|
extensions: ["vue"],
|
|
108991
109161
|
load() {
|
|
108992
|
-
return import("./dist-
|
|
109162
|
+
return import("./dist-CzfcaAEs.js").then((m) => m.vue());
|
|
108993
109163
|
}
|
|
108994
109164
|
}),
|
|
108995
109165
|
/* @__PURE__ */ LanguageDescription.of({
|
|
108996
109166
|
name: "Angular Template",
|
|
108997
109167
|
load() {
|
|
108998
|
-
return import("./dist-
|
|
109168
|
+
return import("./dist-CkE7XypO.js").then((m) => m.angular());
|
|
108999
109169
|
}
|
|
109000
109170
|
})
|
|
109001
109171
|
];
|
|
@@ -169221,7 +169391,14 @@ function ReadonlyKanbanRow({ item, laneId, compact }) {
|
|
|
169221
169391
|
family: archived ? "archive" : "changes",
|
|
169222
169392
|
entityId: item.id
|
|
169223
169393
|
};
|
|
169224
|
-
const
|
|
169394
|
+
const cli = item.cliTaskSummary ?? null;
|
|
169395
|
+
const progress = cli ? {
|
|
169396
|
+
completed: cli.completedTasks,
|
|
169397
|
+
total: cli.totalTasks
|
|
169398
|
+
} : {
|
|
169399
|
+
completed: item.trackedTaskProgress.completed,
|
|
169400
|
+
total: item.trackedTaskProgress.total
|
|
169401
|
+
};
|
|
169225
169402
|
const percent = progress.total > 0 ? Math.round(progress.completed / progress.total * 100) : 0;
|
|
169226
169403
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(VTLink, {
|
|
169227
169404
|
to: archived ? "/archive/$changeId" : "/changes/$changeId",
|
|
@@ -169619,13 +169796,103 @@ function Board() {
|
|
|
169619
169796
|
});
|
|
169620
169797
|
}
|
|
169621
169798
|
//#endregion
|
|
169799
|
+
//#region src/components/change-row.tsx
|
|
169800
|
+
/**
|
|
169801
|
+
* Orthogonal intents (created 2026-08-15 Asia/Shanghai):
|
|
169802
|
+
* 1. Render one Change row with a grid: icon, title/subtitle, and a right rail.
|
|
169803
|
+
* 2. Keep the phase badge vertically centered while the time anchors the rail bottom.
|
|
169804
|
+
* 3. Share the exact row vocabulary between the Changes list and Dashboard.
|
|
169805
|
+
* 4. Preserve shared-element bindings for View Transition continuity.
|
|
169806
|
+
* 5. Fill the phase badge with a proportional background when a progress ratio exists —
|
|
169807
|
+
* an ambient progress signal that survives subtitle truncation on narrow viewports.
|
|
169808
|
+
*
|
|
169809
|
+
* Original request (2026-08-15): Owner walkthrough: grid layout, subtitle facts, badge
|
|
169810
|
+
* centered with time at the bottom, one atomic row component across pages.
|
|
169811
|
+
* Original request (2026-08-16): Owner walkthrough: use a soft primary fill behind the
|
|
169812
|
+
* Applying badge as a space-free progress affordance for mobile truncation.
|
|
169813
|
+
*/
|
|
169814
|
+
/**
|
|
169815
|
+
* Ambient fill layer behind the phase badge: a soft primary wash sized to the applied-task
|
|
169816
|
+
* ratio. It carries no text and claims no layout — a visual progress hint that stays
|
|
169817
|
+
* readable when the row's subtitle facts are truncated on narrow viewports.
|
|
169818
|
+
*/
|
|
169819
|
+
function PhaseBadgeProgressFill({ ratio }) {
|
|
169820
|
+
if (!Number.isFinite(ratio) || ratio <= 0) return null;
|
|
169821
|
+
const clamped = Math.min(100, Math.max(0, ratio * 100));
|
|
169822
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
169823
|
+
"aria-hidden": "true",
|
|
169824
|
+
className: "bg-primary/50 pointer-events-none absolute inset-y-0 left-0 rounded-[inherit]",
|
|
169825
|
+
style: { width: `${clamped}%` }
|
|
169826
|
+
});
|
|
169827
|
+
}
|
|
169828
|
+
/** Shared Change-row layout: icon | title+subtitle | badge(time) | chevron. */
|
|
169829
|
+
function ChangeRow({ changeId, name, subtitle, phase, updatedAt, formatTime, sharedFamily = "changes", className = "", progressRatio = null, containerProps, titleProps, iconProps }) {
|
|
169830
|
+
const sharedDescriptor = {
|
|
169831
|
+
family: sharedFamily,
|
|
169832
|
+
entityId: changeId
|
|
169833
|
+
};
|
|
169834
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169835
|
+
...containerProps,
|
|
169836
|
+
...getSharedElementBinding(sharedDescriptor, "container"),
|
|
169837
|
+
className: `grid grid-cols-[auto_minmax(0,1fr)_auto] items-stretch gap-x-3 ${className}`,
|
|
169838
|
+
children: [
|
|
169839
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169840
|
+
className: "flex items-center",
|
|
169841
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitBranch, {
|
|
169842
|
+
...iconProps,
|
|
169843
|
+
...getSharedElementBinding(sharedDescriptor, "icon"),
|
|
169844
|
+
className: "text-muted-foreground h-5 w-5 shrink-0"
|
|
169845
|
+
})
|
|
169846
|
+
}),
|
|
169847
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169848
|
+
className: "flex min-w-0 flex-col justify-center gap-0.5 py-0.5",
|
|
169849
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169850
|
+
...titleProps,
|
|
169851
|
+
...getSharedElementBinding(sharedDescriptor, "title"),
|
|
169852
|
+
className: "truncate font-medium",
|
|
169853
|
+
children: name
|
|
169854
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169855
|
+
className: "text-muted-foreground truncate text-xs",
|
|
169856
|
+
children: subtitle
|
|
169857
|
+
})]
|
|
169858
|
+
}),
|
|
169859
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169860
|
+
className: "flex flex-col items-end justify-between gap-1 text-right",
|
|
169861
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169862
|
+
className: "flex flex-1 items-center",
|
|
169863
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Badge, {
|
|
169864
|
+
tone: "custom",
|
|
169865
|
+
size: "sm",
|
|
169866
|
+
shape: "box",
|
|
169867
|
+
className: `relative overflow-hidden border ${phase.toneClass}`,
|
|
169868
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhaseBadgeProgressFill, { ratio: progressRatio ?? NaN }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
169869
|
+
className: "relative",
|
|
169870
|
+
children: phase.label
|
|
169871
|
+
})]
|
|
169872
|
+
})
|
|
169873
|
+
}), updatedAt > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
169874
|
+
className: "text-muted-foreground shrink-0 text-xs",
|
|
169875
|
+
children: formatTime(updatedAt)
|
|
169876
|
+
}) : null]
|
|
169877
|
+
})
|
|
169878
|
+
]
|
|
169879
|
+
});
|
|
169880
|
+
}
|
|
169881
|
+
/** Chevron affordance kept outside the grid so row layouts stay composable. */
|
|
169882
|
+
function ChangeRowChevron() {
|
|
169883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, {
|
|
169884
|
+
className: "text-muted-foreground h-4 w-4 shrink-0",
|
|
169885
|
+
"aria-hidden": true
|
|
169886
|
+
});
|
|
169887
|
+
}
|
|
169888
|
+
//#endregion
|
|
169622
169889
|
//#region src/lib/change-workflow-phase.ts
|
|
169623
169890
|
function classifyChangeWorkflowPhase(params) {
|
|
169624
169891
|
if (!params.hasStatus) return {
|
|
169625
169892
|
label: "Unknown",
|
|
169626
169893
|
toneClass: "border-border text-muted-foreground"
|
|
169627
169894
|
};
|
|
169628
|
-
if (params.
|
|
169895
|
+
if (params.isPlanningComplete && params.trackedTaskPhase === "complete") return {
|
|
169629
169896
|
label: "Workflow Complete",
|
|
169630
169897
|
toneClass: "border-emerald-500/40 text-emerald-700 dark:text-emerald-300"
|
|
169631
169898
|
};
|
|
@@ -169637,6 +169904,15 @@ function classifyChangeWorkflowPhase(params) {
|
|
|
169637
169904
|
label: "No Tracked Tasks",
|
|
169638
169905
|
toneClass: "border-border text-muted-foreground"
|
|
169639
169906
|
};
|
|
169907
|
+
const applied = params.cliCompletedTasks ?? null;
|
|
169908
|
+
if (applied !== null && applied > 0) return {
|
|
169909
|
+
label: "Applying",
|
|
169910
|
+
toneClass: "border-primary/40 text-primary"
|
|
169911
|
+
};
|
|
169912
|
+
if (params.isPlanningComplete) return {
|
|
169913
|
+
label: "Planning Complete",
|
|
169914
|
+
toneClass: "border-sky-500/40 text-sky-700 dark:text-sky-300"
|
|
169915
|
+
};
|
|
169640
169916
|
return {
|
|
169641
169917
|
label: "In Execution",
|
|
169642
169918
|
toneClass: "border-primary/40 text-primary"
|
|
@@ -169726,7 +170002,7 @@ function useChangeListContinuity(incomingChanges, containerRef) {
|
|
|
169726
170002
|
//#endregion
|
|
169727
170003
|
//#region src/routes/change-list.tsx
|
|
169728
170004
|
/**
|
|
169729
|
-
* Orthogonal intents (updated 2026-
|
|
170005
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
169730
170006
|
* 1. List only active Changes from the current writable Planning root.
|
|
169731
170007
|
* 2. Derive workflow state and terminal evidence from CLI Status and formal tracked-task progress.
|
|
169732
170008
|
* 3. Preserve ChangeList row continuity and stale display together with collision-safe detail navigation.
|
|
@@ -169739,6 +170015,8 @@ function useChangeListContinuity(incomingChanges, containerRef) {
|
|
|
169739
170015
|
*
|
|
169740
170016
|
* Original request (2026-07-15): "One project backend has one launch project and one CLI-selected writable planning root."
|
|
169741
170017
|
* Original request (2026-07-21): "Changes页面的右上角没有 New,你要不要快速补一个"
|
|
170018
|
+
|
|
170019
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
169742
170020
|
*/
|
|
169743
170021
|
function buildStatusMap(statuses) {
|
|
169744
170022
|
return new Map((statuses ?? []).map((status) => [status.changeName, status]));
|
|
@@ -169861,16 +170139,16 @@ function ChangeList() {
|
|
|
169861
170139
|
const totalArtifacts = status?.artifacts.length ?? 0;
|
|
169862
170140
|
const phase = classifyChangeWorkflowPhase({
|
|
169863
170141
|
hasStatus: Boolean(status),
|
|
169864
|
-
|
|
170142
|
+
isPlanningComplete: status?.isPlanningComplete ?? false,
|
|
169865
170143
|
trackedTaskPhase: change.trackedTaskProgress.phase,
|
|
169866
|
-
trackedArtifactStatus: inferTrackedArtifactStatus(status?.artifacts.map((artifact) => artifact.status) ?? [])
|
|
170144
|
+
trackedArtifactStatus: inferTrackedArtifactStatus(status?.artifacts.map((artifact) => artifact.status) ?? []),
|
|
170145
|
+
cliCompletedTasks: change.cliTaskSummary?.completedTasks ?? null
|
|
169867
170146
|
});
|
|
169868
|
-
const taskPercent = change.trackedTaskProgress.total > 0 ? Math.round(change.trackedTaskProgress.completed / change.trackedTaskProgress.total * 100) : 0;
|
|
169869
170147
|
const sharedDescriptor = {
|
|
169870
170148
|
family: "changes",
|
|
169871
170149
|
entityId: change.id
|
|
169872
170150
|
};
|
|
169873
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
170151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VTLink, {
|
|
169874
170152
|
to: "/changes/$changeId",
|
|
169875
170153
|
params: { changeId: change.id },
|
|
169876
170154
|
state: (prev) => ({
|
|
@@ -169885,74 +170163,30 @@ function ChangeList() {
|
|
|
169885
170163
|
vt: { sharedElements: sharedDescriptor },
|
|
169886
170164
|
...getSharedElementBinding(sharedDescriptor, "container"),
|
|
169887
170165
|
className: "hover:bg-muted/50 block px-4 py-3",
|
|
169888
|
-
children:
|
|
169889
|
-
|
|
169890
|
-
|
|
169891
|
-
|
|
169892
|
-
|
|
169893
|
-
|
|
169894
|
-
|
|
169895
|
-
|
|
169896
|
-
|
|
169897
|
-
|
|
169898
|
-
|
|
169899
|
-
|
|
169900
|
-
|
|
169901
|
-
children: change.name
|
|
169902
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169903
|
-
className: "text-muted-foreground truncate text-sm",
|
|
169904
|
-
children: [change.id, change.updatedAt > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [" · ", formatRelativeTime(change.updatedAt)] })]
|
|
169905
|
-
})]
|
|
169906
|
-
})]
|
|
169907
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169908
|
-
className: "flex items-center gap-3",
|
|
169909
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169910
|
-
className: "flex flex-col items-end gap-1 text-right text-sm",
|
|
169911
|
-
children: [
|
|
169912
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
169913
|
-
tone: "custom",
|
|
169914
|
-
size: "sm",
|
|
169915
|
-
shape: "box",
|
|
169916
|
-
className: `border ${phase.toneClass}`,
|
|
169917
|
-
children: phase.label
|
|
169918
|
-
}),
|
|
169919
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169920
|
-
className: "font-medium",
|
|
169921
|
-
children: [
|
|
169922
|
-
change.trackedTaskProgress.completed,
|
|
169923
|
-
"/",
|
|
169924
|
-
change.trackedTaskProgress.total
|
|
169925
|
-
]
|
|
169926
|
-
}),
|
|
169927
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169928
|
-
className: "text-muted-foreground text-xs",
|
|
169929
|
-
children: "tasks"
|
|
169930
|
-
})
|
|
169931
|
-
]
|
|
169932
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "text-muted-foreground h-4 w-4 shrink-0" })]
|
|
169933
|
-
})]
|
|
169934
|
-
}),
|
|
169935
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169936
|
-
className: "bg-muted h-1.5 rounded-full",
|
|
169937
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
169938
|
-
className: "bg-primary h-full rounded-full transition-all",
|
|
169939
|
-
style: { width: `${taskPercent}%` }
|
|
169940
|
-
})
|
|
169941
|
-
}),
|
|
169942
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169943
|
-
className: "text-muted-foreground mt-2 flex flex-wrap items-center justify-between gap-2 text-xs",
|
|
169944
|
-
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", {
|
|
169945
|
-
className: "truncate",
|
|
170166
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
170167
|
+
className: "flex items-center gap-3",
|
|
170168
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
|
|
170169
|
+
changeId: change.id,
|
|
170170
|
+
name: change.name,
|
|
170171
|
+
phase,
|
|
170172
|
+
updatedAt: change.updatedAt,
|
|
170173
|
+
formatTime: formatRelativeTime,
|
|
170174
|
+
progressRatio: change.cliTaskSummary && change.cliTaskSummary.totalTasks > 0 ? change.cliTaskSummary.completedTasks / change.cliTaskSummary.totalTasks : null,
|
|
170175
|
+
className: "min-w-0 flex-1",
|
|
170176
|
+
titleProps: { ...change.id !== change.name ? {} : null },
|
|
170177
|
+
subtitle: !statusError && status ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
170178
|
+
title: "Task counts reported by the OpenSpec CLI for this Change.",
|
|
169946
170179
|
children: [
|
|
169947
170180
|
doneArtifacts,
|
|
169948
170181
|
"/",
|
|
169949
170182
|
totalArtifacts,
|
|
169950
170183
|
" artifacts · ",
|
|
169951
|
-
status.schemaName
|
|
170184
|
+
status.schemaName,
|
|
170185
|
+
change.cliTaskSummary ? ` · Tasks ${change.cliTaskSummary.completedTasks}/${change.cliTaskSummary.totalTasks}` : ""
|
|
169952
170186
|
]
|
|
169953
|
-
}) : !statusError && statuses === void 0 && isStatusLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RealtimeSkeletonLine, { className: "w-28" }) :
|
|
169954
|
-
})
|
|
169955
|
-
|
|
170187
|
+
}) : !statusError && statuses === void 0 && isStatusLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RealtimeSkeletonLine, { className: "w-28" }) : "Workflow status unavailable"
|
|
170188
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRowChevron, {})]
|
|
170189
|
+
})
|
|
169956
170190
|
}, change.id);
|
|
169957
170191
|
}), hasCurrentEmptyChanges && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
169958
170192
|
className: "text-muted-foreground p-4 text-center",
|
|
@@ -170980,15 +171214,41 @@ function EvidenceDisclosure({ title, children, summary, defaultOpen = false, cla
|
|
|
170980
171214
|
//#endregion
|
|
170981
171215
|
//#region src/components/apply-progress-notice.tsx
|
|
170982
171216
|
/**
|
|
170983
|
-
* Orthogonal intents (updated 2026-
|
|
171217
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
170984
171218
|
* 1. Attribute Apply instruction counts to the upstream Apply command.
|
|
170985
|
-
* 2.
|
|
170986
|
-
* 3. Keep divergence
|
|
171219
|
+
* 2. Compress agreement to one subtitle badge; keep divergence a direct blocker.
|
|
171220
|
+
* 3. Keep divergence's two objective source counts side by side with their causes.
|
|
171221
|
+
* 4. Keep tooltips as the keyboard-reachable explanation for every compact count.
|
|
170987
171222
|
*
|
|
170988
171223
|
* Original request (2026-07-15): "与 tracked glob 进度分歧时各自归因展示。"
|
|
170989
171224
|
* Original request (2026-07-28): supporting 6.x evidence should use Badge + Tooltip or Accordion.
|
|
171225
|
+
* Original request (2026-08-15): Owner walkthrough: agreement is one badge in the subtitle row,
|
|
171226
|
+
* not a two-line block; only divergence owns a notice.
|
|
171227
|
+
*/
|
|
171228
|
+
/**
|
|
171229
|
+
* One compact, source-attributed Apply progress badge for the Change subtitle row.
|
|
171230
|
+
* The Apply instruction result is the only visible implementation progress authority, so
|
|
171231
|
+
* this stays rendered whenever instructions exist — agreement is not a reason to hide the
|
|
171232
|
+
* CLI's own count, but it needs no separate block.
|
|
171233
|
+
*/
|
|
171234
|
+
function ApplyProgressBadge({ applyInstructionProgress }) {
|
|
171235
|
+
const { complete, total, remaining } = applyInstructionProgress;
|
|
171236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171237
|
+
ariaLabel: `Apply instructions progress ${complete} of ${total}`,
|
|
171238
|
+
tooltip: `Progress reported by openspec instructions apply — ${complete} of ${total} tasks applied, ${remaining} remaining.`,
|
|
171239
|
+
children: [
|
|
171240
|
+
"Apply ",
|
|
171241
|
+
complete,
|
|
171242
|
+
"/",
|
|
171243
|
+
total
|
|
171244
|
+
]
|
|
171245
|
+
});
|
|
171246
|
+
}
|
|
171247
|
+
/**
|
|
171248
|
+
* Render the Apply/tracked divergence as one direct, source-attributed blocker. Returns
|
|
171249
|
+
* null when the sources agree — the agreement case lives in the subtitle badge row via
|
|
171250
|
+
* {@link ApplyProgressBadge}.
|
|
170990
171251
|
*/
|
|
170991
|
-
/** Render source-attributed Apply progress and any tracked-progress divergence. */
|
|
170992
171252
|
function ApplyProgressNotice({ applyInstructionProgress }) {
|
|
170993
171253
|
const divergence = applyInstructionProgress.divergence;
|
|
170994
171254
|
if (!divergence) return null;
|
|
@@ -171010,13 +171270,13 @@ function ApplyProgressNotice({ applyInstructionProgress }) {
|
|
|
171010
171270
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171011
171271
|
className: "flex flex-wrap gap-1.5",
|
|
171012
171272
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171013
|
-
ariaLabel: `Apply instructions progress ${
|
|
171273
|
+
ariaLabel: `Apply instructions progress ${applyInstructionProgress.complete} of ${applyInstructionProgress.total}`,
|
|
171014
171274
|
tooltip: "Progress reported by openspec instructions apply.",
|
|
171015
171275
|
children: [
|
|
171016
171276
|
"Apply ",
|
|
171017
|
-
|
|
171277
|
+
applyInstructionProgress.complete,
|
|
171018
171278
|
"/",
|
|
171019
|
-
|
|
171279
|
+
applyInstructionProgress.total
|
|
171020
171280
|
]
|
|
171021
171281
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InformationBadge, {
|
|
171022
171282
|
ariaLabel: `Tracked artifact glob progress ${divergence.tracked.completed} of ${divergence.tracked.total}`,
|
|
@@ -171033,16 +171293,284 @@ function ApplyProgressNotice({ applyInstructionProgress }) {
|
|
|
171033
171293
|
})]
|
|
171034
171294
|
});
|
|
171035
171295
|
}
|
|
171296
|
+
var OPENSPEC_CLI_SUPPORTED_SERIES = ["1.8", "1.9"];
|
|
171297
|
+
/**
|
|
171298
|
+
* Derive command capabilities from one parsed CLI version.
|
|
171299
|
+
*
|
|
171300
|
+
* Only an admitted version — stable inside the accepted range — can select version-specific
|
|
171301
|
+
* capabilities. Unsupported forms (prereleases, >=1.10, below-range) and unparseable output
|
|
171302
|
+
* keep their mismatch evidence and expose no capability, so a page-level version bypass can
|
|
171303
|
+
* never manufacture a 1.9 command surface for a CLI the release line does not admit.
|
|
171304
|
+
*/
|
|
171305
|
+
function deriveOpenSpecCliCapabilities(version) {
|
|
171306
|
+
if (!isAdmittedVersion(version)) return {
|
|
171307
|
+
schemasRootSelector: false,
|
|
171308
|
+
archivedValidation: false
|
|
171309
|
+
};
|
|
171310
|
+
const onTargetSeries = isSeries(version, "1.9");
|
|
171311
|
+
return {
|
|
171312
|
+
schemasRootSelector: onTargetSeries,
|
|
171313
|
+
archivedValidation: onTargetSeries
|
|
171314
|
+
};
|
|
171315
|
+
}
|
|
171316
|
+
function parseOpenSpecCliVersion(raw) {
|
|
171317
|
+
if (!raw) return null;
|
|
171318
|
+
const match = raw.match(/(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/);
|
|
171319
|
+
if (!match) return null;
|
|
171320
|
+
return {
|
|
171321
|
+
major: Number(match[1]),
|
|
171322
|
+
minor: Number(match[2]),
|
|
171323
|
+
patch: Number(match[3]),
|
|
171324
|
+
prerelease: match[4] ?? null
|
|
171325
|
+
};
|
|
171326
|
+
}
|
|
171327
|
+
function isSeries(version, series) {
|
|
171328
|
+
const [major, minor] = series.split(".").map((part) => Number(part));
|
|
171329
|
+
return version.major === major && version.minor === minor;
|
|
171330
|
+
}
|
|
171331
|
+
function isStable(version) {
|
|
171332
|
+
return version.prerelease === null;
|
|
171333
|
+
}
|
|
171334
|
+
/** True only for stable versions inside the accepted range (current or supported non-current). */
|
|
171335
|
+
function isAdmittedVersion(version) {
|
|
171336
|
+
if (!version || !isStable(version)) return false;
|
|
171337
|
+
return isSeries(version, "1.9") || isSupportedNonCurrentSeries(version);
|
|
171338
|
+
}
|
|
171339
|
+
function isSupportedNonCurrentSeries(version) {
|
|
171340
|
+
return OPENSPEC_CLI_SUPPORTED_SERIES.filter((series) => series !== "1.9").some((series) => isSeries(version, series));
|
|
171341
|
+
}
|
|
171342
|
+
//#endregion
|
|
171343
|
+
//#region src/components/archived-validation-evidence.tsx
|
|
171344
|
+
/**
|
|
171345
|
+
* Orthogonal intents (created 2026-08-15 Asia/Shanghai):
|
|
171346
|
+
* 1. Present OpenSpec 1.9 `validate --archived --json` as typed CLI evidence.
|
|
171347
|
+
* 2. Preserve item issues, totals, root, and exit/failure evidence without repair actions.
|
|
171348
|
+
* 3. Identify the evidence as unavailable in static snapshots instead of fabricating it.
|
|
171349
|
+
* 4. Derive the capability from the detected admitted CLI and hide the action on 1.8.
|
|
171350
|
+
* 5. Validate report payloads with the Core contract schema, never shallow shape guards.
|
|
171351
|
+
*
|
|
171352
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
171353
|
+
*/
|
|
171354
|
+
function parseValidationReport(value) {
|
|
171355
|
+
const parsed = CliValidateReportSchema.safeParse(value);
|
|
171356
|
+
if (parsed.success) return {
|
|
171357
|
+
report: parsed.data,
|
|
171358
|
+
schemaIssues: []
|
|
171359
|
+
};
|
|
171360
|
+
return {
|
|
171361
|
+
report: null,
|
|
171362
|
+
schemaIssues: parsed.error.issues.map((issue) => `${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`)
|
|
171363
|
+
};
|
|
171364
|
+
}
|
|
171365
|
+
function IssueList({ issues }) {
|
|
171366
|
+
if (issues.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
171367
|
+
className: "text-muted-foreground",
|
|
171368
|
+
children: "No CLI issue reported."
|
|
171369
|
+
});
|
|
171370
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
171371
|
+
className: "text-muted-foreground space-y-0.5",
|
|
171372
|
+
children: issues.map((issue, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
|
|
171373
|
+
className: "break-words",
|
|
171374
|
+
children: [
|
|
171375
|
+
issue.level,
|
|
171376
|
+
" · ",
|
|
171377
|
+
issue.path,
|
|
171378
|
+
" · ",
|
|
171379
|
+
issue.message
|
|
171380
|
+
]
|
|
171381
|
+
}, index))
|
|
171382
|
+
});
|
|
171383
|
+
}
|
|
171384
|
+
function RunButton({ pending, label, onRun }) {
|
|
171385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
171386
|
+
type: "button",
|
|
171387
|
+
onClick: onRun,
|
|
171388
|
+
disabled: pending,
|
|
171389
|
+
"aria-busy": pending || void 0,
|
|
171390
|
+
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",
|
|
171391
|
+
children: [pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
|
|
171392
|
+
className: "h-3.5 w-3.5 animate-spin",
|
|
171393
|
+
"aria-hidden": true
|
|
171394
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCw, {
|
|
171395
|
+
className: "h-3.5 w-3.5",
|
|
171396
|
+
"aria-hidden": true
|
|
171397
|
+
}), label]
|
|
171398
|
+
});
|
|
171399
|
+
}
|
|
171400
|
+
/** On-demand, read-only archived-task validation evidence for the Change Evidence tab. */
|
|
171401
|
+
function ArchivedValidationEvidence() {
|
|
171402
|
+
const [report, setReport] = (0, import_react.useState)(null);
|
|
171403
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
171404
|
+
const [pending, setPending] = (0, import_react.useState)(false);
|
|
171405
|
+
const cli = useRootActionState().context?.cli;
|
|
171406
|
+
const capabilities = deriveOpenSpecCliCapabilities(cli?.available ? parseOpenSpecCliVersion(cli.version) : null);
|
|
171407
|
+
if (isStaticMode()) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171408
|
+
title: "Archived validation",
|
|
171409
|
+
summary: "Unavailable in static snapshot",
|
|
171410
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
171411
|
+
className: "text-muted-foreground",
|
|
171412
|
+
children: "Archived-task validation is live CLI evidence and is not captured in this static snapshot."
|
|
171413
|
+
})
|
|
171414
|
+
});
|
|
171415
|
+
if (cli?.available === true && !capabilities.archivedValidation) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171416
|
+
title: "Archived validation",
|
|
171417
|
+
summary: "Unavailable on this CLI line",
|
|
171418
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
171419
|
+
className: "text-muted-foreground",
|
|
171420
|
+
children: [
|
|
171421
|
+
"Archived-task validation requires the OpenSpec 1.9 line",
|
|
171422
|
+
cli.version ? ` (detected ${cli.version.trim()})` : "",
|
|
171423
|
+
". This session's CLI does not declare the capability, so no command is offered."
|
|
171424
|
+
]
|
|
171425
|
+
})
|
|
171426
|
+
});
|
|
171427
|
+
const run = async () => {
|
|
171428
|
+
setPending(true);
|
|
171429
|
+
setError(null);
|
|
171430
|
+
setReport(null);
|
|
171431
|
+
try {
|
|
171432
|
+
const result = await trpcClient.cli.validate.mutate({ kind: "archived" });
|
|
171433
|
+
const transport = CliCommandTransportSchema.safeParse(result);
|
|
171434
|
+
if (transport.success) setReport({
|
|
171435
|
+
...transport.data,
|
|
171436
|
+
data: transport.data.data ?? null,
|
|
171437
|
+
payload: transport.data.payload ?? null
|
|
171438
|
+
});
|
|
171439
|
+
else setError("The archived validation transport returned an unrecognized result shape.");
|
|
171440
|
+
} catch (cause) {
|
|
171441
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
171442
|
+
} finally {
|
|
171443
|
+
setPending(false);
|
|
171444
|
+
}
|
|
171445
|
+
};
|
|
171446
|
+
if (!report && !error) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171447
|
+
title: "Archived validation",
|
|
171448
|
+
summary: "OpenSpec 1.9 archived-task validation",
|
|
171449
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171450
|
+
className: "space-y-2",
|
|
171451
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
171452
|
+
className: "text-muted-foreground",
|
|
171453
|
+
children: "Run the official CLI's archived-task validation and keep its typed report as evidence. OpenSpecUI never repairs or archives from here."
|
|
171454
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
|
|
171455
|
+
pending,
|
|
171456
|
+
label: "Validate archived tasks",
|
|
171457
|
+
onRun: () => void run()
|
|
171458
|
+
})]
|
|
171459
|
+
})
|
|
171460
|
+
});
|
|
171461
|
+
const parsed = report ? parseValidationReport(report.data) : {
|
|
171462
|
+
report: null,
|
|
171463
|
+
schemaIssues: []
|
|
171464
|
+
};
|
|
171465
|
+
const validationReport = parsed.report;
|
|
171466
|
+
if (error || !validationReport) {
|
|
171467
|
+
const schemaDiagnostic = parsed.schemaIssues.length > 0 ? parsed.schemaIssues.join("; ") : null;
|
|
171468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171469
|
+
title: "Archived validation",
|
|
171470
|
+
summary: "CLI failure evidence",
|
|
171471
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171472
|
+
className: "space-y-2",
|
|
171473
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171474
|
+
className: "text-destructive flex items-start gap-2 break-words",
|
|
171475
|
+
role: "alert",
|
|
171476
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
171477
|
+
className: "mt-0.5 h-3.5 w-3.5 shrink-0",
|
|
171478
|
+
"aria-hidden": true
|
|
171479
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171480
|
+
className: "min-w-0 break-all",
|
|
171481
|
+
children: error ?? report?.contractError ?? schemaDiagnostic ?? report?.stderr.trim() ?? "The archived validation command failed."
|
|
171482
|
+
})]
|
|
171483
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
|
|
171484
|
+
pending,
|
|
171485
|
+
label: "Rerun",
|
|
171486
|
+
onRun: () => void run()
|
|
171487
|
+
})]
|
|
171488
|
+
})
|
|
171489
|
+
});
|
|
171490
|
+
}
|
|
171491
|
+
const validation = validationReport;
|
|
171492
|
+
const failed = validation.summary.totals.failed;
|
|
171493
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvidenceDisclosure, {
|
|
171494
|
+
title: "Archived validation",
|
|
171495
|
+
summary: `${validation.summary.totals.passed} passed · ${failed} failed`,
|
|
171496
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171497
|
+
className: "space-y-3",
|
|
171498
|
+
children: [
|
|
171499
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
|
|
171500
|
+
className: "@[32rem]:grid-cols-[auto_minmax(0,1fr)] grid min-w-0 gap-x-3 gap-y-1",
|
|
171501
|
+
children: [
|
|
171502
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
171503
|
+
className: "text-muted-foreground",
|
|
171504
|
+
children: "Root"
|
|
171505
|
+
}),
|
|
171506
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
|
|
171507
|
+
className: "min-w-0 break-all font-mono",
|
|
171508
|
+
children: validation.root.path
|
|
171509
|
+
}),
|
|
171510
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
171511
|
+
className: "text-muted-foreground",
|
|
171512
|
+
children: "Exit"
|
|
171513
|
+
}),
|
|
171514
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: report?.exitCode ?? "unknown" }),
|
|
171515
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
171516
|
+
className: "text-muted-foreground",
|
|
171517
|
+
children: "Totals"
|
|
171518
|
+
}),
|
|
171519
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dd", { children: [
|
|
171520
|
+
validation.summary.totals.passed,
|
|
171521
|
+
" passed · ",
|
|
171522
|
+
failed,
|
|
171523
|
+
" failed ·",
|
|
171524
|
+
" ",
|
|
171525
|
+
validation.summary.totals.items,
|
|
171526
|
+
" archived changes"
|
|
171527
|
+
] })
|
|
171528
|
+
]
|
|
171529
|
+
}),
|
|
171530
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171531
|
+
className: "space-y-2",
|
|
171532
|
+
children: validation.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171533
|
+
className: "border-border/60 rounded border p-2",
|
|
171534
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171535
|
+
className: "flex min-w-0 items-center gap-2",
|
|
171536
|
+
children: [item.valid ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleCheck, {
|
|
171537
|
+
className: "h-3.5 w-3.5 shrink-0 text-emerald-600",
|
|
171538
|
+
"aria-hidden": true
|
|
171539
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriangleAlert, {
|
|
171540
|
+
className: "h-3.5 w-3.5 shrink-0 text-amber-600",
|
|
171541
|
+
"aria-hidden": true
|
|
171542
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
171543
|
+
className: "min-w-0 break-all font-mono text-[11px]",
|
|
171544
|
+
children: item.id
|
|
171545
|
+
})]
|
|
171546
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171547
|
+
className: "mt-1",
|
|
171548
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IssueList, { issues: item.issues })
|
|
171549
|
+
})]
|
|
171550
|
+
}, item.id))
|
|
171551
|
+
}),
|
|
171552
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunButton, {
|
|
171553
|
+
pending,
|
|
171554
|
+
label: "Rerun",
|
|
171555
|
+
onRun: () => void run()
|
|
171556
|
+
})
|
|
171557
|
+
]
|
|
171558
|
+
})
|
|
171559
|
+
});
|
|
171560
|
+
}
|
|
171036
171561
|
//#endregion
|
|
171037
171562
|
//#region src/components/change-context-summary.tsx
|
|
171038
171563
|
/**
|
|
171039
|
-
* Orthogonal intents (
|
|
171564
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
171040
171565
|
* 1. Project compact Schema, artifact progress, Root, Store, and Reference subtitle badges.
|
|
171041
|
-
* 2.
|
|
171042
|
-
* 3.
|
|
171566
|
+
* 2. Carry the Apply instruction count as one subtitle badge — the progress authority.
|
|
171567
|
+
* 3. Preserve current, retained, unavailable, and static authority distinctions.
|
|
171568
|
+
* 4. Keep Reference failures directly visible without owning subscriptions or mutations.
|
|
171043
171569
|
*
|
|
171044
171570
|
* Original request (2026-08-03): keep only necessary Change evidence in the default decision plane.
|
|
171045
171571
|
* Owner correction (2026-08-03): unify Change scan Tooltips in the subtitle and keep failures below the Header.
|
|
171572
|
+
* Original request (2026-08-15): Owner walkthrough: merge Apply progress into the subtitle badge row.
|
|
171573
|
+
* Original request (2026-08-15): 刷新/解析中的 lifecycle 锁收敛为副标题行内的 shiny 徽章 + Tooltip。
|
|
171046
171574
|
*/
|
|
171047
171575
|
function summarizeReferences(references) {
|
|
171048
171576
|
return references.reduce((counts, reference) => {
|
|
@@ -171063,7 +171591,7 @@ function referenceErrorLabels(references) {
|
|
|
171063
171591
|
});
|
|
171064
171592
|
}
|
|
171065
171593
|
/** Compact source-attributed facts that share the Change Header subtitle. */
|
|
171066
|
-
function ChangeContextSummary({ status, referenceEvidence }) {
|
|
171594
|
+
function ChangeContextSummary({ status, referenceEvidence, applyInstructionProgress, statusRefreshing = null, rootChecking = null }) {
|
|
171067
171595
|
const provenance = status.provenance;
|
|
171068
171596
|
const references = referenceEvidence.state === "unavailable" ? null : referenceEvidence.references;
|
|
171069
171597
|
const referenceCounts = references ? summarizeReferences(references) : null;
|
|
@@ -171089,6 +171617,7 @@ function ChangeContextSummary({ status, referenceEvidence }) {
|
|
|
171089
171617
|
" artifacts"
|
|
171090
171618
|
]
|
|
171091
171619
|
}),
|
|
171620
|
+
applyInstructionProgress ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ApplyProgressBadge, { applyInstructionProgress }) : null,
|
|
171092
171621
|
provenance.kind === "static" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InformationBadge, {
|
|
171093
171622
|
ariaLabel: "Static Change context has no live backend provenance",
|
|
171094
171623
|
tooltip: "CLI Change context is unavailable in this static snapshot.",
|
|
@@ -171121,7 +171650,15 @@ function ChangeContextSummary({ status, referenceEvidence }) {
|
|
|
171121
171650
|
ariaLabel: "Reference evidence unavailable",
|
|
171122
171651
|
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.",
|
|
171123
171652
|
children: "References unavailable"
|
|
171124
|
-
})
|
|
171653
|
+
}),
|
|
171654
|
+
rootChecking ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShinyStatusBadge, {
|
|
171655
|
+
label: rootChecking.label,
|
|
171656
|
+
message: rootChecking.message
|
|
171657
|
+
}) : null,
|
|
171658
|
+
statusRefreshing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShinyStatusBadge, {
|
|
171659
|
+
label: statusRefreshing.label,
|
|
171660
|
+
message: statusRefreshing.message
|
|
171661
|
+
}) : null
|
|
171125
171662
|
]
|
|
171126
171663
|
});
|
|
171127
171664
|
}
|
|
@@ -171602,29 +172139,39 @@ function OperationInputsDialogAction({ title, context, operationGuidance }) {
|
|
|
171602
172139
|
//#endregion
|
|
171603
172140
|
//#region src/components/root-action-notice.tsx
|
|
171604
172141
|
/**
|
|
171605
|
-
* Orthogonal intents (updated 2026-
|
|
171606
|
-
* 1. Render root-action
|
|
171607
|
-
* 2.
|
|
171608
|
-
* 3. Keep
|
|
172142
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
172143
|
+
* 1. Render root-action blocked states with CLI-owned evidence as direct alerts.
|
|
172144
|
+
* 2. Render root-action checking states as one inline shiny badge for header/status rows.
|
|
172145
|
+
* 3. Keep blocker meaning direct while placing verbose CLI evidence in shared indirect space.
|
|
172146
|
+
* 4. Keep the notice reusable across OPSX compose and direct-action surfaces.
|
|
171609
172147
|
*
|
|
171610
172148
|
* Original request (2026-07-15): "Show CLI-owned failure evidence when root selection fails."
|
|
171611
172149
|
* Original request (2026-07-28): supporting 6.x evidence should use Badge + Tooltip or Accordion.
|
|
172150
|
+
* Original request (2026-08-15): 刷新/解析中的块级 Alert 改为 Animated Shiny Text + Tooltip。
|
|
171612
172151
|
*/
|
|
171613
|
-
/**
|
|
172152
|
+
/**
|
|
172153
|
+
* Normal lifecycle (resolving/refreshing) as visual language — one inline shiny badge
|
|
172154
|
+
* with no layout block. The complete lock reason stays available on hover/keyboard
|
|
172155
|
+
* focus via the Tooltip and the hidden polite live region.
|
|
172156
|
+
*/
|
|
172157
|
+
function RootCheckingBadge({ state }) {
|
|
172158
|
+
if (state.status !== "checking") return null;
|
|
172159
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShinyStatusBadge, {
|
|
172160
|
+
label: state.title,
|
|
172161
|
+
message: state.message
|
|
172162
|
+
});
|
|
172163
|
+
}
|
|
172164
|
+
/** Render objective failure evidence that locks root-dependent actions; null otherwise. */
|
|
171614
172165
|
function RootActionNotice({ state }) {
|
|
171615
|
-
if (state.status
|
|
171616
|
-
const checking = state.status === "checking";
|
|
172166
|
+
if (state.status !== "blocked") return null;
|
|
171617
172167
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171618
|
-
role:
|
|
171619
|
-
"aria-live":
|
|
171620
|
-
className:
|
|
172168
|
+
role: "alert",
|
|
172169
|
+
"aria-live": "assertive",
|
|
172170
|
+
className: "border-destructive/40 bg-destructive/10 text-destructive rounded-md border p-3 text-sm",
|
|
171621
172171
|
children: [
|
|
171622
172172
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171623
172173
|
className: "flex items-center gap-2 font-medium",
|
|
171624
|
-
children: [
|
|
171625
|
-
className: "h-4 w-4 animate-spin",
|
|
171626
|
-
"aria-hidden": true
|
|
171627
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleAlert, {
|
|
172174
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleAlert, {
|
|
171628
172175
|
className: "h-4 w-4",
|
|
171629
172176
|
"aria-hidden": true
|
|
171630
172177
|
}), state.title]
|
|
@@ -171664,6 +172211,7 @@ function RootActionNotice({ state }) {
|
|
|
171664
172211
|
* Original request (2026-08-01): preserve OpenSpec 1.7 Apply operation inputs end to end.
|
|
171665
172212
|
* Original request (2026-08-03): move complete Change evidence into a dedicated tab page.
|
|
171666
172213
|
* Owner correction (2026-08-03): move Actions inline with the title, unify subtitle badges, and localize unavailable Tooltips.
|
|
172214
|
+
* Original request (2026-08-15): 刷新/解析中状态收敛为副标题行内的 shiny 徽章,不再占据 statusRegion 块。
|
|
171667
172215
|
*/
|
|
171668
172216
|
function ChangeView() {
|
|
171669
172217
|
const { changeId } = useParams({ from: "/changes/$changeId" });
|
|
@@ -171737,13 +172285,16 @@ function ChangeView() {
|
|
|
171737
172285
|
id: "evidence",
|
|
171738
172286
|
label: "Evidence",
|
|
171739
172287
|
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileSearch, { className: "h-4 w-4" }),
|
|
171740
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
171741
|
-
|
|
171742
|
-
|
|
172288
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
172289
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col",
|
|
172290
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeEvidencePanel, {
|
|
172291
|
+
status,
|
|
172292
|
+
referenceEvidence
|
|
172293
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArchivedValidationEvidence, {})]
|
|
171743
172294
|
})
|
|
171744
172295
|
}] : [], [referenceEvidence, status]);
|
|
171745
172296
|
const hasReferenceFailures = referenceEvidence.state !== "unavailable" && referenceEvidence.references.some((reference) => reference.status.some((diagnostic) => diagnostic.severity === "error"));
|
|
171746
|
-
const hasDirectStatus =
|
|
172297
|
+
const hasDirectStatus = Boolean(error) || rootAction.status === "blocked" || hasReferenceFailures || Boolean(applyInstructions?.applyInstructionProgress.divergence);
|
|
171747
172298
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OpsxEntityDetailView, {
|
|
171748
172299
|
entityId: changeId,
|
|
171749
172300
|
sharedFamily: "changes",
|
|
@@ -171753,7 +172304,16 @@ function ChangeView() {
|
|
|
171753
172304
|
title: status?.changeName,
|
|
171754
172305
|
subtitle: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeContextSummary, {
|
|
171755
172306
|
status,
|
|
171756
|
-
referenceEvidence
|
|
172307
|
+
referenceEvidence,
|
|
172308
|
+
applyInstructionProgress: applyInstructions?.applyInstructionProgress ?? null,
|
|
172309
|
+
statusRefreshing: statusCurrent ? null : {
|
|
172310
|
+
label: "Status refreshing",
|
|
172311
|
+
message: statusAuthorityMessage ?? ""
|
|
172312
|
+
},
|
|
172313
|
+
rootChecking: rootAction.status === "checking" ? {
|
|
172314
|
+
label: rootAction.title,
|
|
172315
|
+
message: rootAction.message
|
|
172316
|
+
} : null
|
|
171757
172317
|
}) : void 0,
|
|
171758
172318
|
headerActions: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeCommandBar, {
|
|
171759
172319
|
status,
|
|
@@ -171791,15 +172351,6 @@ function ChangeView() {
|
|
|
171791
172351
|
statusRegion: status && hasDirectStatus ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171792
172352
|
className: "flex min-w-0 flex-col gap-2",
|
|
171793
172353
|
children: [
|
|
171794
|
-
!statusCurrent && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
171795
|
-
role: "status",
|
|
171796
|
-
"aria-live": "polite",
|
|
171797
|
-
className: "border-border bg-muted/30 text-muted-foreground flex items-center gap-2 rounded-md border px-3 py-2 text-xs",
|
|
171798
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCw, {
|
|
171799
|
-
className: "h-3.5 w-3.5 shrink-0",
|
|
171800
|
-
"aria-hidden": true
|
|
171801
|
-
}), statusAuthorityMessage]
|
|
171802
|
-
}) : null,
|
|
171803
172354
|
error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
171804
172355
|
role: "alert",
|
|
171805
172356
|
"aria-live": "assertive",
|
|
@@ -171858,7 +172409,7 @@ var CONFIG_GUIDE_STAGE_META = {
|
|
|
171858
172409
|
//#region src/components/config/config-guide.tsx
|
|
171859
172410
|
var ConfigGuideContext = (0, import_react.createContext)(null);
|
|
171860
172411
|
(0, import_react.lazy)(async () => {
|
|
171861
|
-
return { default: (await import("./config-guide-presentation-
|
|
172412
|
+
return { default: (await import("./config-guide-presentation-CmUNOJoP.js")).ConfigGuidePresentationLayer };
|
|
171862
172413
|
});
|
|
171863
172414
|
/** Access the root-owned adaptive Guide runtime. */
|
|
171864
172415
|
function useConfigGuide() {
|
|
@@ -173623,6 +174174,7 @@ function ActiveRootConfigSection({ isStatic }) {
|
|
|
173623
174174
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
173624
174175
|
className: "flex flex-wrap items-center justify-end gap-2",
|
|
173625
174176
|
children: [
|
|
174177
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootCheckingBadge, { state: rootAction }),
|
|
173626
174178
|
(config.exists || isEditing) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
173627
174179
|
role: "tablist",
|
|
173628
174180
|
"aria-label": "Active Root editor mode",
|
|
@@ -174616,19 +175168,23 @@ function ConfigSchemaWorkspace({ onNavigate, schemaId }) {
|
|
|
174616
175168
|
]
|
|
174617
175169
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
174618
175170
|
className: "flex items-center gap-2",
|
|
174619
|
-
children: [
|
|
174620
|
-
|
|
174621
|
-
|
|
174622
|
-
|
|
174623
|
-
|
|
174624
|
-
|
|
174625
|
-
|
|
174626
|
-
|
|
174627
|
-
|
|
174628
|
-
|
|
174629
|
-
|
|
174630
|
-
|
|
174631
|
-
|
|
175171
|
+
children: [
|
|
175172
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootCheckingBadge, { state: rootAction }),
|
|
175173
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
175174
|
+
type: "button",
|
|
175175
|
+
onClick: handleAddSchema,
|
|
175176
|
+
disabled: !schemaCanEdit || createSchemaMutation.isPending,
|
|
175177
|
+
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",
|
|
175178
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Plus, { className: "h-3.5 w-3.5" }), "Add"]
|
|
175179
|
+
}),
|
|
175180
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
175181
|
+
type: "button",
|
|
175182
|
+
onClick: handleDeleteSchema,
|
|
175183
|
+
disabled: !schemaCanEdit || deleteSchemaMutation.isPending,
|
|
175184
|
+
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",
|
|
175185
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trash2, { className: "h-3.5 w-3.5" }), "Delete"]
|
|
175186
|
+
})
|
|
175187
|
+
]
|
|
174632
175188
|
})]
|
|
174633
175189
|
}),
|
|
174634
175190
|
!isStatic && rootAction.disabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootActionNotice, { state: rootAction }) : null,
|
|
@@ -176874,14 +177430,15 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
|
|
|
176874
177430
|
//#endregion
|
|
176875
177431
|
//#region src/routes/dashboard.tsx
|
|
176876
177432
|
/**
|
|
176877
|
-
* Orthogonal intents (updated 2026-
|
|
177433
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
176878
177434
|
* 1. Render independent Dashboard projections inside stable region-owned Pending geometry.
|
|
176879
177435
|
* 2. Keep Dashboard-owned readonly Code Git refresh bound to rendered provenance and separate from Planning-root mutation authority.
|
|
176880
177436
|
* 3. Curate Code Git activity while preserving binding-token detail handoff provenance.
|
|
176881
|
-
* 4.
|
|
176882
|
-
* 5.
|
|
177437
|
+
* 4. Show only objective planning and artifact facts, never tracked task completion.
|
|
177438
|
+
* 5. Retain stable regional snapshots beside their own loading, updating, and error evidence.
|
|
176883
177439
|
*
|
|
176884
177440
|
* Original request (2026-07-16): "接下来,你来接手后续工作"
|
|
177441
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
176885
177442
|
* Derived requirement (2026-07-19): Checkpoint 6.11 preserves Git handoff and action provenance.
|
|
176886
177443
|
* Original request (2026-07-23): "现在页面数据的加载数据非常慢(比如dashboard页面、changes页面都要等待非常久,页面刷新后,似乎后台没有缓存一样,也要加载很久。"
|
|
176887
177444
|
* Original request (2026-07-27): "统一修复所有类似的问题(我们也没不多,各个页面都检查一下,特别是app 那边新增的页面)"
|
|
@@ -176895,6 +177452,7 @@ async function refreshDashboardGitSnapshot(reason, expectedBindingToken) {
|
|
|
176895
177452
|
* Original request (2026-07-31): "Code Git Snapshot 的 Other Worktrees 默认隐藏 (detached)。然后commitList这里默认显示5个就好"
|
|
176896
177453
|
* Original request (2026-07-31): "检查目前的这个 Code Git Snapshot,它非常慢,有时候甚至要十几秒"
|
|
176897
177454
|
* Owner correction (2026-07-31): Hidden documents pause the timer; visibility resumes the remaining delay or refreshes once when the absolute deadline elapsed.
|
|
177455
|
+
|
|
176898
177456
|
*/
|
|
176899
177457
|
var GIT_AUTO_REFRESH_OPTIONS = [
|
|
176900
177458
|
{
|
|
@@ -177351,8 +177909,6 @@ function Dashboard() {
|
|
|
177351
177909
|
children: [
|
|
177352
177910
|
summaryPending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeListSkeleton, { count: 3 }) : null,
|
|
177353
177911
|
!summaryPending && activeChanges.map((change) => {
|
|
177354
|
-
const progress = change.trackedTaskProgress;
|
|
177355
|
-
const taskPercent = progress.total > 0 ? Math.round(progress.completed / progress.total * 100) : 0;
|
|
177356
177912
|
const status = activeStatuses.find((item) => item.changeName === change.id);
|
|
177357
177913
|
const doneArtifacts = status?.artifacts.filter((artifact) => artifact.status === "done").length ?? 0;
|
|
177358
177914
|
const totalArtifacts = status?.artifacts.length ?? 0;
|
|
@@ -177360,11 +177916,12 @@ function Dashboard() {
|
|
|
177360
177916
|
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) ?? []);
|
|
177361
177917
|
const phase = classifyChangeWorkflowPhase({
|
|
177362
177918
|
hasStatus: Boolean(status),
|
|
177363
|
-
|
|
177364
|
-
trackedTaskPhase:
|
|
177365
|
-
trackedArtifactStatus
|
|
177919
|
+
isPlanningComplete: status?.isPlanningComplete ?? false,
|
|
177920
|
+
trackedTaskPhase: change.trackedTaskProgress.phase,
|
|
177921
|
+
trackedArtifactStatus,
|
|
177922
|
+
cliCompletedTasks: change.cliTaskSummary?.completedTasks ?? null
|
|
177366
177923
|
});
|
|
177367
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
177924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VTLink, {
|
|
177368
177925
|
to: "/changes/$changeId",
|
|
177369
177926
|
params: { changeId: change.id },
|
|
177370
177927
|
state: (prev) => ({
|
|
@@ -177385,71 +177942,29 @@ function Dashboard() {
|
|
|
177385
177942
|
entityId: change.id
|
|
177386
177943
|
}, "container"),
|
|
177387
177944
|
className: "hover:bg-muted/50 block min-w-0 px-4 py-3",
|
|
177388
|
-
children:
|
|
177389
|
-
|
|
177390
|
-
|
|
177391
|
-
|
|
177392
|
-
|
|
177393
|
-
|
|
177394
|
-
|
|
177395
|
-
|
|
177396
|
-
|
|
177397
|
-
|
|
177398
|
-
|
|
177399
|
-
|
|
177400
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177401
|
-
className: "text-muted-foreground truncate text-xs",
|
|
177402
|
-
children: [change.updatedAt > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [formatRelativeTime(change.updatedAt), " · "] }), change.id]
|
|
177403
|
-
})]
|
|
177404
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177405
|
-
className: "shrink-0 text-right text-sm",
|
|
177406
|
-
children: [
|
|
177407
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
177408
|
-
tone: "custom",
|
|
177409
|
-
size: "sm",
|
|
177410
|
-
shape: "box",
|
|
177411
|
-
className: `border ${phase.toneClass}`,
|
|
177412
|
-
children: phase.label
|
|
177413
|
-
}),
|
|
177414
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177415
|
-
className: "font-medium",
|
|
177416
|
-
children: [
|
|
177417
|
-
progress.completed,
|
|
177418
|
-
"/",
|
|
177419
|
-
progress.total
|
|
177420
|
-
]
|
|
177421
|
-
}),
|
|
177422
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
177423
|
-
className: "text-muted-foreground text-xs",
|
|
177424
|
-
children: "tasks"
|
|
177425
|
-
})
|
|
177426
|
-
]
|
|
177427
|
-
})]
|
|
177428
|
-
}),
|
|
177429
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
177430
|
-
className: "bg-muted h-1.5 rounded-full",
|
|
177431
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
177432
|
-
className: "bg-primary h-full rounded-full transition-all",
|
|
177433
|
-
style: { width: `${taskPercent}%` }
|
|
177434
|
-
})
|
|
177435
|
-
}),
|
|
177436
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177437
|
-
className: "text-muted-foreground mt-2 flex min-w-0 flex-wrap items-center justify-between gap-2 text-xs",
|
|
177438
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
177439
|
-
className: "shrink-0",
|
|
177440
|
-
children: [taskPercent, "% task completion"]
|
|
177441
|
-
}), status ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
177442
|
-
className: "min-w-0 truncate text-right",
|
|
177945
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
177946
|
+
className: "flex min-w-0 items-center gap-3",
|
|
177947
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRow, {
|
|
177948
|
+
changeId: change.id,
|
|
177949
|
+
name: change.name,
|
|
177950
|
+
phase,
|
|
177951
|
+
updatedAt: change.updatedAt,
|
|
177952
|
+
formatTime: formatRelativeTime,
|
|
177953
|
+
progressRatio: change.cliTaskSummary && change.cliTaskSummary.totalTasks > 0 ? change.cliTaskSummary.completedTasks / change.cliTaskSummary.totalTasks : null,
|
|
177954
|
+
className: "min-w-0 flex-1",
|
|
177955
|
+
subtitle: status ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
177956
|
+
title: "Task counts reported by the OpenSpec CLI for this Change.",
|
|
177443
177957
|
children: [
|
|
177444
177958
|
doneArtifacts,
|
|
177445
177959
|
"/",
|
|
177446
177960
|
totalArtifacts,
|
|
177447
177961
|
" artifacts · ",
|
|
177448
|
-
status.schemaName
|
|
177962
|
+
status.schemaName,
|
|
177963
|
+
change.cliTaskSummary ? ` · Tasks ${change.cliTaskSummary.completedTasks}/${change.cliTaskSummary.totalTasks}` : ""
|
|
177449
177964
|
]
|
|
177450
|
-
}) :
|
|
177451
|
-
})
|
|
177452
|
-
|
|
177965
|
+
}) : "Artifacts status unavailable"
|
|
177966
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChangeRowChevron, {})]
|
|
177967
|
+
})
|
|
177453
177968
|
}, change.id);
|
|
177454
177969
|
}),
|
|
177455
177970
|
!summaryPending && !hasChanges && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|