create-principles-disciple 1.144.24 → 1.144.26
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/_release/product-identity.json +2 -2
- package/codex-adapter/dist/pd-hook.js +84 -9
- package/codex-adapter/package.json +1 -1
- package/console/dist/ui/App.js +19 -3
- package/console/dist/ui/components/layout/app-sidebar.d.ts +11 -0
- package/console/dist/ui/components/layout/app-sidebar.js +60 -7
- package/console/dist/ui/components/ui/sheet.js +2 -1
- package/console/dist/ui/i18n/en.json +66 -5
- package/console/dist/ui/i18n/index.js +11 -0
- package/console/dist/ui/i18n/zh-CN.json +66 -5
- package/console/dist/ui/pages/control-center/ControlCenterPage.js +4 -2
- package/console/dist/ui/pages/control-center/RuntimeProfileManager.js +3 -3
- package/console/dist/ui/pages/focus/FocusPage.d.ts +92 -0
- package/console/dist/ui/pages/focus/FocusPage.js +139 -8
- package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +4 -2
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +54 -16
- package/console/dist/ui/pages/settings/UpdatePage.js +1 -1
- package/console/dist/web/assets/app.css +109 -20
- package/console/dist/web/assets/app.js +59 -58
- package/core/dist/principle-tree-ledger.d.ts +20 -0
- package/core/dist/principle-tree-ledger.d.ts.map +1 -1
- package/core/dist/principle-tree-ledger.js +13 -9
- package/core/dist/principle-tree-ledger.js.map +1 -1
- package/core/dist/runtime-v2/activation/activation-dispatcher.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/activation-dispatcher.js +10 -3
- package/core/dist/runtime-v2/activation/activation-dispatcher.js.map +1 -1
- package/core/dist/runtime-v2/activation/ledger-identity.d.ts +12 -3
- package/core/dist/runtime-v2/activation/ledger-identity.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/ledger-identity.js +18 -3
- package/core/dist/runtime-v2/activation/ledger-identity.js.map +1 -1
- package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts +8 -0
- package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js +11 -1
- package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +61 -2
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +68 -3
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.js +5 -0
- package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +18 -0
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.js +7 -0
- package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +36 -2
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js +31 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +52 -12
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +180 -48
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/repair-replay-resolver.d.ts +8 -0
- package/core/dist/runtime-v2/internalization/repair-replay-resolver.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/repair-replay-resolver.js +12 -0
- package/core/dist/runtime-v2/internalization/repair-replay-resolver.js.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.d.ts +4 -0
- package/core/dist/runtime-v2/internalization/scribe-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.js +13 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.js.map +1 -1
- package/core/dist/telemetry-event.d.ts.map +1 -1
- package/core/dist/telemetry-event.js +3 -2
- package/core/dist/telemetry-event.js.map +1 -1
- package/core/package.json +1 -1
- package/host-runtime/dist/internalization-consumer-cycle.js +6 -0
- package/host-runtime/package.json +1 -1
- package/package.json +1 -1
- package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-retry.js +9 -3
- package/pd-cli/dist/commands/pain-retry.js.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js +3 -0
- package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js +6 -0
- package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +449 -440
- package/release-manager/package.json +1 -1
|
@@ -280,7 +280,9 @@ function readinessTagClasses(readiness) {
|
|
|
280
280
|
case "needs_setup":
|
|
281
281
|
return base.replace("border-line", "border-amber/35").replace("text-ink-3", "text-amber");
|
|
282
282
|
case "not_ready":
|
|
283
|
-
|
|
283
|
+
// SPEC-PD-UIUX-001 R5: bare `red` utilities have no matching theme token
|
|
284
|
+
// (silently unstyled) — use the registered danger token.
|
|
285
|
+
return base.replace("border-line", "border-danger/35").replace("text-ink-3", "text-danger");
|
|
284
286
|
default:
|
|
285
287
|
return base;
|
|
286
288
|
}
|
|
@@ -384,7 +386,7 @@ function AdvancedDiagnostics({ config, }) {
|
|
|
384
386
|
const grouped = groupAgentsByReadiness(diagnostics);
|
|
385
387
|
return (_jsxs("details", { className: "group", children: [_jsx("summary", { className: "text-ink-3 text-[13px] cursor-pointer hover:text-ink-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.controlCenter.advancedDiagnostics") }), _jsxs("div", { className: "mt-4 space-y-5", children: [_jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.features") }), _jsx("div", { className: "bg-surface/60 border border-line rounded-[6px] px-3 py-2", children: config.features.length === 0 ? (_jsx("span", { className: "text-ink-4 text-[13px]", children: "\u2014" })) : (_jsx("div", { className: "space-y-1", children: config.features.map((f) => (_jsxs("div", { className: "flex items-center gap-2 text-[13px]", children: [_jsx("span", { className: "text-ink-2", children: enumLabel('featureId', f.id, t) }), _jsx("span", { className: "text-ink-4", children: "\u00B7" }), _jsx("span", { className: "text-ink-3", children: enumLabel('featureCategory', f.category, t) }), _jsx("span", { className: "text-ink-4", children: "\u00B7" }), _jsx("span", { className: f.enabled ? "text-ink-2" : "text-ink-4 line-through", children: f.enabled
|
|
386
388
|
? t("pages.controlCenter.on")
|
|
387
|
-
: t("pages.controlCenter.off") })] }, f.id))) })) })] }), _jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.runtimeProfiles") }), _jsx("div", { className: "bg-surface/60 border border-line rounded-[6px] px-3 py-2", children: config.runtimeProfiles.length === 0 ? (_jsx("span", { className: "text-ink-4 text-[13px]", children: "\u2014" })) : (_jsx("div", { className: "space-y-1", children: config.runtimeProfiles.map((p) => (_jsxs("div", { className: "flex items-center gap-2 text-[13px]", children: [_jsx("span", { className: "text-ink-2", children: p.label }), _jsx("span", { className: "text-ink-4", children: "\u00B7" }), _jsx("span", { className: "text-ink-3", children: p.type }), _jsx("span", { className: readinessTagClasses(p.readiness), children: enumLabel('readiness', p.readiness, t) })] }, p.id))) })) })] }), config.warnings.length > 0 && (_jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.warnings") }), _jsx("div", { className: "bg-surface/60 border border-amber/20 border-l-2 border-l-amber rounded-[6px] px-3 py-2", children: _jsx("ul", { className: "space-y-1", children: config.warnings.map((w, i) => (_jsx("li", { className: "text-ink-2 text-[13px]", children: w }, i))) }) })] })), config.errors && config.errors.length > 0 && (_jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.configErrors") }), _jsx("div", { className: "bg-surface/60 border border-
|
|
389
|
+
: t("pages.controlCenter.off") })] }, f.id))) })) })] }), _jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.runtimeProfiles") }), _jsx("div", { className: "bg-surface/60 border border-line rounded-[6px] px-3 py-2", children: config.runtimeProfiles.length === 0 ? (_jsx("span", { className: "text-ink-4 text-[13px]", children: "\u2014" })) : (_jsx("div", { className: "space-y-1", children: config.runtimeProfiles.map((p) => (_jsxs("div", { className: "flex items-center gap-2 text-[13px]", children: [_jsx("span", { className: "text-ink-2", children: p.label }), _jsx("span", { className: "text-ink-4", children: "\u00B7" }), _jsx("span", { className: "text-ink-3", children: p.type }), _jsx("span", { className: readinessTagClasses(p.readiness), children: enumLabel('readiness', p.readiness, t) })] }, p.id))) })) })] }), config.warnings.length > 0 && (_jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.warnings") }), _jsx("div", { className: "bg-surface/60 border border-amber/20 border-l-2 border-l-amber rounded-[6px] px-3 py-2", children: _jsx("ul", { className: "space-y-1", children: config.warnings.map((w, i) => (_jsx("li", { className: "text-ink-2 text-[13px]", children: w }, i))) }) })] })), config.errors && config.errors.length > 0 && (_jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.configErrors") }), _jsx("div", { className: "bg-surface/60 border border-danger/20 border-l-2 border-l-danger rounded-[6px] px-3 py-2", children: _jsx("ul", { className: "space-y-2", children: config.errors.map((e, i) => (_jsxs("li", { className: "text-[13px]", children: [_jsx("span", { className: "text-ink font-medium", children: e.path }), _jsx("span", { className: "text-ink-4", children: " \u2014 " }), _jsx("span", { className: "text-ink-2", children: e.reason }), _jsxs("div", { className: "text-ink-3 text-[12px] mt-0.5", children: ["\u2192 ", e.nextAction] })] }, i))) }) })] })), _jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.controlCenter.readinessLabel") }), _jsx("div", { className: "bg-surface/60 border border-line rounded-[6px] px-3 py-2 space-y-2", children: Object.keys(grouped).map((status) => {
|
|
388
390
|
const validatedStatus = validateReadinessStatus(status);
|
|
389
391
|
if (validatedStatus === null)
|
|
390
392
|
return null;
|
|
@@ -213,7 +213,7 @@ export function RuntimeProfileManager({ profiles, defaultRuntimeId, onMutated, }
|
|
|
213
213
|
const v = e.target.value;
|
|
214
214
|
const typed = v === "pi-ai" ? "pi-ai" : "openclaw";
|
|
215
215
|
handleFieldChange("type", typed);
|
|
216
|
-
}, disabled: mode === "edit" || submitting, className: inputClass, children: [_jsx("option", { value: "openclaw", children: t("pages.controlCenter.profiles.typeOpenclaw") }), _jsx("option", { value: "pi-ai", children: t("pages.controlCenter.profiles.typePiAi") })] }), mode === "edit" && (_jsx("p", { className: hintClass, children: t("pages.controlCenter.profiles.fieldIdHint") }))] }), form.type === "pi-ai" && (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-provider", children: t("pages.controlCenter.profiles.fieldProvider") }), _jsx("input", { id: "rpf-provider", type: "text", value: form.provider, onChange: (e) => handleFieldChange("provider", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldProviderPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-model", children: t("pages.controlCenter.profiles.fieldModel") }), _jsx("input", { id: "rpf-model", type: "text", value: form.model, onChange: (e) => handleFieldChange("model", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldModelPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-apikeyenv", children: t("pages.controlCenter.profiles.fieldApiKeyEnv") }), _jsx("input", { id: "rpf-apikeyenv", type: "text", value: form.apiKeyEnv, onChange: (e) => handleFieldChange("apiKeyEnv", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldApiKeyEnvPlaceholder"), className: cn(inputClass, "font-mono"), autoComplete: "off", spellCheck: false }), _jsx("p", { className: hintClass, children: t("pages.controlCenter.profiles.fieldApiKeyEnvHint") })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-baseurl", children: t("pages.controlCenter.profiles.fieldBaseUrl") }), _jsx("input", { id: "rpf-baseurl", type: "text", value: form.baseUrl, onChange: (e) => handleFieldChange("baseUrl", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldBaseUrlPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] })] })), form.type === "openclaw" && (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-source", children: t("pages.controlCenter.profiles.fieldSource") }), _jsx("input", { id: "rpf-source", type: "text", value: form.source, onChange: (e) => handleFieldChange("source", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldSourcePlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-provider-oc", children: t("pages.controlCenter.profiles.fieldProvider") }), _jsx("input", { id: "rpf-provider-oc", type: "text", value: form.provider, onChange: (e) => handleFieldChange("provider", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldProviderPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-model-oc", children: t("pages.controlCenter.profiles.fieldModel") }), _jsx("input", { id: "rpf-model-oc", type: "text", value: form.model, onChange: (e) => handleFieldChange("model", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldModelPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] })] }))] }), formError !== null && (_jsx("div", { className: "mt-3 px-[12px] py-[8px] border border-
|
|
216
|
+
}, disabled: mode === "edit" || submitting, className: inputClass, children: [_jsx("option", { value: "openclaw", children: t("pages.controlCenter.profiles.typeOpenclaw") }), _jsx("option", { value: "pi-ai", children: t("pages.controlCenter.profiles.typePiAi") })] }), mode === "edit" && (_jsx("p", { className: hintClass, children: t("pages.controlCenter.profiles.fieldIdHint") }))] }), form.type === "pi-ai" && (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-provider", children: t("pages.controlCenter.profiles.fieldProvider") }), _jsx("input", { id: "rpf-provider", type: "text", value: form.provider, onChange: (e) => handleFieldChange("provider", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldProviderPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-model", children: t("pages.controlCenter.profiles.fieldModel") }), _jsx("input", { id: "rpf-model", type: "text", value: form.model, onChange: (e) => handleFieldChange("model", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldModelPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-apikeyenv", children: t("pages.controlCenter.profiles.fieldApiKeyEnv") }), _jsx("input", { id: "rpf-apikeyenv", type: "text", value: form.apiKeyEnv, onChange: (e) => handleFieldChange("apiKeyEnv", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldApiKeyEnvPlaceholder"), className: cn(inputClass, "font-mono"), autoComplete: "off", spellCheck: false }), _jsx("p", { className: hintClass, children: t("pages.controlCenter.profiles.fieldApiKeyEnvHint") })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-baseurl", children: t("pages.controlCenter.profiles.fieldBaseUrl") }), _jsx("input", { id: "rpf-baseurl", type: "text", value: form.baseUrl, onChange: (e) => handleFieldChange("baseUrl", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldBaseUrlPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] })] })), form.type === "openclaw" && (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-source", children: t("pages.controlCenter.profiles.fieldSource") }), _jsx("input", { id: "rpf-source", type: "text", value: form.source, onChange: (e) => handleFieldChange("source", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldSourcePlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-provider-oc", children: t("pages.controlCenter.profiles.fieldProvider") }), _jsx("input", { id: "rpf-provider-oc", type: "text", value: form.provider, onChange: (e) => handleFieldChange("provider", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldProviderPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] }), _jsxs("div", { children: [_jsx("label", { className: labelClass, htmlFor: "rpf-model-oc", children: t("pages.controlCenter.profiles.fieldModel") }), _jsx("input", { id: "rpf-model-oc", type: "text", value: form.model, onChange: (e) => handleFieldChange("model", e.target.value), disabled: submitting, placeholder: t("pages.controlCenter.profiles.fieldModelPlaceholder"), className: inputClass, autoComplete: "off", spellCheck: false })] })] }))] }), formError !== null && (_jsx("div", { className: "mt-3 px-[12px] py-[8px] border border-danger/35 rounded-[4px] bg-danger/10 text-[12px] text-danger font-mono", children: formError })), _jsxs("div", { className: "mt-3 flex items-center gap-[8px]", children: [_jsx("button", { type: "submit", disabled: submitting, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: submitting
|
|
217
217
|
? mode === "create"
|
|
218
218
|
? t("pages.controlCenter.profiles.creating")
|
|
219
219
|
: t("pages.controlCenter.profiles.saving")
|
|
@@ -225,9 +225,9 @@ export function RuntimeProfileManager({ profiles, defaultRuntimeId, onMutated, }
|
|
|
225
225
|
setDeleteError(null);
|
|
226
226
|
}, disabled: mode !== "closed" ||
|
|
227
227
|
deleting ||
|
|
228
|
-
deleteTarget !== null, className: "text-[11.5px] px-[10px] py-[4px] rounded-[3px] border border-line bg-surface text-ink-3 hover:border-
|
|
228
|
+
deleteTarget !== null, className: "text-[11.5px] px-[10px] py-[4px] rounded-[3px] border border-line bg-surface text-ink-3 hover:border-danger/40 hover:text-danger transition-colors disabled:opacity-40 disabled:cursor-not-allowed", children: t("pages.controlCenter.profiles.deleteButton") })] })] }), isDeleteTarget && (_jsx("div", { className: "px-[16px] pb-[12px]", children: _jsxs("div", { className: "px-[12px] py-[10px] border border-danger rounded-[4px] bg-danger/10 text-[12px] text-ink-2 leading-[1.55]", children: [_jsx("div", { className: "font-medium", children: t("pages.controlCenter.profiles.deleteConfirmMessage", {
|
|
229
229
|
id: p.id,
|
|
230
|
-
}) }), isDefault && (_jsx("div", { className: "mt-1 text-ink-3", children: t("pages.controlCenter.profiles.sectionDescription") })), deleteError !== null && (_jsx("div", { className: "mt-2 font-mono text-[11.5px] text-
|
|
230
|
+
}) }), isDefault && (_jsx("div", { className: "mt-1 text-ink-3", children: t("pages.controlCenter.profiles.sectionDescription") })), deleteError !== null && (_jsx("div", { className: "mt-2 font-mono text-[11.5px] text-danger", children: deleteError })), _jsxs("div", { className: "mt-2 flex gap-[8px]", children: [_jsx("button", { type: "button", onClick: handleDeleteConfirm, disabled: deleting, className: "text-[11.5px] px-[12px] py-[4px] rounded-[3px] border border-transparent bg-danger text-paper font-medium hover:opacity-90 transition-opacity disabled:opacity-50 focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: deleting
|
|
231
231
|
? t("pages.controlCenter.profiles.deleting")
|
|
232
232
|
: t("pages.controlCenter.profiles.deleteConfirmAck") }), _jsx("button", { type: "button", onClick: handleDeleteCancel, disabled: deleting, className: "text-[11.5px] px-[12px] py-[4px] rounded-[3px] border border-line bg-transparent text-ink-3 hover:border-line-2 transition-colors disabled:opacity-50", children: t("pages.controlCenter.profiles.deleteConfirmCancel") })] })] }) }))] }, p.id));
|
|
233
233
|
})] }))] }));
|
|
@@ -22,6 +22,98 @@ export declare function summarizeDecisionResults(results: readonly DecisionResul
|
|
|
22
22
|
failureReason?: string;
|
|
23
23
|
successWarnings: string[];
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* SPEC-PD-UIUX-001 R2: how the owner-inbox display items map onto the Focus
|
|
27
|
+
* page after the reading-order rework. Pure display partitioning — no
|
|
28
|
+
* permission or lifecycle decisions happen here.
|
|
29
|
+
*
|
|
30
|
+
* - decision items whose principleId matches an on-screen action card are NOT
|
|
31
|
+
* duplicated as full cards (one primary action surface per object); the
|
|
32
|
+
* match uses the verified principleId association field, never titles;
|
|
33
|
+
* - unmatched decision items are preserved (with their own entry) — objects
|
|
34
|
+
* are never hidden for visual tidiness;
|
|
35
|
+
* - two different decisions of the same principle are never merged: each
|
|
36
|
+
* action card keeps its own object; this partition only affects the
|
|
37
|
+
* display-only inbox projection;
|
|
38
|
+
* - blocked items follow the inbox.attention semantics: 'individual' items
|
|
39
|
+
* render one card each, everything else gets one aggregate count;
|
|
40
|
+
* - historical unknowns stay an explanatory notice (not part of the todo
|
|
41
|
+
* count).
|
|
42
|
+
*/
|
|
43
|
+
export declare function partitionInboxForDisplay<T extends {
|
|
44
|
+
principleId: string;
|
|
45
|
+
inbox: {
|
|
46
|
+
group: string;
|
|
47
|
+
attention: string;
|
|
48
|
+
};
|
|
49
|
+
}>(inbox: {
|
|
50
|
+
groups: {
|
|
51
|
+
decision: T[];
|
|
52
|
+
blocked: T[];
|
|
53
|
+
recovery: T[];
|
|
54
|
+
};
|
|
55
|
+
historicalUnknown: {
|
|
56
|
+
count: number;
|
|
57
|
+
};
|
|
58
|
+
}, actionCardPrincipleIds: ReadonlySet<string>): {
|
|
59
|
+
unmatchedDecisions: T[];
|
|
60
|
+
blockedIndividual: T[];
|
|
61
|
+
blockedAggregate: T[];
|
|
62
|
+
recovery: T[];
|
|
63
|
+
pendingTotal: number;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* SPEC-PD-UIUX-001 R2 (Owner review round 2): the conclusion strip's headline
|
|
67
|
+
* and total must agree with the objects actually on screen and with the inbox
|
|
68
|
+
* response contract.
|
|
69
|
+
*
|
|
70
|
+
* Modes (display-only; no permission derivation):
|
|
71
|
+
* - 'unavailable' — inbox projection off (feature_disabled surfaces as
|
|
72
|
+
* ownerInbox===null with NO error) or the request failed: the pending count
|
|
73
|
+
* CANNOT be confirmed; never allClear.
|
|
74
|
+
* - 'degraded' — the inbox answered HTTP-success but carries
|
|
75
|
+
* `degraded: { reason, nextAction }` (e.g. principle ledger unreadable, the
|
|
76
|
+
* server then returns EMPTY groups): counts cannot be trusted; the strip
|
|
77
|
+
* shows the server's reason + nextAction and never allClear.
|
|
78
|
+
* - 'ok' — counts are trusted.
|
|
79
|
+
*
|
|
80
|
+
* Counting (S2): displayTotal = actionableCount + inbox pending items NOT
|
|
81
|
+
* already represented by an on-screen action card. The association is the
|
|
82
|
+
* verified principleId field (partition.unmatchedDecisions are inbox items
|
|
83
|
+
* WITHOUT a card). One inbox item matching N cards of the same principle
|
|
84
|
+
* counts the N cards (each is a distinct decision); disjoint sets sum.
|
|
85
|
+
*/
|
|
86
|
+
export declare function deriveConclusionDisplay(input: {
|
|
87
|
+
ownerInbox: {
|
|
88
|
+
groups: {
|
|
89
|
+
decision: unknown[];
|
|
90
|
+
};
|
|
91
|
+
degraded?: {
|
|
92
|
+
reason: string;
|
|
93
|
+
nextAction: string;
|
|
94
|
+
};
|
|
95
|
+
} | null;
|
|
96
|
+
ownerInboxError: string | null;
|
|
97
|
+
partition: {
|
|
98
|
+
pendingTotal: number;
|
|
99
|
+
unmatchedDecisions: unknown[];
|
|
100
|
+
} | null;
|
|
101
|
+
actionableCount: number;
|
|
102
|
+
}): {
|
|
103
|
+
mode: 'ok' | 'degraded' | 'unavailable';
|
|
104
|
+
displayTotal: number;
|
|
105
|
+
actionableCount: number;
|
|
106
|
+
degraded?: {
|
|
107
|
+
reason: string;
|
|
108
|
+
nextAction: string;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* SPEC-PD-UIUX-001 R2 (Owner review S3): EVERY conclusion branch must express
|
|
113
|
+
* governance readiness the same way — "actionable now" is only claimable when
|
|
114
|
+
* the actions are not locked. One matrix, one source.
|
|
115
|
+
*/
|
|
116
|
+
export declare function resolveConclusionActionableKey(mode: 'ok' | 'degraded' | 'unavailable', locked: boolean): string;
|
|
25
117
|
export interface OwnerConfigureCommand {
|
|
26
118
|
/** i18n key for the shell label, e.g. "pages.focus.experience.ownerGuide.cmdPowerShell". */
|
|
27
119
|
labelKey: string;
|
|
@@ -42,6 +42,93 @@ export function summarizeDecisionResults(results) {
|
|
|
42
42
|
successWarnings,
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* SPEC-PD-UIUX-001 R2: how the owner-inbox display items map onto the Focus
|
|
47
|
+
* page after the reading-order rework. Pure display partitioning — no
|
|
48
|
+
* permission or lifecycle decisions happen here.
|
|
49
|
+
*
|
|
50
|
+
* - decision items whose principleId matches an on-screen action card are NOT
|
|
51
|
+
* duplicated as full cards (one primary action surface per object); the
|
|
52
|
+
* match uses the verified principleId association field, never titles;
|
|
53
|
+
* - unmatched decision items are preserved (with their own entry) — objects
|
|
54
|
+
* are never hidden for visual tidiness;
|
|
55
|
+
* - two different decisions of the same principle are never merged: each
|
|
56
|
+
* action card keeps its own object; this partition only affects the
|
|
57
|
+
* display-only inbox projection;
|
|
58
|
+
* - blocked items follow the inbox.attention semantics: 'individual' items
|
|
59
|
+
* render one card each, everything else gets one aggregate count;
|
|
60
|
+
* - historical unknowns stay an explanatory notice (not part of the todo
|
|
61
|
+
* count).
|
|
62
|
+
*/
|
|
63
|
+
export function partitionInboxForDisplay(inbox, actionCardPrincipleIds) {
|
|
64
|
+
const blockedIndividual = inbox.groups.blocked.filter((item) => item.inbox.attention === "individual");
|
|
65
|
+
const blockedAggregate = inbox.groups.blocked.filter((item) => item.inbox.attention !== "individual");
|
|
66
|
+
const unmatchedDecisions = inbox.groups.decision.filter((item) => !actionCardPrincipleIds.has(item.principleId));
|
|
67
|
+
return {
|
|
68
|
+
unmatchedDecisions,
|
|
69
|
+
blockedIndividual,
|
|
70
|
+
blockedAggregate,
|
|
71
|
+
recovery: inbox.groups.recovery,
|
|
72
|
+
// 待处理口径: decision + blocked-individual + recovery (INV-01 lineage).
|
|
73
|
+
pendingTotal: inbox.groups.decision.length + blockedIndividual.length + inbox.groups.recovery.length,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* SPEC-PD-UIUX-001 R2 (Owner review round 2): the conclusion strip's headline
|
|
78
|
+
* and total must agree with the objects actually on screen and with the inbox
|
|
79
|
+
* response contract.
|
|
80
|
+
*
|
|
81
|
+
* Modes (display-only; no permission derivation):
|
|
82
|
+
* - 'unavailable' — inbox projection off (feature_disabled surfaces as
|
|
83
|
+
* ownerInbox===null with NO error) or the request failed: the pending count
|
|
84
|
+
* CANNOT be confirmed; never allClear.
|
|
85
|
+
* - 'degraded' — the inbox answered HTTP-success but carries
|
|
86
|
+
* `degraded: { reason, nextAction }` (e.g. principle ledger unreadable, the
|
|
87
|
+
* server then returns EMPTY groups): counts cannot be trusted; the strip
|
|
88
|
+
* shows the server's reason + nextAction and never allClear.
|
|
89
|
+
* - 'ok' — counts are trusted.
|
|
90
|
+
*
|
|
91
|
+
* Counting (S2): displayTotal = actionableCount + inbox pending items NOT
|
|
92
|
+
* already represented by an on-screen action card. The association is the
|
|
93
|
+
* verified principleId field (partition.unmatchedDecisions are inbox items
|
|
94
|
+
* WITHOUT a card). One inbox item matching N cards of the same principle
|
|
95
|
+
* counts the N cards (each is a distinct decision); disjoint sets sum.
|
|
96
|
+
*/
|
|
97
|
+
export function deriveConclusionDisplay(input) {
|
|
98
|
+
if (input.ownerInbox === null || input.ownerInboxError !== null || input.partition === null) {
|
|
99
|
+
return { mode: 'unavailable', displayTotal: input.actionableCount, actionableCount: input.actionableCount };
|
|
100
|
+
}
|
|
101
|
+
const matchedDecisions = input.ownerInbox.groups.decision.length - input.partition.unmatchedDecisions.length;
|
|
102
|
+
const uncoveredInboxPending = Math.max(0, input.partition.pendingTotal - matchedDecisions);
|
|
103
|
+
const base = {
|
|
104
|
+
actionableCount: input.actionableCount,
|
|
105
|
+
};
|
|
106
|
+
if (input.ownerInbox.degraded !== undefined) {
|
|
107
|
+
return {
|
|
108
|
+
mode: 'degraded',
|
|
109
|
+
displayTotal: input.actionableCount + uncoveredInboxPending,
|
|
110
|
+
...base,
|
|
111
|
+
degraded: input.ownerInbox.degraded,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
mode: 'ok',
|
|
116
|
+
displayTotal: input.actionableCount + uncoveredInboxPending,
|
|
117
|
+
...base,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* SPEC-PD-UIUX-001 R2 (Owner review S3): EVERY conclusion branch must express
|
|
122
|
+
* governance readiness the same way — "actionable now" is only claimable when
|
|
123
|
+
* the actions are not locked. One matrix, one source.
|
|
124
|
+
*/
|
|
125
|
+
export function resolveConclusionActionableKey(mode, locked) {
|
|
126
|
+
if (locked)
|
|
127
|
+
return "pages.focus.conclusion.actionableLocked";
|
|
128
|
+
if (mode === 'unavailable')
|
|
129
|
+
return "pages.focus.conclusion.actionableWithoutTotal";
|
|
130
|
+
return "pages.focus.conclusion.actionableUnlocked";
|
|
131
|
+
}
|
|
45
132
|
// ── i18n code mapping helpers ─────────────────────────────────────────────
|
|
46
133
|
/** Map a stateReasonCode to an i18n key, with optional interpolation params. */
|
|
47
134
|
function getStateReasonText(code, t, pendingReviewCount) {
|
|
@@ -600,6 +687,40 @@ export function FocusPage({ featureFlags }) {
|
|
|
600
687
|
: t(experienceData.readiness.authenticationMode !== "authenticated"
|
|
601
688
|
? "pages.focus.ownerDecision.actionsLockedAuth"
|
|
602
689
|
: "pages.focus.ownerDecision.actionsLockedIdentity");
|
|
690
|
+
// ── SPEC-PD-UIUX-001 R2: one primary action surface per decision object ──
|
|
691
|
+
// Matching uses the verified principleId association field (never titles).
|
|
692
|
+
// See partitionInboxForDisplay for the semantics.
|
|
693
|
+
const actionCardPrincipleIds = new Set();
|
|
694
|
+
for (const item of decisionItems) {
|
|
695
|
+
if (item.principleId !== undefined)
|
|
696
|
+
actionCardPrincipleIds.add(item.principleId);
|
|
697
|
+
}
|
|
698
|
+
for (const group of pendingGroups)
|
|
699
|
+
actionCardPrincipleIds.add(group.principleId);
|
|
700
|
+
const inboxPartition = ownerInbox !== null && ownerInboxError === null
|
|
701
|
+
? partitionInboxForDisplay(ownerInbox, actionCardPrincipleIds)
|
|
702
|
+
: null;
|
|
703
|
+
const inboxBlockedIndividual = inboxPartition?.blockedIndividual ?? [];
|
|
704
|
+
const inboxBlockedAggregate = inboxPartition?.blockedAggregate ?? [];
|
|
705
|
+
const inboxRecovery = inboxPartition?.recovery ?? [];
|
|
706
|
+
const unmatchedInboxDecisions = inboxPartition?.unmatchedDecisions ?? [];
|
|
707
|
+
// 待处理口径 (INV-01 lineage): decision + blocked-individual + recovery —
|
|
708
|
+
// same three groups the inbox renders; historical unknowns stay explanatory.
|
|
709
|
+
const inboxPendingTotal = inboxPartition?.pendingTotal ?? 0;
|
|
710
|
+
// 可操作口径: the action cards actually on screen (decision cards + approval
|
|
711
|
+
// cards) — the same number the「需要你决定」section header shows.
|
|
712
|
+
const actionableCount = (ownerDecisionError === null ? decisionItems.length : 0)
|
|
713
|
+
+ (showApprovalCards ? pendingGroups.length : 0);
|
|
714
|
+
// Review round 2 (P2): the headline never claims allClear from the inbox
|
|
715
|
+
// alone, degraded payloads surface their reason, and the total is the
|
|
716
|
+
// association-deduped union of on-screen cards and inbox items — see
|
|
717
|
+
// deriveConclusionDisplay.
|
|
718
|
+
const conclusionDisplay = deriveConclusionDisplay({
|
|
719
|
+
ownerInbox,
|
|
720
|
+
ownerInboxError,
|
|
721
|
+
partition: inboxPartition,
|
|
722
|
+
actionableCount,
|
|
723
|
+
});
|
|
603
724
|
// Map codes to i18n text
|
|
604
725
|
// Governance Recovery Actions v1: tasks_need_human_review interpolates the
|
|
605
726
|
// needs_human_review task count, not the approvals count.
|
|
@@ -607,9 +728,17 @@ export function FocusPage({ featureFlags }) {
|
|
|
607
728
|
const stateReasonCount = stateReasonCode === "tasks_need_human_review" ? humanReviewCount : pendingCount;
|
|
608
729
|
const stateReason = getStateReasonText(stateReasonCode, t, stateReasonCount);
|
|
609
730
|
const nextAction = getNextActionText(nextActionCode, t);
|
|
610
|
-
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, children: t("pages.focus.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.focus.subtitle") }), _jsxs("section", { "aria-label": t("pages.focus.
|
|
611
|
-
|
|
612
|
-
|
|
731
|
+
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, children: t("pages.focus.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.focus.subtitle") }), _jsxs("section", { "aria-label": t("pages.focus.conclusion.sectionTitle"), "data-testid": "focus-conclusion", className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [_jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${experienceMode && experienceData !== null
|
|
732
|
+
? EXPERIENCE_ATTENTION[experienceData.summary.primaryAttention].badgeClass
|
|
733
|
+
: governanceState === "owner_review_ready"
|
|
734
|
+
? "bg-gov/10 text-gov border border-gov/20"
|
|
735
|
+
: governanceState === "degraded"
|
|
736
|
+
? "bg-amber/10 text-amber border border-amber/20"
|
|
737
|
+
: governanceState === "in_progress"
|
|
738
|
+
? "bg-green/10 text-green border border-green/20"
|
|
739
|
+
: "text-ink-4 border border-line bg-surface/80"}`, role: "status", "data-testid": "focus-conclusion-badge", children: experienceMode && experienceData !== null
|
|
740
|
+
? t(EXPERIENCE_ATTENTION[experienceData.summary.primaryAttention].labelKey)
|
|
741
|
+
: t(`pages.focus.stateLabel.${governanceState}`) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed", "data-testid": "focus-conclusion-counts", children: conclusionDisplay.mode === 'ok' && conclusionDisplay.displayTotal === 0 ? (_jsx("span", { children: t("pages.focus.conclusion.allClear") })) : conclusionDisplay.mode === 'unavailable' || conclusionDisplay.mode === 'degraded' ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-medium", "data-testid": "focus-conclusion-uncertain", children: t("pages.focus.conclusion.pendingUncertain") }), conclusionDisplay.actionableCount > 0 && (_jsxs("span", { className: "text-ink-4", children: [" · ", t(resolveConclusionActionableKey(conclusionDisplay.mode, ownerActionsLockedReason !== null), { count: conclusionDisplay.actionableCount })] }))] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-medium", children: t("pages.focus.conclusion.pendingTotal", { count: conclusionDisplay.displayTotal }) }), _jsxs("span", { className: "text-ink-4", children: [" · ", t(resolveConclusionActionableKey(conclusionDisplay.mode, ownerActionsLockedReason !== null), { count: conclusionDisplay.actionableCount })] })] })) })] }), conclusionDisplay.mode === 'degraded' && conclusionDisplay.degraded && (_jsxs("div", { className: "mt-3 border border-amber/30 rounded-[6px] bg-surface px-3 py-2.5", "data-testid": "focus-conclusion-degraded", children: [_jsxs("p", { className: "text-[12px] text-ink-3 leading-relaxed", children: [t("pages.focus.conclusion.degradedLabel"), " ", conclusionDisplay.degraded.reason] }), _jsx("p", { className: "mt-1 text-[12px] text-ink-3 leading-relaxed", children: conclusionDisplay.degraded.nextAction })] })), ownerActionsLockedReason !== null && (_jsxs("div", { id: "focus-global-lock-notice", className: "mt-3 flex items-start justify-between gap-3 border border-amber/30 rounded-[6px] bg-surface px-3 py-2.5", "data-testid": "focus-conclusion-lock", children: [_jsx("p", { className: "text-[12px] text-ink-3 leading-relaxed", children: ownerActionsLockedReason }), _jsx(Link, { to: "/settings", className: "shrink-0 text-[12px] text-gov underline hover:text-gov-2", children: t("pages.focus.ownerDecision.goSettingsCta") })] })), _jsx("p", { className: "mt-2 text-ink-4 text-[11.5px] leading-relaxed", "data-testid": "focus-conclusion-scope-note", children: t("pages.focus.conclusion.countsNote") })] }), _jsxs("section", { "aria-label": t("pages.focus.ownerDecision.sectionTitle"), className: "mb-7", "data-testid": "owner-decisions-section", children: [_jsxs("div", { className: "flex items-baseline gap-2 mb-3", children: [_jsx(SectionTitle, { children: t("pages.focus.ownerDecision.sectionTitle") }), _jsx("span", { className: "font-mono text-ink-4 text-[12px]", children: ownerDecisionError !== null
|
|
613
742
|
? t("pages.focus.ownerDecision.unavailable")
|
|
614
743
|
: `· ${decisionItems.length + (showApprovalCards ? pendingGroups.length : 0)}` })] }), ownerDecisionError !== null && (_jsx("p", { className: "text-ink-4 text-[12.5px]", children: t("pages.focus.ownerDecision.loadError") })), ownerDecisionError === null && decisionItems.length === 0 && !showApprovalCards && (_jsx("p", { className: "text-ink-4 text-[13px]", children: t("pages.focus.ownerDecision.empty") })), decisionItems.map((item) => (_jsx(OwnerDecisionCard, { item: item, governanceReady: experienceData === null || (experienceData.readiness.authenticationMode === "authenticated"
|
|
615
744
|
&& experienceData.readiness.ownerIdentityConfiguration === "configured"), actionsLockedReason: ownerActionsLockedReason ?? undefined, onResolved: () => { void loadData(); } }, item.reviewKey))), (() => {
|
|
@@ -627,16 +756,18 @@ export function FocusPage({ featureFlags }) {
|
|
|
627
756
|
budget: unconfirmed.budget,
|
|
628
757
|
full: entry.truncated ? t("pages.focus.promptCapacityPerHostFull") : "",
|
|
629
758
|
}) }, entry.hostKind))) }), unconfirmed.nextAction !== undefined && (_jsx("p", { className: "mt-1 text-ink-2", children: unconfirmed.nextAction })), _jsxs("div", { className: "mt-2 flex gap-2", children: [["openclaw", "codex"].map((host) => (_jsx("button", { type: "button", onClick: () => setPromptTargetHost(host), "data-testid": `prompt-capacity-pick-${host}`, className: `inline-flex items-center border rounded-[3px] px-[10px] py-[4px] transition-colors ${promptTargetHost === host ? "border-amber bg-amber/10" : "border-line hover:border-line-2"}`, children: t("pages.focus.promptCapacityViewAsHost", { host: host === "openclaw" ? "OpenClaw" : "Codex" }) }, host))), promptTargetHost !== null && (_jsx("button", { type: "button", onClick: () => setPromptTargetHost(null), "data-testid": "prompt-capacity-pick-clear", className: "inline-flex items-center border border-line rounded-[3px] px-[10px] py-[4px] hover:border-line-2", children: t("pages.focus.promptCapacityClearHost", { defaultValue: "清除选择" }) }))] })] }));
|
|
630
|
-
})(), groupedAvailable && pendingGroups.map((group) => (_jsx(PendingReviewCard, { group: group, actionsLockedReason: ownerActionsLockedReason ?? undefined, promptInjection: groupedData.promptInjection, promptTargetHost: promptTargetHost ?? undefined, onDecisionApplied: () => { void loadData(); } }, group.principleId)))] }),
|
|
759
|
+
})(), groupedAvailable && pendingGroups.map((group) => (_jsx(PendingReviewCard, { group: group, actionsLockedReason: ownerActionsLockedReason ?? undefined, promptInjection: groupedData.promptInjection, promptTargetHost: promptTargetHost ?? undefined, onDecisionApplied: () => { void loadData(); } }, group.principleId)))] }), _jsxs("section", { "aria-label": t("pages.focus.ownerAttention.sectionTitle"), className: "mb-7", "data-testid": "owner-attention-section", children: [_jsxs("div", { className: "flex items-baseline gap-2 mb-3", children: [_jsx(SectionTitle, { children: t("pages.focus.ownerAttention.sectionTitle") }), ownerInbox !== null && ownerInboxError === null && (_jsx("span", { className: "font-mono text-ink-4 text-[12px]", "data-testid": "owner-attention-counts", children: `· ${t("pages.focus.ownerAttention.blockedCount", { count: ownerInbox.groups.blocked.length })} · ${t("pages.focus.ownerAttention.recoveryCount", { count: inboxRecovery.length })}` }))] }), ownerInboxError !== null && (_jsx("p", { className: "text-ink-4 text-[12.5px]", children: t("pages.focus.ownerInbox.loadError") })), ownerInbox !== null && ownerInboxError === null && (_jsxs(_Fragment, { children: [ownerInbox.groups.blocked.length === 0
|
|
760
|
+
&& inboxRecovery.length === 0
|
|
761
|
+
&& unmatchedInboxDecisions.length === 0 && (_jsx("p", { className: "text-ink-4 text-[13px]", children: t("pages.focus.ownerAttention.empty") })), unmatchedInboxDecisions.length > 0 && (_jsx("p", { className: "mb-2 text-ink-4 text-[12px] leading-relaxed", "data-testid": "owner-attention-unmatched-note", children: t("pages.focus.ownerAttention.unmatchedTitle") })), unmatchedInboxDecisions.map((item) => (_jsx(InboxItem, { item: item, t: t, note: t("pages.focus.ownerAttention.unmatchedItemNote") }, item.principleId))), inboxBlockedIndividual.map((item) => (_jsx(InboxItem, { item: item, t: t }, item.principleId))), inboxRecovery.map((item) => (_jsx(InboxItem, { item: item, t: t }, item.principleId))), inboxBlockedAggregate.length > 0 && (_jsxs("p", { className: "mt-2 text-ink-4 text-[12.5px] leading-relaxed", "data-testid": "owner-attention-aggregate-notice", children: [t("pages.focus.ownerAttention.blockedAggregate", { count: inboxBlockedAggregate.length }), " ", _jsx(Link, { to: "/principles", className: "text-gov hover:underline", children: t("pages.focus.ownerInbox.viewLibrary") })] })), ownerInbox.historicalUnknown.count > 0 && (_jsxs("p", { className: "text-ink-4 text-[12.5px] leading-relaxed mt-2", "data-testid": "owner-inbox-aggregate-notice", children: [ownerInbox.historicalUnknown.reasonText, " ", _jsx(Link, { to: "/principles", className: "text-gov hover:underline", children: t("pages.focus.ownerInbox.viewLibrary") })] }))] }))] }), experienceMode && experienceData !== null ? (_jsx(ExperienceSummaryCard, { snapshot: experienceData })) : !experienceMode ? (_jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", children: [_jsx("div", { className: "flex items-center gap-2 mb-1", children: _jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${governanceState === "owner_review_ready" ? "bg-gov/10 text-gov border border-gov/20"
|
|
631
762
|
: governanceState === "degraded" ? "bg-amber/10 text-amber border border-amber/20"
|
|
632
763
|
: governanceState === "in_progress" ? "bg-green/10 text-green border border-green/20"
|
|
633
|
-
: "text-ink-4 border border-line bg-surface/80"}`, role: "status", children: t(`pages.focus.stateLabel.${governanceState}`) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", children: stateReason }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", nextAction] })] })) : null, !experienceMode && (_jsxs(_Fragment, { children: [_jsx(ProseSummary, { pendingCount: pendingCount, deviationCount: deviationCount, stagnationCount: stagnationCount, evidenceCount: evidenceCount }), _jsx(FeedbackStratification, { gateBlocksToday: gateBlocksToday, inProgressCount: evidenceCount, pendingCount: pendingCount }), !experienceMode && governanceState === "none" && pendingCount === 0 && deviationCount === 0 && stagnationCount === 0 && (stateReasonCode === "state_db_missing" ? (_jsx(ZeroStateDbMissing, {})) : (_jsxs(_Fragment, { children: [_jsx(ZeroStateHealthy, {}), _jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })] }))), governanceState === "in_progress" && inProgressSummary && (_jsx(InProgressGuide, { summary: inProgressSummary })), degradedSignals && degradedSignals.length > 0 && (_jsx(DegradedSummary, { signals: degradedSignals }))] })),
|
|
764
|
+
: "text-ink-4 border border-line bg-surface/80"}`, role: "status", children: t(`pages.focus.stateLabel.${governanceState}`) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", children: stateReason }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", nextAction] })] })) : null, !experienceMode && (_jsxs(_Fragment, { children: [_jsx(ProseSummary, { pendingCount: pendingCount, deviationCount: deviationCount, stagnationCount: stagnationCount, evidenceCount: evidenceCount }), _jsx(FeedbackStratification, { gateBlocksToday: gateBlocksToday, inProgressCount: evidenceCount, pendingCount: pendingCount }), !experienceMode && governanceState === "none" && pendingCount === 0 && deviationCount === 0 && stagnationCount === 0 && (stateReasonCode === "state_db_missing" ? (_jsx(ZeroStateDbMissing, {})) : (_jsxs(_Fragment, { children: [_jsx(ZeroStateHealthy, {}), _jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })] }))), governanceState === "in_progress" && inProgressSummary && (_jsx(InProgressGuide, { summary: inProgressSummary })), degradedSignals && degradedSignals.length > 0 && (_jsx(DegradedSummary, { signals: degradedSignals }))] })), experienceMode && experienceData !== null && experienceData.summary.primaryAttention === "all_clear" && pendingGroups.length === 0 && (_jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: evidenceCount > 0
|
|
634
765
|
? t("pages.focus.sectionEvidenceInProgress")
|
|
635
|
-
: t("pages.focus.sectionDeviation") }), deviationCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-ink-2 text-sm mb-3", children: [_jsx("span", { className: "font-mono font-semibold text-ink", children: deviationCount }), " ", t("pages.focus.deviationCount", { count: deviationCount })] }), _jsx("div", { className: "text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2 mb-4", children: t("pages.focus.deviationDisclaimer") }), _jsxs("details", { className: "group", children: [_jsx("summary", { className: "text-gov text-[13px] cursor-pointer hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.viewFullChain") }), _jsx("div", { className: "mt-2 pl-4 border-l-2 border-line text-ink-3 text-[13px]", children: t("pages.focus.deviationDetailPending") })] })] })) : evidenceCount > 0 ? (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.evidenceInProgress", { count: evidenceCount }) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptyDeviation") }))] })), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-signals", children: [_jsx(SectionTitle, { id: "section-signals", children: t("pages.focus.sectionSignals") }), stagnationSignals.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: stagnationSignals.map((signal) => (_jsx(StagnationSignalCard, { signal: signal }, signal.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptySignals") }))] })), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.focus.footer") })] }) }));
|
|
766
|
+
: t("pages.focus.sectionDeviation") }), deviationCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-ink-2 text-sm mb-3", children: [_jsx("span", { className: "font-mono font-semibold text-ink", children: deviationCount }), " ", t("pages.focus.deviationCount", { count: deviationCount })] }), _jsx("div", { className: "text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2 mb-4", children: t("pages.focus.deviationDisclaimer") }), _jsxs("details", { className: "group", children: [_jsx("summary", { className: "text-gov text-[13px] cursor-pointer hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.viewFullChain") }), _jsx("div", { className: "mt-2 pl-4 border-l-2 border-line text-ink-3 text-[13px]", children: t("pages.focus.deviationDetailPending") })] })] })) : evidenceCount > 0 ? (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.evidenceInProgress", { count: evidenceCount }) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptyDeviation") }))] })), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-signals", children: [_jsx(SectionTitle, { id: "section-signals", children: t("pages.focus.sectionSignals") }), stagnationSignals.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: stagnationSignals.map((signal) => (_jsx(StagnationSignalCard, { signal: signal }, signal.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptySignals") }))] })), _jsx(DailyThoughtCard, {}), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.focus.footer") })] }) }));
|
|
636
767
|
}
|
|
637
768
|
/** Owner Decision Experience v1 inbox item — display-only (SPEC §11.1). */
|
|
638
|
-
function InboxItem({ item, t }) {
|
|
769
|
+
function InboxItem({ item, t, note }) {
|
|
639
770
|
return (_jsxs("div", { className: "mb-2 rounded-[var(--radius-md)] border border-line p-3", "data-testid": "owner-inbox-item", children: [_jsxs("div", { className: "flex flex-wrap items-baseline gap-2", children: [_jsx(Link, { to: `/principles/${encodeURIComponent(item.principleId)}`, className: "text-ink text-[13.5px] font-medium hover:underline", children: item.learnedPrinciple.status === 'known'
|
|
640
771
|
? item.learnedPrinciple.text
|
|
641
|
-
: item.learnedPrinciple.reasonText }), _jsx("span", { className: "font-mono text-[11px] text-ink-4 border border-line rounded-[2px] px-1.5 py-0.5", children: t(`pages.focus.ownerInbox.group.${item.inbox.group}`) })] }), _jsx("p", { className: "mt-1 text-ink-3 text-[12.5px] leading-relaxed", children: item.nextAction.ownerText })] }));
|
|
772
|
+
: item.learnedPrinciple.reasonText }), _jsx("span", { className: "font-mono text-[11px] text-ink-4 border border-line rounded-[2px] px-1.5 py-0.5", children: t(`pages.focus.ownerInbox.group.${item.inbox.group}`) })] }), _jsx("p", { className: "mt-1 text-ink-3 text-[12.5px] leading-relaxed", children: note ?? item.nextAction.ownerText })] }));
|
|
642
773
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export declare function getReceiptPresentation(effectCount: number): {
|
|
2
|
-
headlineKey: 'principles.detail.receipts.headline' | 'principles.detail.receipts.headlinePresence';
|
|
1
|
+
export declare function getReceiptPresentation(effectCount: number, presenceCount: number): {
|
|
2
|
+
headlineKey: 'principles.detail.receipts.headline' | 'principles.detail.receipts.headlinePresence' | 'principles.detail.receipts.headlineNone';
|
|
3
|
+
/** effect>0 且 presence=0 — effects exist without any presence records; note it, never fabricate presence. */
|
|
4
|
+
presenceMissing: boolean;
|
|
3
5
|
showZeroEffectExplanation: boolean;
|
|
4
6
|
};
|
|
5
7
|
export type GovernanceControlBlock = {
|
|
@@ -105,10 +105,33 @@ const STAGE_LABEL_KEYS = {
|
|
|
105
105
|
behavior: "principles.detail.stageBehavior",
|
|
106
106
|
};
|
|
107
107
|
// ── Component ───────────────────────────────────────────────────────────────
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
// SPEC-PD-UIUX-001 R1: the headline must agree with BOTH verified counts.
|
|
109
|
+
// effect>0 → effect headline (records exist; no permanence claim)
|
|
110
|
+
// effect=0,presence>0 → "injections recorded, no effect records yet"
|
|
111
|
+
// effect=0,presence=0 → "nothing observed within the current retention window"
|
|
112
|
+
// Presence is never inferred from approval/activation, and effect is never
|
|
113
|
+
// inferred from presence — the degraded branch (status≠ok) handles
|
|
114
|
+
// "cannot be confirmed" separately.
|
|
115
|
+
export function getReceiptPresentation(effectCount, presenceCount) {
|
|
116
|
+
if (effectCount > 0) {
|
|
117
|
+
return {
|
|
118
|
+
headlineKey: 'principles.detail.receipts.headline',
|
|
119
|
+
presenceMissing: presenceCount === 0,
|
|
120
|
+
showZeroEffectExplanation: false,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (presenceCount > 0) {
|
|
124
|
+
return {
|
|
125
|
+
headlineKey: 'principles.detail.receipts.headlinePresence',
|
|
126
|
+
presenceMissing: false,
|
|
127
|
+
showZeroEffectExplanation: true,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
headlineKey: 'principles.detail.receipts.headlineNone',
|
|
132
|
+
presenceMissing: false,
|
|
133
|
+
showZeroEffectExplanation: true,
|
|
134
|
+
};
|
|
112
135
|
}
|
|
113
136
|
export const GOVERNANCE_BLOCK_I18N_KEYS = {
|
|
114
137
|
recoveryReason: 'principles.detail.governance.reason.recovery_required',
|
|
@@ -434,7 +457,7 @@ export function PrincipleDetailPage() {
|
|
|
434
457
|
}
|
|
435
458
|
const hasRules = principle.rules.length > 0;
|
|
436
459
|
const receiptPresentation = receipts?.status === 'ok'
|
|
437
|
-
? getReceiptPresentation(receipts.effectCount)
|
|
460
|
+
? getReceiptPresentation(receipts.effectCount, receipts.presenceCount)
|
|
438
461
|
: null;
|
|
439
462
|
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsxs(Button, { variant: "ghost", onClick: () => navigate("/principles"), className: "mb-4 -ml-2", children: ["\u2190 ", t("principles.detail.backToList")] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.conclusion") }), _jsx("h1", { className: "text-[22px] font-semibold text-ink leading-snug mb-3", children: ownerDecision?.learnedPrinciple.status === 'known'
|
|
440
463
|
? ownerDecision.learnedPrinciple.value.text
|
|
@@ -476,25 +499,40 @@ export function PrincipleDetailPage() {
|
|
|
476
499
|
effectCount: receipts.effectCount,
|
|
477
500
|
lastEffectAt: receipts.lastEffectAt ? formatDate(receipts.lastEffectAt, i18n.language) : '',
|
|
478
501
|
})
|
|
479
|
-
: t('principles.detail.receipts.headlinePresence') }), _jsx("span", { "data-testid": "receipt-history-counts", className: "font-mono text-[11px] text-ink-3", children: t('principles.detail.receipts.counts', { effectCount: receipts.effectCount, presenceCount: receipts.presenceCount }) })] }), receiptPresentation?.showZeroEffectExplanation && (_jsx("p", { "data-testid": "receipt-history-zero-effect", className: "mt-2 text-[12px] leading-relaxed text-ink-3", children: t(
|
|
480
|
-
|
|
502
|
+
: t(receiptPresentation?.headlineKey ?? 'principles.detail.receipts.headlinePresence') }), _jsx("span", { "data-testid": "receipt-history-counts", className: "font-mono text-[11px] text-ink-3", children: t('principles.detail.receipts.counts', { effectCount: receipts.effectCount, presenceCount: receipts.presenceCount }) })] }), receiptPresentation?.showZeroEffectExplanation && (_jsx("p", { "data-testid": "receipt-history-zero-effect", className: "mt-2 text-[12px] leading-relaxed text-ink-3", children: t(receipts.presenceCount > 0
|
|
503
|
+
? 'principles.detail.receipts.zeroEffectPresence'
|
|
504
|
+
: 'principles.detail.receipts.zeroEffectNone') })), receiptPresentation?.presenceMissing && (_jsx("p", { "data-testid": "receipt-history-presence-missing", className: "mt-2 text-[12px] leading-relaxed text-ink-3", children: t('principles.detail.receipts.presenceMissingNote') })), receipts.events.length > 0 ? (_jsx("ul", { className: "mt-3 space-y-1.5", children: receipts.events.map((event, index) => (_jsxs("li", { className: `flex flex-wrap items-baseline gap-2 text-[13px] ${event.level === 'presence' ? 'text-ink-4' : 'text-ink-2'}`, children: [_jsx("span", { className: "font-mono text-[11px] text-ink-4", children: event.createdAt.slice(0, 16).replace('T', ' ') }), _jsx("span", { className: "font-mono text-[11px]", children: t(`principles.detail.receipts.kind.${event.kind}`, { defaultValue: event.kind }) }), event.digest && _jsx("span", { className: "min-w-0 flex-1 truncate", title: event.digest, children: event.digest })] }, `${event.createdAt}-${index}`))) })) : (_jsx("p", { className: "mt-2 text-[13px] text-ink-3", children: t('principles.detail.receipts.empty') })), _jsx("p", { className: "mt-3 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.receipts.note') }), _jsx("div", { className: "mt-3 border-t border-line pt-3", children: _jsx(ReceiptCoverageDisclosure, { coverage: receipts.coverage }) })] })) : (_jsxs("div", { "data-testid": "receipt-history-degraded", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("h3", { className: "text-[13px] font-semibold text-ink", children: i18n.t(getReceiptSourceStatusLabelKey(receipts.coverage.sourceStatus)) }), _jsx("p", { className: "mt-1 text-[13px] text-ink-2", children: receipts.reason ?? t('principles.detail.receipts.unavailableReason') }), receipts.nextAction && _jsx("p", { className: "mt-1 text-[12px] text-ink-3", children: receipts.nextAction })] }))] })), evidenceAudit !== null && (_jsxs("section", { className: "mb-8", "aria-labelledby": "evidence-audit-title", children: [_jsx(SectionTitle, { children: t('principles.detail.evidenceAudit.title') }), evidenceAudit.status === 'ok' ? (_jsxs("div", { "data-testid": "evidence-audit", className: "rounded-[var(--radius-md)] border border-line p-4", children: [_jsx("h2", { id: "evidence-audit-title", className: "text-[15px] font-semibold text-ink", children: t('principles.detail.evidenceAudit.headline', {
|
|
481
505
|
d: evidenceAudit.deliveries.length,
|
|
482
506
|
a: evidenceAudit.applications.length,
|
|
483
507
|
e: evidenceAudit.episodes.length,
|
|
484
508
|
f: evidenceAudit.effects.length,
|
|
485
509
|
o: evidenceAudit.outcomes.length,
|
|
486
510
|
}) }), evidenceAudit.unresolvedReferences.length > 0 && (_jsx("p", { "data-testid": "evidence-audit-unresolved", className: "mt-2 text-[12px] text-amber", children: t('principles.detail.evidenceAudit.unresolved', {
|
|
487
|
-
defaultValue: '{{count}} 条记录的关联对象尚未到达(pending association,非"未发生")',
|
|
488
511
|
count: evidenceAudit.unresolvedReferences.length,
|
|
489
512
|
}) })), _jsx("dl", { className: "mt-3 space-y-2 text-[13px]", children: [
|
|
490
|
-
['delivery', '
|
|
491
|
-
['application', '
|
|
492
|
-
['episode', '
|
|
493
|
-
['effect', '
|
|
494
|
-
['outcome', '
|
|
495
|
-
].map(([key,
|
|
496
|
-
|
|
497
|
-
|
|
513
|
+
['delivery', 'principles.detail.evidenceAudit.sectionDelivery', evidenceAudit.deliveries, 'delivery'],
|
|
514
|
+
['application', 'principles.detail.evidenceAudit.sectionApplication', evidenceAudit.applications, 'application'],
|
|
515
|
+
['episode', 'principles.detail.evidenceAudit.sectionEpisode', evidenceAudit.episodes, 'behavior_episode'],
|
|
516
|
+
['effect', 'principles.detail.evidenceAudit.sectionEffect', evidenceAudit.effects, 'effect'],
|
|
517
|
+
['outcome', 'principles.detail.evidenceAudit.sectionOutcome', evidenceAudit.outcomes, 'outcome'],
|
|
518
|
+
].map(([key, labelKey, list, recordKind]) => (_jsxs("div", { className: "border-t border-line pt-2", children: [_jsx("dt", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t(labelKey) }), _jsx("dd", { className: "mt-1", children: list.length === 0 ? (_jsx("span", { className: "text-[13px] text-ink-3", children: t('principles.detail.evidenceAudit.emptySection') })) : (_jsx("ul", { className: "space-y-1", children: list.map((record) => (_jsxs("li", { className: "flex flex-wrap items-baseline gap-2 text-[13px] text-ink-2", children: [_jsx("span", { className: "font-mono text-[11px] text-ink-4", children: record.recordedAt.slice(0, 16).replace('T', ' ') }), _jsx("span", { className: "font-mono text-[11px]", children: record.summary }), _jsx("span", { className: "min-w-0 flex-1 break-words", title: `${record.observationKey}\n${record.detail}`, children: record.detail }), record.associationStatus === 'pending_association' && (_jsx("span", { className: "font-mono text-[10px] rounded bg-amber/15 px-1.5 py-0.5 text-amber", children: t('principles.detail.evidenceAudit.pending') }))] }, record.evidenceId))) })) }), evidenceAudit.pages[recordKind].hasMore && (_jsx(Button, { variant: "ghost", size: "sm", disabled: loadingEvidenceKind !== null, onClick: () => void loadOlderEvidence(recordKind), children: loadingEvidenceKind === recordKind ? t('principles.detail.evidenceAudit.loading') : t('principles.detail.evidenceAudit.loadOlder') }))] }, key))) }), evidenceAudit.capabilityDeclarations.length > 0 && (_jsxs("details", { className: "mt-3 border-t border-line pt-3", children: [_jsx("summary", { className: "cursor-pointer font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.evidenceAudit.capabilities') }), _jsx("ul", { className: "mt-2 space-y-1", children: evidenceAudit.capabilityDeclarations.map((cap) => (_jsxs("li", { className: "text-[12px] text-ink-3", children: [_jsxs("span", { className: "font-mono", children: [cap.hostKind, " \u00B7 ", cap.capability, " \u00B7 ", cap.status] }), cap.note && _jsxs("span", { children: [" \u2014 ", cap.note] })] }, `${cap.hostKind}-${cap.capability}`))) })] })), _jsxs("details", { className: "mt-3 border-t border-line pt-3", "data-testid": "evidence-audit-technical", children: [_jsx("summary", { className: "cursor-pointer font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.evidenceAudit.technicalSummary') }), _jsx("p", { className: "mt-2 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.evidenceAudit.technicalNote') }), _jsx("ul", { className: "mt-2 space-y-1", children: [
|
|
519
|
+
['principles.detail.evidenceAudit.sectionDelivery', evidenceAudit.deliveries],
|
|
520
|
+
['principles.detail.evidenceAudit.sectionApplication', evidenceAudit.applications],
|
|
521
|
+
['principles.detail.evidenceAudit.sectionEpisode', evidenceAudit.episodes],
|
|
522
|
+
['principles.detail.evidenceAudit.sectionEffect', evidenceAudit.effects],
|
|
523
|
+
['principles.detail.evidenceAudit.sectionOutcome', evidenceAudit.outcomes],
|
|
524
|
+
].flatMap(([labelKey, list]) => list.map((record) => (_jsxs("li", { className: "text-[11px] leading-relaxed text-ink-4", children: [_jsx("span", { className: "font-mono", children: record.evidenceId }), record.sourceStatus === 'unknown' && _jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.sourceUnknown')] }), record.contentRedactedAt && _jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.contentRedacted', { date: record.contentRedactedAt.slice(0, 10) })] }), record.contentReference && (_jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.contentReference', {
|
|
525
|
+
resolution: record.contentReference.resolution === 'resolved' ? t('principles.detail.evidenceAudit.referenceResolved') : t('principles.detail.evidenceAudit.referenceUnresolved'),
|
|
526
|
+
principleId: record.contentReference.principleId,
|
|
527
|
+
artifactId: record.contentReference.artifactId ? ` · ${record.contentReference.artifactId}` : '',
|
|
528
|
+
// Review round (P2): keep the payload digest traceable —
|
|
529
|
+
// the technical note promises it.
|
|
530
|
+
payloadDigest: ` · ${t('principles.detail.evidenceAudit.payloadDigestLabel')}: ${record.contentReference.payloadDigest ?? t('principles.detail.evidenceAudit.noPayloadDigest')}`,
|
|
531
|
+
})] })), record.activationReference && (_jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.activationReference', {
|
|
532
|
+
activationId: record.activationReference.activationId,
|
|
533
|
+
activatedAt: record.activationReference.activatedAt ? ` · ${record.activationReference.activatedAt}` : '',
|
|
534
|
+
snapshotDigest: ` · ${t('principles.detail.evidenceAudit.snapshotDigestLabel')}: ${record.activationReference.sourceSnapshotDigest}`,
|
|
535
|
+
})] })), record.nativeLineage.length > 0 && _jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.nativeLineage', { lineage: record.nativeLineage.join(' · ') })] })] }, record.evidenceId)))) })] }), _jsx("p", { className: "mt-3 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.evidenceAudit.note') })] })) : (_jsxs("div", { "data-testid": "evidence-audit-degraded", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("h3", { className: "text-[13px] font-semibold text-ink", children: t('principles.detail.evidenceAudit.unavailable') }), _jsx("p", { className: "mt-1 text-[13px] text-ink-2", children: evidenceAudit.reason ?? '—' }), evidenceAudit.nextAction && _jsx("p", { className: "mt-1 text-[12px] text-ink-3", children: evidenceAudit.nextAction })] }))] })), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.whyExists") }), _jsxs("div", { className: "space-y-3 mb-6", children: [_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.applicable", { defaultValue: "适用场景(原始触发配置)" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed font-mono break-all", children: principle.triggerPattern || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] }), _jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.expectedBehavior", { defaultValue: "预期行为(原始建议)" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.action || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] })] }), principle.derivedFromPainIds.length > 0 && (_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.evidence") }), _jsxs("div", { className: "mt-2 flex items-center gap-3 flex-wrap", children: [_jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.evidenceCount", {
|
|
498
536
|
defaultValue: "已关联 {{count}} 条证据记录",
|
|
499
537
|
count: principle.derivedFromPainIds.length,
|
|
500
538
|
}) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: async () => {
|