create-principles-disciple 1.145.16 → 1.145.18
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/worker/workspace-worker.js +2 -1
- package/codex-adapter/package.json +1 -1
- package/console/dist/server/index.js +12 -0
- package/console/dist/server/models/ActivationsConsoleModel.js +20 -2
- package/console/dist/server/models/ApprovalsConsoleModel.js +28 -4
- package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +29 -3
- package/console/dist/server/routes/design-gate.d.ts +11 -0
- package/console/dist/server/routes/design-gate.js +156 -0
- package/console/dist/shared/prompt-injection-contract.d.ts +1 -1
- package/console/dist/ui/api.d.ts +29 -1
- package/console/dist/ui/api.js +105 -1
- package/console/dist/ui/i18n/en.json +48 -0
- package/console/dist/ui/i18n/zh-CN.json +48 -0
- package/console/dist/ui/pages/activation/ActivationPage.js +3 -1
- package/console/dist/ui/pages/control-center/ControlCenterPage.js +2 -1
- package/console/dist/ui/pages/control-center/DesignGatePanel.d.ts +1 -0
- package/console/dist/ui/pages/control-center/DesignGatePanel.js +137 -0
- package/console/dist/ui/pages/focus/FocusPage.js +19 -3
- package/console/dist/ui/utils/validators.js +1 -1
- package/console/dist/web/assets/app.css +6 -0
- package/console/dist/web/assets/app.js +30 -30
- package/core/dist/runtime-v2/activation/prompt-budget-policy.d.ts +14 -2
- package/core/dist/runtime-v2/activation/prompt-budget-policy.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/prompt-budget-policy.js +24 -2
- package/core/dist/runtime-v2/activation/prompt-budget-policy.js.map +1 -1
- package/core/dist/runtime-v2/config/index.d.ts +3 -3
- package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/index.js +3 -1
- package/core/dist/runtime-v2/config/index.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-effective.d.ts +8 -1
- package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-effective.js +10 -0
- package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-redaction.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-redaction.js +2 -0
- package/core/dist/runtime-v2/config/pd-config-redaction.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-types.d.ts +39 -0
- package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-types.js +7 -0
- package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-validate.js +67 -1
- package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +5 -2
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +6 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-intent-preflight.d.ts +12 -0
- package/core/dist/runtime-v2/internalization/artificer-intent-preflight.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-intent-preflight.js +23 -0
- package/core/dist/runtime-v2/internalization/artificer-intent-preflight.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +1 -1
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +15 -5
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/design-gate-facts.d.ts +54 -0
- package/core/dist/runtime-v2/internalization/design-gate-facts.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/design-gate-facts.js +172 -0
- package/core/dist/runtime-v2/internalization/design-gate-facts.js.map +1 -0
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +8 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js +73 -3
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +64 -2
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/rule-context-v2.d.ts +3 -0
- package/core/dist/runtime-v2/internalization/rule-context-v2.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/rule-context-v2.js +4 -0
- package/core/dist/runtime-v2/internalization/rule-context-v2.js.map +1 -1
- package/core/dist/runtime-v2/store/design-gate/sqlite-design-gate-store.d.ts +49 -0
- package/core/dist/runtime-v2/store/design-gate/sqlite-design-gate-store.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/design-gate/sqlite-design-gate-store.js +274 -0
- package/core/dist/runtime-v2/store/design-gate/sqlite-design-gate-store.js.map +1 -0
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js +31 -0
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +3 -3
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +1 -0
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/package.json +5 -1
- package/host-runtime/dist/codex-artificer-trusted-facts.d.ts +7 -0
- package/host-runtime/dist/codex-artificer-trusted-facts.js +17 -0
- package/host-runtime/dist/codex-rule-context-provider.js +82 -13
- package/host-runtime/dist/design-gate-facts.d.ts +37 -0
- package/host-runtime/dist/design-gate-facts.js +249 -0
- package/host-runtime/dist/index.d.ts +3 -0
- package/host-runtime/dist/index.js +20 -1
- package/host-runtime/dist/production-rulehost-gate.js +37 -1
- package/host-runtime/dist/prompt-injection-budget-observation.d.ts +10 -1
- package/host-runtime/dist/prompt-injection-budget-observation.js +21 -2
- package/host-runtime/dist/workspace-behavior-evidence.d.ts +9 -0
- package/host-runtime/dist/workspace-behavior-evidence.js +85 -0
- package/host-runtime/package.json +1 -1
- package/package.json +2 -2
- package/pd-cli/dist/commands/config-doctor.d.ts.map +1 -1
- package/pd-cli/dist/commands/config-doctor.js +18 -0
- package/pd-cli/dist/commands/config-doctor.js.map +1 -1
- package/pd-cli/dist/services/config-doctor.d.ts +9 -0
- package/pd-cli/dist/services/config-doctor.d.ts.map +1 -1
- package/pd-cli/dist/services/config-doctor.js +6 -0
- package/pd-cli/dist/services/config-doctor.js.map +1 -1
- package/plugin/dist/bundle.js +462 -432
- package/plugin/dist/governance-audit.js +1 -1
- package/plugin/dist/openclaw.plugin.json +1 -1
- package/plugin/dist/rulehost-evidence.js +24 -24
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/release-manager/package.json +2 -2
- package/workbuddy-adapter/package.json +1 -1
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"promptCapacityListRoute": "list injection (billed on the selected lines)",
|
|
103
103
|
"promptCapacityPerHostEntry": "{{host}}: {{billing}} — {{used}}/{{budget}} chars{{full}}{{observed}}",
|
|
104
104
|
"promptCapacityPerHostFull": " (full)",
|
|
105
|
+
"promptCapacityPerHostDeclared": "(budget from the workspace config declaration)",
|
|
105
106
|
"promptCapacityPerHostObserved": " (budget from this host's most recent runtime observation at {{observedAt}})",
|
|
106
107
|
"promptCapacityViewAsHost": "View as {{host}}",
|
|
107
108
|
"promptCapacityClearHost": "Clear selection",
|
|
@@ -116,6 +117,8 @@
|
|
|
116
117
|
"promptBudgetFallbackObservedSuffix": "; the runtime's most recent observation was at {{observedAt}}",
|
|
117
118
|
"budgetCapacitySourceHostWindow": "host effective context window",
|
|
118
119
|
"budgetCapacitySourcePiCatalog": "exact model catalog match",
|
|
120
|
+
"budgetCapacitySourceOperatorDeclared": "workspace config declaration",
|
|
121
|
+
"budgetCapacitySourceOperatorDeclaredSuffix": ", source: workspace config declaration",
|
|
119
122
|
"budgetFallbackReason": {
|
|
120
123
|
"host_capacity_absent": "the host provided no context capacity fact",
|
|
121
124
|
"host_capacity_source_untrusted": "the host capacity source is untrusted",
|
|
@@ -1404,6 +1407,51 @@
|
|
|
1404
1407
|
"eyebrow": "Control Center",
|
|
1405
1408
|
"title": "Config Readiness",
|
|
1406
1409
|
"subtitle": "PD can only work when configuration is complete. This page shows config readiness — not a system health dashboard.",
|
|
1410
|
+
"designGate": {
|
|
1411
|
+
"title": "Local Codex Design Declaration",
|
|
1412
|
+
"description": "Record an Owner decision for a SPEC and an observed native Codex session. The server verifies the session and SPEC snapshot; it does not prove that implementation matches natural-language intent.",
|
|
1413
|
+
"loadingSessions": "Loading observed Codex sessions…",
|
|
1414
|
+
"noSessions": "No native Codex sessions have been observed for this workspace yet. Open a Codex session with PD observation enabled, then refresh.",
|
|
1415
|
+
"refresh": "Refresh",
|
|
1416
|
+
"loadingDeclaration": "Loading the latest declaration…",
|
|
1417
|
+
"nativeSession": "Observed native session",
|
|
1418
|
+
"noDeclaration": "No declaration exists for this session. Record the SPEC, covered paths, actions, and an explicit Owner decision.",
|
|
1419
|
+
"specPath": "SPEC file path",
|
|
1420
|
+
"specPathHint": "Relative to the selected project workspace, or an absolute path inside it",
|
|
1421
|
+
"scopePathsInput": "Project-relative paths covered by this declaration (one per line)",
|
|
1422
|
+
"scopePathsHint": "packages/example/src/file.ts",
|
|
1423
|
+
"scopePathsHelp": "Use . for the project root. With Execute, . covers command invocations originating in this native project/session; it does not sandbox process effects or prove filesystem containment.",
|
|
1424
|
+
"scopeActionsInput": "Actions covered",
|
|
1425
|
+
"initialDecision": "Owner decision",
|
|
1426
|
+
"decisions": {
|
|
1427
|
+
"approved": "Approved",
|
|
1428
|
+
"notApproved": "Not approved",
|
|
1429
|
+
"notRequired": "Approval not required"
|
|
1430
|
+
},
|
|
1431
|
+
"actions": {
|
|
1432
|
+
"read": "Read",
|
|
1433
|
+
"write": "Write",
|
|
1434
|
+
"execute": "Execute"
|
|
1435
|
+
},
|
|
1436
|
+
"decision": "Decision:",
|
|
1437
|
+
"revision": "Revision:",
|
|
1438
|
+
"spec": "SPEC:",
|
|
1439
|
+
"specDigest": "SPEC snapshot digest:",
|
|
1440
|
+
"scopePaths": "Covered paths:",
|
|
1441
|
+
"scopeActions": "Covered actions:",
|
|
1442
|
+
"owner": "Recorded by Owner:",
|
|
1443
|
+
"decidedAt": "Recorded at:",
|
|
1444
|
+
"revoked": "Revoked",
|
|
1445
|
+
"revokedLatest": "The latest declaration is revoked (revision {{revision}}). You can record a new declaration for this session.",
|
|
1446
|
+
"semanticLimit": "This Owner declaration is bound to the shown SPEC snapshot, project, session, and paths/actions. Execute with . covers commands originating in this native project/session; it does not sandbox process effects or prove filesystem containment. Host operations outside a reliably classified path/action scope remain unknown. This declaration does not prove that code satisfies the SPEC’s natural-language meaning.",
|
|
1447
|
+
"requiredFields": "Enter a SPEC path, at least one covered path, and one or more actions.",
|
|
1448
|
+
"invalidMutationResponse": "The server returned no declaration after a successful change. Refresh before continuing.",
|
|
1449
|
+
"approve": "Approve this scope",
|
|
1450
|
+
"markPending": "Mark not approved",
|
|
1451
|
+
"revoke": "Revoke declaration",
|
|
1452
|
+
"saving": "Saving…",
|
|
1453
|
+
"create": "Record declaration"
|
|
1454
|
+
},
|
|
1407
1455
|
"configReady": "Configuration complete. All enabled agents are ready.",
|
|
1408
1456
|
"configNeedsSetup": "Some agents need configuration before they can run.",
|
|
1409
1457
|
"configNotReady": "Some agents cannot run. Check configuration errors below.",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"promptCapacityListRoute": "列表注入(按选中行计费)",
|
|
103
103
|
"promptCapacityPerHostEntry": "{{host}}:{{billing}} — {{used}}/{{budget}} 字符{{full}}{{observed}}",
|
|
104
104
|
"promptCapacityPerHostFull": "(已满)",
|
|
105
|
+
"promptCapacityPerHostDeclared": "(预算来自工作区配置声明)",
|
|
105
106
|
"promptCapacityPerHostObserved": "(预算来自该宿主最近一次运行时观测,观测于 {{observedAt}})",
|
|
106
107
|
"promptCapacityViewAsHost": "按 {{host}} 查看",
|
|
107
108
|
"promptCapacityClearHost": "清除选择",
|
|
@@ -116,6 +117,8 @@
|
|
|
116
117
|
"promptBudgetFallbackObservedSuffix": ";运行时最近一次观测于 {{observedAt}}",
|
|
117
118
|
"budgetCapacitySourceHostWindow": "宿主有效上下文窗口",
|
|
118
119
|
"budgetCapacitySourcePiCatalog": "模型目录精确匹配",
|
|
120
|
+
"budgetCapacitySourceOperatorDeclared": "工作区配置声明",
|
|
121
|
+
"budgetCapacitySourceOperatorDeclaredSuffix": ",来源: 工作区配置声明",
|
|
119
122
|
"budgetFallbackReason": {
|
|
120
123
|
"host_capacity_absent": "宿主未提供上下文容量事实",
|
|
121
124
|
"host_capacity_source_untrusted": "宿主容量来源不可信",
|
|
@@ -1404,6 +1407,51 @@
|
|
|
1404
1407
|
"eyebrow": "控制中心",
|
|
1405
1408
|
"title": "配置就绪",
|
|
1406
1409
|
"subtitle": "PD 能否正常工作取决于配置是否完成。本页展示配置就绪状态——不是系统健康面板。",
|
|
1410
|
+
"designGate": {
|
|
1411
|
+
"title": "本地 Codex 设计声明",
|
|
1412
|
+
"description": "为一份 SPEC 和已观测到的 Codex 原生会话记录拥有者决定。服务端会核验会话与 SPEC 快照,但不会证明实现符合自然语言意图。",
|
|
1413
|
+
"loadingSessions": "正在加载已观测的 Codex 会话…",
|
|
1414
|
+
"noSessions": "此工作区尚未观测到 Codex 原生会话。请在启用 PD 观测的情况下打开 Codex 会话,然后刷新。",
|
|
1415
|
+
"refresh": "刷新",
|
|
1416
|
+
"loadingDeclaration": "正在加载最新声明…",
|
|
1417
|
+
"nativeSession": "已观测的原生会话",
|
|
1418
|
+
"noDeclaration": "此会话尚无声明。请填写 SPEC、覆盖路径、操作和明确的拥有者决定。",
|
|
1419
|
+
"specPath": "SPEC 文件路径",
|
|
1420
|
+
"specPathHint": "相对于所选项目工作区,或工作区内的绝对路径",
|
|
1421
|
+
"scopePathsInput": "声明覆盖的项目相对路径(每行一个)",
|
|
1422
|
+
"scopePathsHint": "packages/example/src/file.ts",
|
|
1423
|
+
"scopePathsHelp": "项目根目录使用 .。选择“执行”并填写 .,表示覆盖从此原生项目/会话发起的命令;这不会沙箱化进程副作用,也不能证明文件系统影响仅限于项目内。",
|
|
1424
|
+
"scopeActionsInput": "覆盖的操作",
|
|
1425
|
+
"initialDecision": "拥有者决定",
|
|
1426
|
+
"decisions": {
|
|
1427
|
+
"approved": "已批准",
|
|
1428
|
+
"notApproved": "未批准",
|
|
1429
|
+
"notRequired": "无需批准"
|
|
1430
|
+
},
|
|
1431
|
+
"actions": {
|
|
1432
|
+
"read": "读取",
|
|
1433
|
+
"write": "写入",
|
|
1434
|
+
"execute": "执行"
|
|
1435
|
+
},
|
|
1436
|
+
"decision": "决定:",
|
|
1437
|
+
"revision": "修订:",
|
|
1438
|
+
"spec": "SPEC:",
|
|
1439
|
+
"specDigest": "SPEC 快照摘要:",
|
|
1440
|
+
"scopePaths": "覆盖路径:",
|
|
1441
|
+
"scopeActions": "覆盖操作:",
|
|
1442
|
+
"owner": "记录拥有者:",
|
|
1443
|
+
"decidedAt": "记录时间:",
|
|
1444
|
+
"revoked": "已撤回",
|
|
1445
|
+
"revokedLatest": "最新声明已撤回(修订 {{revision}})。你可以为此会话记录新声明。",
|
|
1446
|
+
"semanticLimit": "此拥有者声明绑定所示 SPEC 快照、项目、会话及路径/操作范围。选择“执行”并填写 .,覆盖从此原生项目/会话发起的命令;这不会沙箱化进程副作用,也不能证明文件系统影响仅限于项目内。无法可靠分类到路径/操作范围的宿主操作仍属未知。此声明不能证明代码符合 SPEC 的自然语言含义。",
|
|
1447
|
+
"requiredFields": "请填写 SPEC 路径、至少一个覆盖路径和至少一种操作。",
|
|
1448
|
+
"invalidMutationResponse": "服务器在变更成功后未返回声明。请刷新后再继续。",
|
|
1449
|
+
"approve": "批准此范围",
|
|
1450
|
+
"markPending": "标记为未批准",
|
|
1451
|
+
"revoke": "撤回声明",
|
|
1452
|
+
"saving": "保存中…",
|
|
1453
|
+
"create": "记录声明"
|
|
1454
|
+
},
|
|
1407
1455
|
"configReady": "配置完成,所有已启用智能体就绪。",
|
|
1408
1456
|
"configNeedsSetup": "部分智能体需要配置后才能运行。",
|
|
1409
1457
|
"configNotReady": "部分智能体无法运行,请检查下方配置错误。",
|
|
@@ -414,7 +414,9 @@ export function ActivationPage() {
|
|
|
414
414
|
defaultValue: "注入状态中的预算数字取自最近一次运行时观测(来源 {{source}},上下文 {{window}} tokens,观测于 {{observedAt}}),并非实时确认值。",
|
|
415
415
|
source: route.budgetCapacitySource === "pi_catalog_exact"
|
|
416
416
|
? t("pages.focus.budgetCapacitySourcePiCatalog", { defaultValue: "模型目录精确匹配" })
|
|
417
|
-
:
|
|
417
|
+
: route.budgetCapacitySource === "operator_declared"
|
|
418
|
+
? t("pages.focus.budgetCapacitySourceOperatorDeclared", { defaultValue: "工作区配置声明" })
|
|
419
|
+
: t("pages.focus.budgetCapacitySourceHostWindow", { defaultValue: "宿主有效上下文窗口" }),
|
|
418
420
|
window: route.budgetContextWindowTokens,
|
|
419
421
|
observedAt: route.budgetObservedAt,
|
|
420
422
|
}) }));
|
|
@@ -11,6 +11,7 @@ import { enumLabel } from "../../utils/enum-labels.js";
|
|
|
11
11
|
import { WorkflowDiagram } from "./WorkflowDiagram.js";
|
|
12
12
|
import { AgentGroup } from "./AgentGroup.js";
|
|
13
13
|
import { RuntimeProfileManager } from "./RuntimeProfileManager.js";
|
|
14
|
+
import { DesignGatePanel } from "./DesignGatePanel.js";
|
|
14
15
|
import { AGENT_GROUPS, AGENT_METADATA, } from "../../utils/agent-metadata.js";
|
|
15
16
|
// ── Runtime validators (H section / ERR-001/005/009/013) ─────────────────────
|
|
16
17
|
function validateSource(raw) {
|
|
@@ -485,7 +486,7 @@ export function ControlCenterPage() {
|
|
|
485
486
|
};
|
|
486
487
|
const overallReadiness = computeOverallReadiness(diagnostics);
|
|
487
488
|
const availableProfiles = catalogData?.profiles ?? configData.runtimeProfiles;
|
|
488
|
-
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.controlCenter.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.controlCenter.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.controlCenter.subtitle") }), _jsx(WorkflowDiagram, {}), _jsx(CompactStatusBar, { readiness: overallReadiness, agents: configData.agents }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-agents", children: [_jsx(SectionTitle, { id: "section-agents", children: t("pages.controlCenter.internalAgents") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-3", children: t("pages.controlCenter.internalAgentsDescription") }), (() => {
|
|
489
|
+
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.controlCenter.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.controlCenter.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.controlCenter.subtitle") }), _jsx(WorkflowDiagram, {}), _jsx(CompactStatusBar, { readiness: overallReadiness, agents: configData.agents }), _jsx(DesignGatePanel, {}), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-agents", children: [_jsx(SectionTitle, { id: "section-agents", children: t("pages.controlCenter.internalAgents") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-3", children: t("pages.controlCenter.internalAgentsDescription") }), (() => {
|
|
489
490
|
const { groups, unknown } = groupAgentsByDependency(configData.agents);
|
|
490
491
|
const locale = i18n.language.startsWith("en")
|
|
491
492
|
? "en"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function DesignGatePanel(): import("react").JSX.Element;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
import { SectionTitle } from "../../components/layout/section-title.js";
|
|
5
|
+
import { createDesignGateDeclaration, fetchDesignGateDeclaration, fetchDesignGateSessions, revokeDesignGateDeclaration, updateDesignGateDecision, } from "../../api.js";
|
|
6
|
+
const decisionTranslationKey = {
|
|
7
|
+
approved: "approved",
|
|
8
|
+
not_approved: "notApproved",
|
|
9
|
+
not_required: "notRequired",
|
|
10
|
+
};
|
|
11
|
+
const actionTranslationKey = {
|
|
12
|
+
read: "read",
|
|
13
|
+
write: "write",
|
|
14
|
+
execute: "execute",
|
|
15
|
+
};
|
|
16
|
+
function sessionKey(session) {
|
|
17
|
+
return `${session.projectWorkspacePath}\u001f${session.hostSessionId}`;
|
|
18
|
+
}
|
|
19
|
+
function parsePaths(value) {
|
|
20
|
+
return value.split(/\r?\n/).map((path) => path.trim()).filter(Boolean);
|
|
21
|
+
}
|
|
22
|
+
function errorFromResponse(response) {
|
|
23
|
+
return { error: response.error, nextAction: response.nextAction, status: response.status };
|
|
24
|
+
}
|
|
25
|
+
function fieldClass() {
|
|
26
|
+
return "mt-1 w-full rounded-[4px] border border-line bg-surface px-3 py-2 text-[13px] text-ink focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2";
|
|
27
|
+
}
|
|
28
|
+
function actionButtonClass() {
|
|
29
|
+
return "rounded-[4px] border border-line px-3 py-2 text-[12.5px] font-medium text-ink transition-colors hover:border-line-2 focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50";
|
|
30
|
+
}
|
|
31
|
+
export function DesignGatePanel() {
|
|
32
|
+
const { t } = useTranslation();
|
|
33
|
+
const [sessions, setSessions] = useState([]);
|
|
34
|
+
const [selectedKey, setSelectedKey] = useState("");
|
|
35
|
+
const [declaration, setDeclaration] = useState(null);
|
|
36
|
+
const [sessionsLoading, setSessionsLoading] = useState(true);
|
|
37
|
+
const [declarationLoading, setDeclarationLoading] = useState(false);
|
|
38
|
+
const [pending, setPending] = useState(false);
|
|
39
|
+
const [error, setError] = useState(null);
|
|
40
|
+
const [specPath, setSpecPath] = useState("");
|
|
41
|
+
const [scopePaths, setScopePaths] = useState("");
|
|
42
|
+
const [scopeActions, setScopeActions] = useState(["write", "execute"]);
|
|
43
|
+
const [newDecision, setNewDecision] = useState("not_approved");
|
|
44
|
+
const declarationRequest = useRef(0);
|
|
45
|
+
const selectedSession = useMemo(() => sessions.find((session) => sessionKey(session) === selectedKey) ?? null, [sessions, selectedKey]);
|
|
46
|
+
const loadSessions = useCallback(async () => {
|
|
47
|
+
setSessionsLoading(true);
|
|
48
|
+
setError(null);
|
|
49
|
+
const result = await fetchDesignGateSessions();
|
|
50
|
+
setSessionsLoading(false);
|
|
51
|
+
if (!result.success) {
|
|
52
|
+
setError(errorFromResponse(result));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
setSessions(result.data.sessions);
|
|
56
|
+
setSelectedKey((current) => result.data.sessions.some((session) => sessionKey(session) === current)
|
|
57
|
+
? current
|
|
58
|
+
: result.data.sessions[0] ? sessionKey(result.data.sessions[0]) : "");
|
|
59
|
+
}, []);
|
|
60
|
+
const loadDeclaration = useCallback(async (session) => {
|
|
61
|
+
const requestNumber = ++declarationRequest.current;
|
|
62
|
+
setDeclarationLoading(true);
|
|
63
|
+
setError(null);
|
|
64
|
+
const result = await fetchDesignGateDeclaration(session.projectWorkspacePath, session.hostSessionId);
|
|
65
|
+
if (requestNumber !== declarationRequest.current)
|
|
66
|
+
return;
|
|
67
|
+
setDeclarationLoading(false);
|
|
68
|
+
if (!result.success) {
|
|
69
|
+
setError(errorFromResponse(result));
|
|
70
|
+
setDeclaration(null);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
setDeclaration(result.data.declaration);
|
|
74
|
+
}, []);
|
|
75
|
+
useEffect(() => { void loadSessions(); }, [loadSessions]);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (selectedSession)
|
|
78
|
+
void loadDeclaration(selectedSession);
|
|
79
|
+
else {
|
|
80
|
+
declarationRequest.current += 1;
|
|
81
|
+
setDeclarationLoading(false);
|
|
82
|
+
setDeclaration(null);
|
|
83
|
+
}
|
|
84
|
+
}, [selectedSession, loadDeclaration]);
|
|
85
|
+
const runMutation = useCallback(async (mutation) => {
|
|
86
|
+
setPending(true);
|
|
87
|
+
setError(null);
|
|
88
|
+
const result = await mutation();
|
|
89
|
+
setPending(false);
|
|
90
|
+
if (!result.success) {
|
|
91
|
+
const failure = errorFromResponse(result);
|
|
92
|
+
setError(failure);
|
|
93
|
+
if (result.status === 409 && selectedSession) {
|
|
94
|
+
await loadDeclaration(selectedSession);
|
|
95
|
+
setError(failure);
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!result.data.declaration) {
|
|
100
|
+
setError({ error: t("pages.controlCenter.designGate.invalidMutationResponse") });
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
setDeclaration(result.data.declaration);
|
|
104
|
+
}, [loadDeclaration, selectedSession, t]);
|
|
105
|
+
const createDeclaration = useCallback(async () => {
|
|
106
|
+
if (!selectedSession)
|
|
107
|
+
return;
|
|
108
|
+
const paths = parsePaths(scopePaths);
|
|
109
|
+
if (!specPath.trim() || paths.length === 0 || scopeActions.length === 0) {
|
|
110
|
+
setError({ error: t("pages.controlCenter.designGate.requiredFields") });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
await runMutation(() => createDesignGateDeclaration({
|
|
114
|
+
projectWorkspacePath: selectedSession.projectWorkspacePath,
|
|
115
|
+
hostSessionId: selectedSession.hostSessionId,
|
|
116
|
+
specPath: specPath.trim(),
|
|
117
|
+
scope: { paths, actions: scopeActions },
|
|
118
|
+
decision: newDecision,
|
|
119
|
+
}));
|
|
120
|
+
}, [newDecision, runMutation, scopeActions, scopePaths, selectedSession, specPath, t]);
|
|
121
|
+
const mutateDecision = useCallback((decision) => {
|
|
122
|
+
if (!declaration)
|
|
123
|
+
return;
|
|
124
|
+
void runMutation(() => updateDesignGateDecision(declaration.sourceRef, declaration.revision, decision));
|
|
125
|
+
}, [declaration, runMutation]);
|
|
126
|
+
const revoke = useCallback(() => {
|
|
127
|
+
if (!declaration)
|
|
128
|
+
return;
|
|
129
|
+
void runMutation(() => revokeDesignGateDeclaration(declaration.sourceRef, declaration.revision));
|
|
130
|
+
}, [declaration, runMutation]);
|
|
131
|
+
const disabled = pending || declarationLoading || sessionsLoading;
|
|
132
|
+
return (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-design-gate", children: [_jsx(SectionTitle, { id: "section-design-gate", children: t("pages.controlCenter.designGate.title") }), _jsx("p", { className: "mb-4 max-w-[68ch] text-[13px] leading-relaxed text-ink-3", children: t("pages.controlCenter.designGate.description") }), error && (_jsxs("div", { role: "alert", className: "mb-4 rounded-[4px] border border-amber/30 border-l-2 border-l-amber bg-amber/10 p-3 text-[12.5px] text-ink-2", children: [_jsx("p", { children: error.error }), error.nextAction && _jsx("p", { className: "mt-1 text-ink-3", children: error.nextAction }), error.status === 409 && selectedSession && (_jsx("button", { type: "button", className: "mt-2 underline", disabled: disabled, onClick: () => void loadDeclaration(selectedSession), children: t("pages.controlCenter.designGate.refresh") }))] })), sessionsLoading ? (_jsx("p", { className: "text-[13px] text-ink-3", children: t("pages.controlCenter.designGate.loadingSessions") })) : sessions.length === 0 ? (_jsxs("div", { className: "rounded-[4px] border border-line bg-panel p-4 text-[13px] text-ink-3", children: [_jsx("p", { children: t("pages.controlCenter.designGate.noSessions") }), _jsx("button", { type: "button", className: `${actionButtonClass()} mt-3`, disabled: disabled, onClick: () => void loadSessions(), children: t("pages.controlCenter.designGate.refresh") })] })) : (_jsxs("div", { className: "space-y-4 rounded-[4px] border border-line bg-panel p-4", children: [_jsxs("label", { className: "block text-[12.5px] font-medium text-ink", children: [t("pages.controlCenter.designGate.nativeSession"), _jsx("select", { className: fieldClass(), value: selectedKey, disabled: disabled, onChange: (event) => setSelectedKey(event.currentTarget.value), children: sessions.map((session) => (_jsxs("option", { value: sessionKey(session), children: [session.projectWorkspacePath, " \u00B7 ", session.hostSessionId] }, sessionKey(session)))) })] }), declarationLoading ? (_jsx("p", { className: "text-[13px] text-ink-3", children: t("pages.controlCenter.designGate.loadingDeclaration") })) : declaration && !declaration.revoked ? (_jsxs("div", { className: "space-y-3", "aria-live": "polite", children: [_jsxs("div", { className: "grid gap-2 rounded-[4px] border border-line-2 bg-surface p-3 text-[12.5px]", children: [_jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.decision") }), " ", t(`pages.controlCenter.designGate.decisions.${decisionTranslationKey[declaration.decision]}`), declaration.revoked ? ` · ${t("pages.controlCenter.designGate.revoked")}` : ""] }), _jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.revision") }), " ", declaration.revision] }), _jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.spec") }), " ", _jsx("span", { className: "break-all font-mono", children: declaration.specPath })] }), _jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.specDigest") }), " ", _jsx("span", { className: "break-all font-mono", children: declaration.specDigest })] }), _jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.scopePaths") }), " ", _jsx("span", { className: "font-mono", children: declaration.scope.paths.join(", ") })] }), _jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.scopeActions") }), " ", declaration.scope.actions.map((action) => t(`pages.controlCenter.designGate.actions.${actionTranslationKey[action]}`)).join(", ")] }), _jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.owner") }), " ", _jsx("span", { className: "font-mono", children: declaration.actor.ownerId })] }), _jsxs("p", { children: [_jsx("strong", { children: t("pages.controlCenter.designGate.decidedAt") }), " ", declaration.decidedAt] })] }), _jsx("p", { className: "border-l-2 border-amber pl-3 text-[12.5px] leading-relaxed text-ink-3", children: t("pages.controlCenter.designGate.semanticLimit") }), !declaration.revoked && (_jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx("button", { type: "button", className: actionButtonClass(), disabled: disabled || declaration.decision === "approved", onClick: () => mutateDecision("approved"), children: pending ? t("pages.controlCenter.designGate.saving") : t("pages.controlCenter.designGate.approve") }), _jsx("button", { type: "button", className: actionButtonClass(), disabled: disabled || declaration.decision === "not_approved", onClick: () => mutateDecision("not_approved"), children: t("pages.controlCenter.designGate.markPending") }), _jsx("button", { type: "button", className: actionButtonClass(), disabled: disabled, onClick: revoke, children: t("pages.controlCenter.designGate.revoke") })] }))] })) : (_jsxs("div", { className: "space-y-3 border-t border-line pt-4", children: [declaration?.revoked && (_jsxs("div", { className: "rounded-[4px] border border-line-2 bg-surface p-3 text-[12.5px] text-ink-3", children: [_jsx("p", { children: t("pages.controlCenter.designGate.revokedLatest", { revision: declaration.revision }) }), _jsxs("p", { className: "mt-1 break-all font-mono", children: [declaration.specPath, " \u00B7 ", declaration.scope.paths.join(", ")] })] })), _jsx("p", { className: "text-[12.5px] text-ink-3", children: t("pages.controlCenter.designGate.noDeclaration") }), _jsxs("label", { className: "block text-[12.5px] font-medium text-ink", children: [t("pages.controlCenter.designGate.specPath"), _jsx("input", { className: fieldClass(), value: specPath, onChange: (event) => setSpecPath(event.currentTarget.value), placeholder: t("pages.controlCenter.designGate.specPathHint"), disabled: disabled })] }), _jsxs("label", { className: "block text-[12.5px] font-medium text-ink", children: [t("pages.controlCenter.designGate.scopePathsInput"), _jsx("textarea", { className: fieldClass(), rows: 3, value: scopePaths, onChange: (event) => setScopePaths(event.currentTarget.value), placeholder: t("pages.controlCenter.designGate.scopePathsHint"), disabled: disabled })] }), _jsx("p", { className: "-mt-2 text-[12px] leading-relaxed text-ink-4", children: t("pages.controlCenter.designGate.scopePathsHelp") }), _jsxs("fieldset", { disabled: disabled, children: [_jsx("legend", { className: "text-[12.5px] font-medium text-ink", children: t("pages.controlCenter.designGate.scopeActionsInput") }), _jsx("div", { className: "mt-2 flex flex-wrap gap-4", children: ["read", "write", "execute"].map((action) => (_jsxs("label", { className: "flex items-center gap-2 text-[12.5px] text-ink-2", children: [_jsx("input", { type: "checkbox", checked: scopeActions.includes(action), onChange: (event) => setScopeActions((current) => event.currentTarget.checked ? [...current, action] : current.filter((entry) => entry !== action)) }), t(`pages.controlCenter.designGate.actions.${actionTranslationKey[action]}`)] }, action))) })] }), _jsxs("label", { className: "block text-[12.5px] font-medium text-ink", children: [t("pages.controlCenter.designGate.initialDecision"), _jsx("select", { className: fieldClass(), value: newDecision, onChange: (event) => {
|
|
133
|
+
const value = event.currentTarget.value;
|
|
134
|
+
if (value === "approved" || value === "not_approved" || value === "not_required")
|
|
135
|
+
setNewDecision(value);
|
|
136
|
+
}, disabled: disabled, children: ["not_approved", "approved", "not_required"].map((decision) => (_jsx("option", { value: decision, children: t(`pages.controlCenter.designGate.decisions.${decisionTranslationKey[decision]}`) }, decision))) })] }), _jsx("p", { className: "text-[12px] leading-relaxed text-ink-4", children: t("pages.controlCenter.designGate.semanticLimit") }), _jsx("button", { type: "button", className: actionButtonClass(), disabled: disabled, onClick: () => void createDeclaration(), children: pending ? t("pages.controlCenter.designGate.saving") : t("pages.controlCenter.designGate.create") })] }))] }))] }));
|
|
137
|
+
}
|
|
@@ -441,15 +441,24 @@ function PendingReviewCard({ group, actionsLockedReason, onDecisionApplied, prom
|
|
|
441
441
|
// present a past observation as a live confirmation.
|
|
442
442
|
? t("pages.focus.promptBudgetObservedNote", {
|
|
443
443
|
defaultValue: "预算取自最近一次运行时观测(来源 {{source}},上下文 {{window}} tokens,观测于 {{observedAt}})",
|
|
444
|
+
// PRI-1020: three-way source label — the owner-declared
|
|
445
|
+
// basis reads as a declaration, never as a runtime fact.
|
|
444
446
|
source: promptInjection.budgetCapacitySource === "pi_catalog_exact"
|
|
445
447
|
? t("pages.focus.budgetCapacitySourcePiCatalog", { defaultValue: "模型目录精确匹配" })
|
|
446
|
-
:
|
|
448
|
+
: promptInjection.budgetCapacitySource === "operator_declared"
|
|
449
|
+
? t("pages.focus.budgetCapacitySourceOperatorDeclared", { defaultValue: "工作区配置声明" })
|
|
450
|
+
: t("pages.focus.budgetCapacitySourceHostWindow", { defaultValue: "宿主有效上下文窗口" }),
|
|
447
451
|
window: promptInjection.budgetContextWindowTokens,
|
|
448
452
|
observedAt: promptInjection.budgetObservedAt,
|
|
449
453
|
})
|
|
450
454
|
: t("pages.focus.promptBudgetModelAwareNote", {
|
|
451
|
-
defaultValue: "预算按已确认的模型上下文解析({{window}} tokens)",
|
|
455
|
+
defaultValue: "预算按已确认的模型上下文解析({{window}} tokens{{sourceSuffix}})",
|
|
452
456
|
window: promptInjection.budgetContextWindowTokens,
|
|
457
|
+
// PRI-1020: without an observation, a confirmed budget can
|
|
458
|
+
// only come from the Owner's declaration — say so.
|
|
459
|
+
sourceSuffix: promptInjection.budgetCapacitySource === "operator_declared"
|
|
460
|
+
? t("pages.focus.budgetCapacitySourceOperatorDeclaredSuffix", { defaultValue: ",来源: 工作区配置声明" })
|
|
461
|
+
: "",
|
|
453
462
|
})
|
|
454
463
|
: promptInjection.budgetObservedAt !== undefined
|
|
455
464
|
// PRI-1017: a fallback that still carries an observation
|
|
@@ -822,7 +831,14 @@ export function FocusPage({ featureFlags }) {
|
|
|
822
831
|
defaultValue: "(预算来自该宿主最近一次运行时观测,观测于 {{observedAt}})",
|
|
823
832
|
observedAt: entry.budgetObservedAt,
|
|
824
833
|
})
|
|
825
|
-
:
|
|
834
|
+
// PRI-1020: a declared basis is the Owner's own config
|
|
835
|
+
// fact — label it as a declaration, never as an
|
|
836
|
+
// observation.
|
|
837
|
+
: entry.budgetCapacitySource === "operator_declared"
|
|
838
|
+
? t("pages.focus.promptCapacityPerHostDeclared", {
|
|
839
|
+
defaultValue: "(预算来自工作区配置声明)",
|
|
840
|
+
})
|
|
841
|
+
: "",
|
|
826
842
|
}), entry.budgetFallbackReason !== undefined && (_jsxs("span", { "data-testid": `prompt-capacity-perhost-reason-${entry.hostKind}`, children: [" · ", t(`pages.focus.budgetFallbackReason.${entry.budgetFallbackReason}`, {
|
|
827
843
|
defaultValue: entry.budgetFallbackReason,
|
|
828
844
|
})] }))] }, 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", "workbuddy"].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" : host === "workbuddy" ? "WorkBuddy" : "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: "清除选择" }) }))] })] }));
|
|
@@ -85,7 +85,7 @@ function isPromptBudgetFallbackReason(value) {
|
|
|
85
85
|
return isString(value) && PROMPT_BUDGET_FALLBACK_REASONS.has(value);
|
|
86
86
|
}
|
|
87
87
|
function isPromptBudgetCapacitySource(value) {
|
|
88
|
-
return value === 'host_effective_window' || value === 'pi_catalog_exact' || value === 'legacy_fallback';
|
|
88
|
+
return value === 'operator_declared' || value === 'host_effective_window' || value === 'pi_catalog_exact' || value === 'legacy_fallback';
|
|
89
89
|
}
|
|
90
90
|
function isPromptBudgetCapacityStatus(value) {
|
|
91
91
|
return value === 'confirmed' || value === 'unknown';
|
|
@@ -401,6 +401,9 @@
|
|
|
401
401
|
.my-5 {
|
|
402
402
|
margin-block: calc(var(--spacing) * 5);
|
|
403
403
|
}
|
|
404
|
+
.-mt-2 {
|
|
405
|
+
margin-top: calc(var(--spacing) * -2);
|
|
406
|
+
}
|
|
404
407
|
.mt-0\.5 {
|
|
405
408
|
margin-top: calc(var(--spacing) * 0.5);
|
|
406
409
|
}
|
|
@@ -783,6 +786,9 @@
|
|
|
783
786
|
.max-w-\[60ch\] {
|
|
784
787
|
max-width: 60ch;
|
|
785
788
|
}
|
|
789
|
+
.max-w-\[68ch\] {
|
|
790
|
+
max-width: 68ch;
|
|
791
|
+
}
|
|
786
792
|
.max-w-\[85vw\] {
|
|
787
793
|
max-width: 85vw;
|
|
788
794
|
}
|