Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,10 @@ function CapabilityMutationFeedback({ mutationError, onApplied, partialWrite, pr
function CapabilityCatalog({ callbacks, catalog, goalId, notification, onApplied, onNotificationChanged }: CapabilityCatalogProps) {
const { locale, t } = useWorkspaceI18n();
const orderedCapabilities = useMemo(
() => orderCapabilitiesForPresentation(catalog.capabilities, locale),
() => orderCapabilitiesForPresentation(
catalog.capabilities.filter((capability) => capability.available_scopes.includes("goal")),
locale,
),
[catalog.capabilities, locale],
);
const [selectedCapabilityId, setSelectedCapabilityId] = useState(
Expand Down Expand Up @@ -241,7 +244,7 @@ function CapabilityCatalog({ callbacks, catalog, goalId, notification, onApplied
return (
<div className="personal-capability-layout">
<CapabilityCatalogNavigation
capabilities={catalog.capabilities}
capabilities={orderedCapabilities}
locale={locale}
onSelect={setSelectedCapabilityId}
scope="goal"
Expand Down
1 change: 1 addition & 0 deletions docs/development/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ Do not mix marketing pills and application squares in the same control group.
- Theme and language choices use the same two-column grid in every workspace theme.
- Omit secondary descriptive lines under workspace page titles, navigation labels, and display choices. Preserve operational status, errors, and action outcomes.
- Capability navigation shows the localized name and a compact Goal or machine scope badge; omit the secondary internal identifier. Configuration forms use shared spacing and a full-width switch row; optional capability and field explanations live in a collapsed configuration-help section. Keep activation consequences and read-only restrictions visible. Goal and machine editors share the enable-row JSON entry point. Goal JSON accepts only registered editable fields and invalidates the previous preview whenever edited; applying still requires a new reviewed preview.
- Scope each settings catalog to its owner: Goal settings include only capabilities with Goal scope, including Goal-scoped read-only entries. Machine-only capabilities belong in machine or steward settings even when a shared API catalog also describes them.

### Forms

Expand Down
6 changes: 4 additions & 2 deletions examples/personal-workspace-browser/fixture.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,9 @@ export async function installApi(page, { goalSubagentConfigurationEnabled = true
],
capability_catalog: {
schema_version: "capability_configuration_catalog_v0",
capabilities: goalCapabilityCatalog(multiSubagentConfiguration).map((capability) => capability.capability_id === "periodic_report" ? periodicReportCapability({
capabilities: [...machineConfigurationBase.capability_catalog.capabilities.filter(
(capability) => !capability.available_scopes.includes("goal"),
), ...goalCapabilityCatalog(multiSubagentConfiguration).map((capability) => capability.capability_id === "periodic_report" ? periodicReportCapability({
machineCurrent: periodicConfiguration,
effectiveConfiguration: {
schema_version: "capability_configuration_resolution_v0",
Expand All @@ -1209,7 +1211,7 @@ export async function installApi(page, { goalSubagentConfigurationEnabled = true
machine_default_present: true,
effective_revision: "sha256:periodic-effective",
},
}) : capability),
}) : capability)],
},
}, status: 200 });
return;
Expand Down
3 changes: 3 additions & 0 deletions examples/personal-workspace-browser/typed-actions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,9 @@ export const typedActionsScenario = {
if (await page.locator(".personal-workspace-shell:visible").count()) throw new Error("Unified Goal capability action did not open the Settings surface");
await page.getByRole("heading", { level: 2, name: /^周期报告/ }).waitFor({ state: "visible" });
const goalCapabilityOrder = await page.locator(".personal-capability-list button strong").allTextContents();
if (goalCapabilityOrder.includes("管家执行器") || goalCapabilityOrder.includes("管家 Runtime")) {
throw new Error(`Machine-only capabilities leaked into Goal settings: ${JSON.stringify(goalCapabilityOrder)}`);
}
if (await page.locator(".personal-capability-editor-status").count()) throw new Error("Editable Goal settings must not show internal editor-contract notices");
const expectedGoalCapabilities = [
"变更质量验证", "Goal 复核周期", "探索图谱", "探索 Harness", "飞书事件收件箱",
Expand Down
Loading