825 lines
57 KiB
Go
825 lines
57 KiB
Go
//nolint:goconst // Catalog owner and scope labels are stable metadata vocabulary.
|
|
package settingscatalog
|
|
|
|
import "strings"
|
|
|
|
// DefaultDomainDescriptors is the stable cross-domain inventory used by the
|
|
// backend when composition has not supplied a narrower registry.
|
|
func DefaultDomainDescriptors() []DomainDescriptor {
|
|
return []DomainDescriptor{
|
|
profileDomain(),
|
|
profileMCPDomain(),
|
|
agentDomain(),
|
|
userSettingsDomain(),
|
|
workflowDomain(),
|
|
workflowStepDomain(),
|
|
workspaceDomain(),
|
|
repositoryDomain(),
|
|
repositoryScriptDomain(),
|
|
repositorySetDomain(),
|
|
executorDomain(),
|
|
executorProfileDomain(),
|
|
environmentDomain(),
|
|
taskDomain(),
|
|
promptDomain(),
|
|
utilityAgentDomain(),
|
|
editorDomain(),
|
|
notificationProviderDomain(),
|
|
compatibilityIntegrationDomain("issue_integrations", "issue_integration", "Issue integrations", "Use provider-specific Jira, Linear, and Sentry resource types for settings updates."),
|
|
compatibilityIntegrationDomain("code_host_integrations", "code_host_integration", "Code host integrations", "Use provider-specific GitHub, GitLab, and Azure DevOps resource types for settings updates."),
|
|
jiraSettingsDomain(),
|
|
linearSettingsDomain(),
|
|
sentryInstanceDomain(),
|
|
jiraIssueWatchDomain(),
|
|
linearIssueWatchDomain(),
|
|
sentryIssueWatchDomain(),
|
|
githubSettingsDomain(),
|
|
gitlabSettingsDomain(),
|
|
azureDevOpsSettingsDomain(),
|
|
githubReviewWatchDomain(),
|
|
githubIssueWatchDomain(),
|
|
gitlabReviewWatchDomain(),
|
|
gitlabIssueWatchDomain(),
|
|
azureDevOpsWorkItemWatchDomain(),
|
|
azureDevOpsPullRequestWatchDomain(),
|
|
automationDomain(),
|
|
automationTriggerDomain(),
|
|
runtimeFlagDomain(),
|
|
storageMaintenanceDomain(),
|
|
}
|
|
}
|
|
|
|
func compatibilityIntegrationDomain(domain, resourceType, label, description string) DomainDescriptor {
|
|
return DomainDescriptor{
|
|
Domain: domain, ResourceType: resourceType, Label: label, Description: description, Owner: domain,
|
|
Scope: ScopeWorkspace, Target: TargetRules{Scope: ScopeWorkspace, RequiresWorkspaceID: true}, SettingsHref: "/settings/integrations",
|
|
Fields: []FieldDescriptor{{
|
|
Key: resourceType + ".settings", FieldPath: "settings", Label: "Provider settings", Description: description,
|
|
JSONType: "object", Support: SupportReadOnly, Classification: ClassificationException, Owner: domain,
|
|
ExceptionReason: "Provider-specific resource types preserve the provider's validation and workspace boundary.",
|
|
Recovery: "Use the provider-specific settings resource returned by search or target lookup.",
|
|
}},
|
|
}
|
|
}
|
|
|
|
func integrationReadOnly(resourceType, path, label, description, jsonType, owner string) FieldDescriptor {
|
|
return FieldDescriptor{
|
|
Key: resourceType + "." + path, FieldPath: path, Label: label, Description: description, JSONType: jsonType,
|
|
Support: SupportReadOnly, Classification: ClassificationComputed, Owner: owner,
|
|
}
|
|
}
|
|
|
|
func integrationWritable(resourceType, path, label, description, jsonType, owner, authority string) FieldDescriptor {
|
|
return domainWritable(resourceType, path, label, description, jsonType, owner, authority)
|
|
}
|
|
|
|
func integrationNullableWritable(resourceType, path, label, description, jsonType, owner, authority string) FieldDescriptor {
|
|
field := integrationWritable(resourceType, path, label, description, jsonType, owner, authority)
|
|
field.Nullable = true
|
|
return field
|
|
}
|
|
|
|
func integrationDomain(domain, resourceType, label, description, owner string, target TargetRules, fields ...FieldDescriptor) DomainDescriptor {
|
|
return supportedDomain(domain, resourceType, label, description, owner, target.Scope, target, fields...)
|
|
}
|
|
|
|
func workspaceIntegrationTarget() TargetRules {
|
|
return TargetRules{Scope: ScopeWorkspace, RequiresWorkspaceID: true}
|
|
}
|
|
|
|
func watchTarget() TargetRules {
|
|
return TargetRules{Scope: ScopeResource, RequiresResourceID: true, RequiresWorkspaceID: true, AllowsWorkspaceID: true}
|
|
}
|
|
|
|
func jiraSettingsDomain() DomainDescriptor {
|
|
owner := "jira"
|
|
target := workspaceIntegrationTarget()
|
|
return integrationDomain("issue_integrations", "jira_settings", "Jira settings", "Noncredential Jira defaults for one workspace.", owner, target,
|
|
integrationWritable("jira_settings", "defaultProjectKey", "Default project", "Default Jira project key for issue workflows.", "string", owner, "workspace.manage"),
|
|
integrationReadOnly("jira_settings", "siteUrl", "Site URL", "Configured Jira site identity. Credential and identity changes use the connection flow.", "string", owner),
|
|
integrationReadOnly("jira_settings", "email", "Account email", "Configured Jira account metadata.", "string", owner),
|
|
integrationReadOnly("jira_settings", "authMethod", "Authentication method", "Configured Jira authentication method.", "string", owner),
|
|
integrationReadOnly("jira_settings", "instanceType", "Instance type", "Configured Jira deployment type.", "string", owner),
|
|
integrationReadOnly("jira_settings", "hasSecret", "Credential present", "Whether a credential is enrolled, without exposing it.", "boolean", owner),
|
|
)
|
|
}
|
|
|
|
func linearSettingsDomain() DomainDescriptor {
|
|
owner := "linear"
|
|
target := workspaceIntegrationTarget()
|
|
return integrationDomain("issue_integrations", "linear_settings", "Linear settings", "Noncredential Linear defaults for one workspace.", owner, target,
|
|
integrationWritable("linear_settings", "defaultTeamKey", "Default team", "Default Linear team key for issue workflows.", "string", owner, "workspace.manage"),
|
|
integrationReadOnly("linear_settings", "authMethod", "Authentication method", "Configured Linear authentication method.", "string", owner),
|
|
integrationReadOnly("linear_settings", "orgSlug", "Organization slug", "Computed Linear organization metadata.", "string", owner),
|
|
integrationReadOnly("linear_settings", "hasSecret", "Credential present", "Whether a credential is enrolled, without exposing it.", "boolean", owner),
|
|
)
|
|
}
|
|
|
|
func sentryInstanceDomain() DomainDescriptor {
|
|
owner := "sentry"
|
|
return integrationDomain("issue_integrations", "sentry_instance", "Sentry instances", "Named noncredential Sentry instance settings.", owner, TargetRules{Scope: ScopeResource, RequiresResourceID: true, RequiresWorkspaceID: true, AllowsWorkspaceID: true},
|
|
integrationWritable("sentry_instance", "name", "Name", "Display name for the Sentry instance.", "string", owner, "workspace.manage"),
|
|
integrationReadOnly("sentry_instance", "url", "URL", "Configured Sentry instance identity. Connection changes use the interactive flow.", "string", owner),
|
|
integrationReadOnly("sentry_instance", "authMethod", "Authentication method", "Configured Sentry authentication method.", "string", owner),
|
|
integrationReadOnly("sentry_instance", "hasSecret", "Credential present", "Whether a credential is enrolled, without exposing it.", "boolean", owner),
|
|
)
|
|
}
|
|
|
|
func issueWatchFields(resourceType, owner, filterPath, filterType string) []FieldDescriptor {
|
|
fields := []FieldDescriptor{
|
|
integrationWritable(resourceType, "workflowId", "Workflow", "Workflow that receives matching issues.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "workflowStepId", "Workflow step", "Workflow step that receives matching issues.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "repositoryId", "Repository", "Optional repository binding for created tasks.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "baseBranch", "Base branch", "Base branch for the optional repository binding.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "agentProfileId", "Agent profile", "Profile used for created tasks.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "executorProfileId", "Executor profile", "Executor profile used for created tasks.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "prompt", "Prompt", "Prompt added to created tasks.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "enabled", "Enabled", "Whether background polling is enabled.", "boolean", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "pollIntervalSeconds", "Poll interval", "Background polling interval in seconds.", "integer", owner, "workspace.manage"),
|
|
integrationNullableWritable(resourceType, "maxInflightTasks", "Concurrent task limit", "Maximum open tasks created by this watch, or null for unlimited.", "integer", owner, "workspace.manage"),
|
|
}
|
|
if filterPath != "" {
|
|
fields = append(fields, integrationWritable(resourceType, filterPath, "Filter", "Provider-specific issue filter.", filterType, owner, "workspace.manage"))
|
|
}
|
|
return fields
|
|
}
|
|
|
|
func jiraIssueWatchDomain() DomainDescriptor {
|
|
return integrationDomain("issue_integrations", "jira_issue_watch", "Jira issue watches", "Jira issue watch schedules and task bindings.", "jira", watchTarget(), issueWatchFields("jira_issue_watch", "jira", "jql", "string")...)
|
|
}
|
|
|
|
func linearIssueWatchDomain() DomainDescriptor {
|
|
fields := issueWatchFields("linear_issue_watch", "linear", "filter", "object")
|
|
fields = append(fields, integrationWritable("linear_issue_watch", "sortBy", "Sort order", "Order in which matching Linear issues are dispatched.", "string", "linear", "workspace.manage"))
|
|
return integrationDomain("issue_integrations", "linear_issue_watch", "Linear issue watches", "Linear issue watch schedules and task bindings.", "linear", watchTarget(), fields...)
|
|
}
|
|
|
|
func sentryIssueWatchDomain() DomainDescriptor {
|
|
return integrationDomain("issue_integrations", "sentry_issue_watch", "Sentry issue watches", "Sentry issue watch schedules and task bindings.", "sentry", watchTarget(), issueWatchFields("sentry_issue_watch", "sentry", "filter", "object")...)
|
|
}
|
|
|
|
func githubSettingsDomain() DomainDescriptor {
|
|
owner := "github"
|
|
return integrationDomain("code_host_integrations", "github_settings", "GitHub settings", "Noncredential GitHub scope and query preferences for one workspace.", owner, workspaceIntegrationTarget(),
|
|
integrationWritable("github_settings", "task_git_credentials_mode", "Task Git credentials", "Credential routing mode for task worktrees.", "string", owner, "workspace.manage"),
|
|
integrationWritable("github_settings", "repo_scope_mode", "Repository scope mode", "Repository scope selection mode.", "string", owner, "workspace.manage"),
|
|
integrationWritable("github_settings", "repo_scope_orgs", "Organizations", "Organization allowlist for repository scope.", "array", owner, "workspace.manage"),
|
|
integrationWritable("github_settings", "repo_scope_repos", "Repositories", "Repository allowlist for repository scope.", "array", owner, "workspace.manage"),
|
|
integrationWritable("github_settings", "saved_presets", "Saved presets", "Workspace-scoped GitHub action presets.", "object", owner, "workspace.manage"),
|
|
integrationWritable("github_settings", "default_query_presets", "Default query presets", "Workspace-scoped GitHub query presets.", "object", owner, "workspace.manage"),
|
|
)
|
|
}
|
|
|
|
func gitlabSettingsDomain() DomainDescriptor {
|
|
owner := "gitlab"
|
|
return integrationDomain("code_host_integrations", "gitlab_settings", "GitLab settings", "Configured GitLab workspace connection metadata.", owner, workspaceIntegrationTarget(),
|
|
integrationReadOnly("gitlab_settings", "host", "Host", "Configured GitLab host. Connection identity changes use the interactive flow.", "string", owner),
|
|
integrationReadOnly("gitlab_settings", "auth_method", "Authentication method", "Configured GitLab authentication method.", "string", owner),
|
|
integrationReadOnly("gitlab_settings", "username", "Username", "Last authenticated GitLab username.", "string", owner),
|
|
)
|
|
}
|
|
|
|
func azureDevOpsSettingsDomain() DomainDescriptor {
|
|
owner := "azuredevops"
|
|
return integrationDomain("code_host_integrations", "azure_devops_settings", "Azure DevOps settings", "Noncredential Azure DevOps query and action presets for one workspace.", owner, workspaceIntegrationTarget(),
|
|
integrationWritable("azure_devops_settings", "workItemQueries", "Work item queries", "Saved work item query presets.", "array", owner, "workspace.manage"),
|
|
integrationWritable("azure_devops_settings", "pullRequestQueries", "Pull request queries", "Saved pull request query presets.", "array", owner, "workspace.manage"),
|
|
integrationWritable("azure_devops_settings", "workItemActions", "Work item actions", "Saved work item action presets.", "array", owner, "workspace.manage"),
|
|
integrationWritable("azure_devops_settings", "pullRequestActions", "Pull request actions", "Saved pull request action presets.", "array", owner, "workspace.manage"),
|
|
)
|
|
}
|
|
|
|
func codeHostWatchFields(resourceType, owner string, projects bool, issue, camelCase bool) []FieldDescriptor {
|
|
fields := []FieldDescriptor{
|
|
integrationWritable(resourceType, codeHostWatchPath("workflow_id", camelCase), "Workflow", "Workflow that receives matching items.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, codeHostWatchPath("workflow_step_id", camelCase), "Workflow step", "Workflow step that receives matching items.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, codeHostWatchPath("agent_profile_id", camelCase), "Agent profile", "Profile used for created tasks.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, codeHostWatchPath("executor_profile_id", camelCase), "Executor profile", "Executor profile used for created tasks.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "prompt", "Prompt", "Prompt added to created tasks.", "string", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, "enabled", "Enabled", "Whether background polling is enabled.", "boolean", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, codeHostWatchPath("poll_interval_seconds", camelCase), "Poll interval", "Background polling interval in seconds.", "integer", owner, "workspace.manage"),
|
|
integrationWritable(resourceType, codeHostWatchPath("cleanup_policy", camelCase), "Cleanup policy", "Policy for tasks created by this watch.", "string", owner, "workspace.manage"),
|
|
integrationNullableWritable(resourceType, codeHostWatchPath("max_inflight_tasks", camelCase), "Concurrent task limit", "Maximum open tasks created by this watch, or null for unlimited.", "integer", owner, "workspace.manage"),
|
|
}
|
|
if projects {
|
|
fields = append(fields, integrationWritable(resourceType, "projects", "Projects", "Provider project filters.", "array", owner, "workspace.manage"))
|
|
} else {
|
|
fields = append(fields, integrationWritable(resourceType, "repos", "Repositories", "Provider repository filters.", "array", owner, "workspace.manage"))
|
|
}
|
|
if issue {
|
|
fields = append(fields, integrationWritable(resourceType, "labels", "Labels", "Issue label filters.", "array", owner, "workspace.manage"))
|
|
fields = append(fields, integrationWritable(resourceType, "custom_query", "Custom query", "Provider-specific issue query.", "string", owner, "workspace.manage"))
|
|
} else {
|
|
fields = append(fields, integrationWritable(resourceType, "review_scope", "Review scope", "Review assignment scope.", "string", owner, "workspace.manage"))
|
|
fields = append(fields, integrationWritable(resourceType, "custom_query", "Custom query", "Provider-specific review query.", "string", owner, "workspace.manage"))
|
|
}
|
|
return fields
|
|
}
|
|
|
|
func codeHostWatchPath(snake string, camelCase bool) string {
|
|
if !camelCase {
|
|
return snake
|
|
}
|
|
parts := strings.Split(snake, "_")
|
|
for index := 1; index < len(parts); index++ {
|
|
if parts[index] == "" {
|
|
continue
|
|
}
|
|
parts[index] = strings.ToUpper(parts[index][:1]) + parts[index][1:]
|
|
}
|
|
return strings.Join(parts, "")
|
|
}
|
|
|
|
func githubReviewWatchDomain() DomainDescriptor {
|
|
fields := withoutIntegrationFields(codeHostWatchFields("github_review_watch", "github", false, false, false), "max_inflight_tasks")
|
|
return integrationDomain("code_host_integrations", "github_review_watch", "GitHub review watches", "GitHub review watch schedules and task bindings.", "github", watchTarget(), fields...)
|
|
}
|
|
|
|
func githubIssueWatchDomain() DomainDescriptor {
|
|
fields := withoutIntegrationFields(codeHostWatchFields("github_issue_watch", "github", false, true, false), "max_inflight_tasks")
|
|
return integrationDomain("code_host_integrations", "github_issue_watch", "GitHub issue watches", "GitHub issue watch schedules and task bindings.", "github", watchTarget(), fields...)
|
|
}
|
|
|
|
func gitlabReviewWatchDomain() DomainDescriptor {
|
|
return integrationDomain("code_host_integrations", "gitlab_review_watch", "GitLab review watches", "GitLab review watch schedules and task bindings.", "gitlab", watchTarget(), codeHostWatchFields("gitlab_review_watch", "gitlab", true, false, false)...)
|
|
}
|
|
|
|
func gitlabIssueWatchDomain() DomainDescriptor {
|
|
return integrationDomain("code_host_integrations", "gitlab_issue_watch", "GitLab issue watches", "GitLab issue watch schedules and task bindings.", "gitlab", watchTarget(), codeHostWatchFields("gitlab_issue_watch", "gitlab", true, true, false)...)
|
|
}
|
|
|
|
func azureDevOpsWorkItemWatchDomain() DomainDescriptor {
|
|
fields := withoutIntegrationFields(codeHostWatchFields("azure_devops_work_item_watch", "azuredevops", false, true, true), "repos", "labels", "custom_query")
|
|
fields = append(fields,
|
|
integrationWritable("azure_devops_work_item_watch", "projectId", "Project", "Azure DevOps project filter.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_work_item_watch", "wiql", "WIQL", "Azure Boards query.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_work_item_watch", "repositoryId", "Repository", "Optional repository binding.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_work_item_watch", "baseBranch", "Base branch", "Base branch for the optional repository binding.", "string", "azuredevops", "workspace.manage"),
|
|
)
|
|
return integrationDomain("code_host_integrations", "azure_devops_work_item_watch", "Azure work item watches", "Azure work item watch schedules and task bindings.", "azuredevops", watchTarget(), fields...)
|
|
}
|
|
|
|
func azureDevOpsPullRequestWatchDomain() DomainDescriptor {
|
|
fields := withoutIntegrationFields(codeHostWatchFields("azure_devops_pull_request_watch", "azuredevops", false, false, true), "repos", "review_scope", "custom_query")
|
|
fields = append(fields,
|
|
integrationWritable("azure_devops_pull_request_watch", "projectId", "Project", "Azure DevOps project filter.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_pull_request_watch", "azureRepositoryId", "Azure repository", "Azure Repos repository filter.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_pull_request_watch", "status", "Status", "Pull request status filter.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_pull_request_watch", "creatorId", "Creator", "Pull request creator filter.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_pull_request_watch", "reviewerId", "Reviewer", "Pull request reviewer filter.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_pull_request_watch", "repositoryId", "Repository", "Optional repository binding.", "string", "azuredevops", "workspace.manage"),
|
|
integrationWritable("azure_devops_pull_request_watch", "baseBranch", "Base branch", "Base branch for the optional repository binding.", "string", "azuredevops", "workspace.manage"),
|
|
)
|
|
return integrationDomain("code_host_integrations", "azure_devops_pull_request_watch", "Azure pull request watches", "Azure pull request watch schedules and task bindings.", "azuredevops", watchTarget(), fields...)
|
|
}
|
|
|
|
func withoutIntegrationFields(fields []FieldDescriptor, paths ...string) []FieldDescriptor {
|
|
remove := make(map[string]struct{}, len(paths))
|
|
for _, path := range paths {
|
|
remove[path] = struct{}{}
|
|
}
|
|
filtered := make([]FieldDescriptor, 0, len(fields))
|
|
for _, field := range fields {
|
|
if _, skip := remove[field.FieldPath]; !skip {
|
|
filtered = append(filtered, field)
|
|
}
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
func agentDomain() DomainDescriptor {
|
|
owner := "agent-settings"
|
|
return DomainDescriptor{
|
|
Domain: "agents", ResourceType: "agent", Label: "Agent definitions",
|
|
Description: "Saved agent definition metadata and MCP connection settings.", Owner: owner,
|
|
Scope: ScopeResource, Target: TargetRules{Scope: ScopeResource, RequiresResourceID: true, AllowsWorkspaceID: true},
|
|
SettingsHref: "/settings/agents",
|
|
Operations: []OperationDescriptor{{Name: "update", Binding: "agent-settings.agent.update", Authority: "org.config.manage"}},
|
|
Fields: []FieldDescriptor{
|
|
{Key: "agent.name", FieldPath: "name", Label: "Name", Description: "Stable agent definition name.", JSONType: "string", Support: SupportReadOnly, Classification: ClassificationComputed, Owner: owner},
|
|
{Key: "agent.workspace_id", FieldPath: "workspace_id", Label: "Workspace", Description: "Owning workspace, when the definition is workspace-scoped.", JSONType: "string", Nullable: true, Support: SupportReadOnly, Classification: ClassificationComputed, Owner: owner},
|
|
domainWritable("agent", "supports_mcp", "Supports MCP", "Whether the agent definition supports MCP configuration.", "boolean", owner, "org.config.manage"),
|
|
func() FieldDescriptor {
|
|
field := domainWritable("agent", "mcp_config_path", "MCP configuration path", "Path used by the agent definition for MCP configuration.", "string", owner, "org.config.manage")
|
|
field.Nullable = true
|
|
return field
|
|
}(),
|
|
{Key: "agent.tui_config", FieldPath: "tui_config", Label: "TUI definition", Description: "Custom TUI definition owned by the explicit agent lifecycle surface.", JSONType: "object", Support: SupportReadOnly, Classification: ClassificationComputed, Owner: owner},
|
|
{Key: "agent.profiles", FieldPath: "profiles", Label: "Profiles", Description: "Profiles attached to this agent definition.", JSONType: "array", Support: SupportReadOnly, Classification: ClassificationComputed, Owner: owner},
|
|
{Key: "agent.capability_status", FieldPath: "capability_status", Label: "Capability status", Description: "Computed host capability status.", JSONType: "string", Support: SupportReadOnly, Classification: ClassificationComputed, Owner: owner},
|
|
{Key: "agent.capability_error", FieldPath: "capability_error", Label: "Capability error", Description: "Computed host capability diagnostic.", JSONType: "string", Support: SupportReadOnly, Classification: ClassificationComputed, Owner: owner},
|
|
},
|
|
}
|
|
}
|
|
|
|
func supportedDomain(domain, resourceType, label, description, owner string, scope Scope, target TargetRules, fields ...FieldDescriptor) DomainDescriptor {
|
|
authority := ""
|
|
for _, field := range fields {
|
|
if field.Writable && field.Authority != "" {
|
|
authority = field.Authority
|
|
break
|
|
}
|
|
}
|
|
operations := []OperationDescriptor(nil)
|
|
if authority != "" {
|
|
operations = []OperationDescriptor{{Name: "update", Binding: owner + "." + resourceType + ".update", Authority: authority}}
|
|
}
|
|
return DomainDescriptor{
|
|
Domain: domain, ResourceType: resourceType, Label: label, Description: description, Owner: owner,
|
|
Scope: scope, Target: target, Fields: fields,
|
|
Operations: operations,
|
|
SettingsHref: "/settings",
|
|
}
|
|
}
|
|
|
|
func domainWritable(resourceType, path, label, description, jsonType, owner, authority string) FieldDescriptor {
|
|
return FieldDescriptor{
|
|
Key: resourceType + "." + path, FieldPath: path, Label: label, Description: description, JSONType: jsonType,
|
|
Support: SupportSupported, Classification: ClassificationWritable, Owner: owner, Writable: true,
|
|
Validator: owner + "." + resourceType, Authority: authority, SettingsHref: "/settings",
|
|
}
|
|
}
|
|
|
|
func domainSensitiveWritable(resourceType, path, label, description, jsonType, owner, authority string) FieldDescriptor {
|
|
field := domainWritable(resourceType, path, label, description, jsonType, owner, authority)
|
|
field.Sensitive = true
|
|
return field
|
|
}
|
|
|
|
func exceptionField(resourceType, path, label, description, jsonType, owner, recovery string) FieldDescriptor {
|
|
return FieldDescriptor{
|
|
Key: resourceType + "." + path, FieldPath: path, Label: label, Description: description,
|
|
JSONType: jsonType, Support: SupportException, Classification: ClassificationException,
|
|
Owner: owner, SettingsHref: "/settings", ExceptionReason: description, Recovery: recovery,
|
|
}
|
|
}
|
|
|
|
func lifecycleException(resourceType, path, label, description, jsonType, owner, recovery string) FieldDescriptor {
|
|
field := exceptionField(resourceType, path, label, description, jsonType, owner, recovery)
|
|
field.Classification = ClassificationAction
|
|
return field
|
|
}
|
|
|
|
func workflowDomain() DomainDescriptor {
|
|
owner := "workflow"
|
|
target := TargetRules{Scope: ScopeResource, RequiresResourceID: true, AllowsWorkspaceID: true}
|
|
return supportedDomain("workflows", "workflow", "Workflows", "Saved workflow definitions.", owner, ScopeResource, target,
|
|
domainWritable("workflow", "name", "Name", "Workflow name.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow", "description", "Description", "Workflow description.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow", "prompt", "Prompt", "Workflow-level instructions.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow", "agent_profile_id", "Agent profile", "Profile used by the workflow when configured.", "string", owner, "workspace.manage"),
|
|
)
|
|
}
|
|
|
|
func workflowStepDomain() DomainDescriptor {
|
|
owner := "workflow"
|
|
fields := []FieldDescriptor{
|
|
domainWritable("workflow_step", "name", "Name", "Step name.", "string", owner, "workspace.manage"),
|
|
lifecycleException("workflow_step", "position", "Position", "Step ordering is controlled by the workflow reorder action.", "integer", owner, "Use the workflow step reorder action."),
|
|
domainWritable("workflow_step", "color", "Color", "Step display color.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "prompt", "Prompt", "Step instructions.", "string", owner, "workspace.manage"),
|
|
workflowEventsField(owner),
|
|
domainWritable("workflow_step", "allow_manual_move", "Manual move", "Whether users may move tasks into this step.", "boolean", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "is_start_step", "Start step", "Whether this is the workflow start step.", "boolean", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "show_in_command_panel", "Command panel", "Whether the step appears in the command panel.", "boolean", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "auto_archive_after_hours", "Auto archive", "Hours before tasks in this step are archived.", "integer", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "agent_profile_id", "Agent profile", "Profile bound to this step.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "profile_session_start_policy", "Session start policy", "Session policy when entering a profile-bound step.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "profile_session_end_policy", "Session end policy", "Session policy when leaving a profile-bound step.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "wip_limit", "WIP limit", "Maximum admitted work in this step.", "integer", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "pull_from_step_id", "Pull source", "Step that supplies work to this step.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "stage_type", "Stage type", "Workflow stage type.", "string", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "auto_advance_requires_signal", "Completion signal", "Require an explicit completion signal before advancing.", "boolean", owner, "workspace.manage"),
|
|
domainWritable("workflow_step", "cancel_triggers_turn_complete", "Cancel transition", "Whether cancellation runs turn-complete actions.", "boolean", owner, "workspace.manage"),
|
|
}
|
|
return supportedDomain("workflows", "workflow_step", "Workflow steps", "Editable steps in a saved workflow.", owner, ScopeResource, targetRulesResourceWorkspace(), fields...)
|
|
}
|
|
|
|
func workflowEventsField(owner string) FieldDescriptor {
|
|
field := domainWritable("workflow_step", "events", "Events", "Validated step event actions and bindings.", "object", owner, "workspace.manage")
|
|
triggers := []string{
|
|
"on_enter", "on_turn_start", "on_turn_complete", "on_exit", "on_comment",
|
|
"on_blocker_resolved", "on_children_completed", "on_approval_resolved", "on_heartbeat",
|
|
"on_budget_alert", "on_agent_error",
|
|
}
|
|
properties := make(map[string]any, len(triggers))
|
|
for _, trigger := range triggers {
|
|
properties[trigger] = map[string]any{
|
|
"type": "array",
|
|
"items": map[string]any{"type": "object", "additionalProperties": false, "properties": map[string]any{
|
|
"type": map[string]any{"type": "string"},
|
|
"config": map[string]any{"type": "object", "additionalProperties": true},
|
|
}},
|
|
}
|
|
}
|
|
field.Schema = map[string]any{"type": "object", "additionalProperties": false, "properties": properties}
|
|
return field
|
|
}
|
|
|
|
func targetRulesResourceWorkspace() TargetRules {
|
|
return TargetRules{Scope: ScopeResource, RequiresResourceID: true, AllowsWorkspaceID: true}
|
|
}
|
|
|
|
func workspaceDomain() DomainDescriptor {
|
|
owner := "workspace"
|
|
return supportedDomain("workspaces", "workspace", "Workspaces", "Workspace defaults and display settings.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("workspace", "name", "Name", "Workspace name.", "string", owner, "workspace.manage"),
|
|
domainWritable("workspace", "description", "Description", "Workspace description.", "string", owner, "workspace.manage"),
|
|
domainWritable("workspace", "default_executor_id", "Default executor", "Default execution target.", "string", owner, "workspace.manage"),
|
|
domainWritable("workspace", "default_environment_id", "Default environment", "Default runtime environment.", "string", owner, "workspace.manage"),
|
|
domainWritable("workspace", "default_agent_profile_id", "Default agent profile", "Default profile for new work.", "string", owner, "workspace.manage"),
|
|
domainWritable("workspace", "default_config_agent_profile_id", "Default configuration profile", "Profile used for configuration work.", "string", owner, "workspace.manage"),
|
|
)
|
|
}
|
|
|
|
func repositoryDomain() DomainDescriptor {
|
|
owner := "workspace"
|
|
paths := []struct{ path, label, typ string }{
|
|
{"name", "Name", "string"}, {"source_type", "Source type", "string"}, {"local_path", "Local path", "string"},
|
|
{"provider", "Provider", "string"}, {"provider_repo_id", "Provider repository ID", "string"}, {"provider_host", "Provider host", "string"},
|
|
{"provider_scope", "Provider scope", "string"}, {"provider_owner", "Provider owner", "string"}, {"provider_name", "Provider name", "string"},
|
|
{"remote_url", "Remote URL", "string"}, {"default_branch", "Default branch", "string"}, {"worktree_branch_prefix", "Branch prefix", "string"},
|
|
{"worktree_branch_template", "Branch template", "string"}, {"pull_before_worktree", "Pull before worktree", "boolean"},
|
|
{"setup_script", "Setup script", "string"}, {"cleanup_script", "Cleanup script", "string"}, {"dev_script", "Development script", "string"},
|
|
{"copy_files", "Copy files", "string"}, {"secret_bindings", "Secret bindings", "array"},
|
|
}
|
|
fields := make([]FieldDescriptor, 0, len(paths))
|
|
for _, item := range paths {
|
|
field := domainWritable("repository", item.path, item.label, "Repository setting.", item.typ, owner, "workspace.manage")
|
|
if item.path == "secret_bindings" {
|
|
field.Sensitive = true
|
|
}
|
|
fields = append(fields, field)
|
|
}
|
|
return supportedDomain("workspaces", "repository", "Repositories", "Workspace repository settings.", owner, ScopeResource, targetRulesResourceWorkspace(), fields...)
|
|
}
|
|
|
|
func repositoryScriptDomain() DomainDescriptor {
|
|
owner := "workspace"
|
|
return supportedDomain("workspaces", "repository_script", "Repository scripts", "Custom repository commands.", owner, ScopeResource, targetRulesResourceWorkspace(),
|
|
domainWritable("repository_script", "name", "Name", "Script name.", "string", owner, "workspace.manage"),
|
|
domainWritable("repository_script", "command", "Command", "Script command.", "string", owner, "workspace.manage"),
|
|
lifecycleException("repository_script", "position", "Position", "Script ordering is controlled by the repository script reorder action.", "integer", owner, "Use the repository script reorder action."),
|
|
)
|
|
}
|
|
|
|
func repositorySetDomain() DomainDescriptor {
|
|
owner := "workspace"
|
|
return supportedDomain("workspaces", "repository_set", "Repository sets", "Reusable repository selections.", owner, ScopeResource, targetRulesResourceWorkspace(),
|
|
domainWritable("repository_set", "name", "Name", "Repository set name.", "string", owner, "workspace.manage"),
|
|
domainWritable("repository_set", "description", "Description", "Repository set description.", "string", owner, "workspace.manage"),
|
|
domainWritable("repository_set", "repository_ids", "Repositories", "Ordered repository membership.", "array", owner, "workspace.manage"),
|
|
)
|
|
}
|
|
|
|
func executorDomain() DomainDescriptor {
|
|
owner := "execution"
|
|
return supportedDomain("execution", "executor", "Executors", "Execution target settings.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("executor", "name", "Name", "Executor name.", "string", owner, "execution.manage"),
|
|
domainWritable("executor", "type", "Type", "Executor runtime type.", "string", owner, "execution.manage"),
|
|
domainWritable("executor", "status", "Status", "Whether the executor accepts work.", "string", owner, "execution.manage"),
|
|
domainWritable("executor", "resumable", "Resumable", "Whether sessions can resume on this executor.", "boolean", owner, "execution.manage"),
|
|
domainSensitiveWritable("executor", "config", "Configuration", "Validated executor configuration.", "object", owner, "execution.manage"),
|
|
)
|
|
}
|
|
|
|
func executorProfileDomain() DomainDescriptor {
|
|
owner := "execution"
|
|
return supportedDomain("execution", "executor_profile", "Executor profiles", "Named executor presets.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("executor_profile", "name", "Name", "Profile name.", "string", owner, "execution.manage"),
|
|
domainWritable("executor_profile", "mcp_policy", "MCP policy", "MCP policy for this executor profile.", "string", owner, "execution.manage"),
|
|
domainWritable("executor_profile", "config", "Configuration", "Validated executor profile configuration.", "object", owner, "execution.manage"),
|
|
domainWritable("executor_profile", "prepare_script", "Prepare script", "Preparation command.", "string", owner, "execution.manage"),
|
|
domainWritable("executor_profile", "cleanup_script", "Cleanup script", "Cleanup command.", "string", owner, "execution.manage"),
|
|
domainSensitiveWritable("executor_profile", "env_vars", "Environment variables", "Environment values or secret references.", "array", owner, "execution.manage"),
|
|
)
|
|
}
|
|
|
|
func environmentDomain() DomainDescriptor {
|
|
owner := "execution"
|
|
return supportedDomain("execution", "environment", "Environments", "Execution environment definitions.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("environment", "name", "Name", "Environment name.", "string", owner, "execution.manage"),
|
|
domainWritable("environment", "kind", "Kind", "Environment kind.", "string", owner, "execution.manage"),
|
|
domainWritable("environment", "worktree_root", "Worktree root", "Worktree root path.", "string", owner, "execution.manage"),
|
|
domainWritable("environment", "image_tag", "Image tag", "Container image tag.", "string", owner, "execution.manage"),
|
|
domainWritable("environment", "dockerfile", "Dockerfile", "Dockerfile content.", "string", owner, "execution.manage"),
|
|
domainWritable("environment", "build_config", "Build configuration", "Validated build options.", "object", owner, "execution.manage"),
|
|
)
|
|
}
|
|
|
|
func taskDomain() DomainDescriptor {
|
|
owner := "task"
|
|
return supportedDomain("tasks", "task", "Tasks", "Permitted saved task configuration.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true, AllowsWorkspaceID: true},
|
|
domainWritable("task", "title", "Title", "Task title.", "string", owner, "task.manage"),
|
|
domainWritable("task", "description", "Description", "Task description.", "string", owner, "task.manage"),
|
|
domainWritable("task", "priority", "Priority", "Task priority.", "string", owner, "task.manage"),
|
|
lifecycleException("task", "workflow_step_id", "Workflow step", "Task movement is controlled by the task lifecycle action.", "string", owner, "Use the task move action."),
|
|
lifecycleException("task", "position", "Position", "Task ordering is controlled by the task reorder action.", "integer", owner, "Use the task reorder action."),
|
|
exceptionField("task", "metadata", "Metadata", "Open-ended task metadata is controlled by domain-specific task operations.", "object", owner, "Use the task metadata operation for a known metadata key."),
|
|
)
|
|
}
|
|
|
|
func promptDomain() DomainDescriptor {
|
|
owner := "prompts"
|
|
return supportedDomain("prompts", "prompt", "Saved prompts", "Saved prompt definitions.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("prompt", "name", "Name", "Prompt name.", "string", owner, "prompt.manage"),
|
|
domainWritable("prompt", "content", "Content", "Prompt content.", "string", owner, "prompt.manage"),
|
|
)
|
|
}
|
|
|
|
func utilityAgentDomain() DomainDescriptor {
|
|
owner := "utilities"
|
|
return supportedDomain("utilities", "utility_agent", "Utility agents", "Utility agent definitions.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("utility_agent", "name", "Name", "Utility name.", "string", owner, "utility.manage"),
|
|
domainWritable("utility_agent", "description", "Description", "Utility description.", "string", owner, "utility.manage"),
|
|
domainWritable("utility_agent", "prompt", "Prompt", "Utility prompt template.", "string", owner, "utility.manage"),
|
|
domainWritable("utility_agent", "agent_id", "Agent", "Inference agent identifier.", "string", owner, "utility.manage"),
|
|
domainWritable("utility_agent", "model", "Model", "Default model.", "string", owner, "utility.manage"),
|
|
domainWritable("utility_agent", "agent_profile_id", "Agent profile", "Profile binding.", "string", owner, "utility.manage"),
|
|
domainWritable("utility_agent", "profile_binding_state", "Profile binding state", "Profile inheritance state.", "string", owner, "utility.manage"),
|
|
domainWritable("utility_agent", "enabled", "Enabled", "Whether the utility is available.", "boolean", owner, "utility.manage"),
|
|
)
|
|
}
|
|
|
|
func editorDomain() DomainDescriptor {
|
|
owner := "editors"
|
|
return supportedDomain("editors", "editor", "Editor definitions", "Custom editor definitions.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("editor", "name", "Name", "Editor display name.", "string", owner, "editor.manage"),
|
|
domainWritable("editor", "kind", "Kind", "Custom editor kind.", "string", owner, "editor.manage"),
|
|
domainWritable("editor", "config", "Configuration", "Validated editor configuration.", "object", owner, "editor.manage"),
|
|
domainWritable("editor", "enabled", "Enabled", "Whether the editor can be selected.", "boolean", owner, "editor.manage"),
|
|
)
|
|
}
|
|
|
|
func notificationProviderDomain() DomainDescriptor {
|
|
owner := "notifications"
|
|
return supportedDomain("notifications", "notification_provider", "Notification providers", "Notification provider settings and subscriptions.", owner, ScopeResource, TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
domainWritable("notification_provider", "name", "Name", "Provider name.", "string", owner, "notification.manage"),
|
|
domainWritable("notification_provider", "type", "Type", "Provider type.", "string", owner, "notification.manage"),
|
|
domainSensitiveWritable("notification_provider", "config", "Configuration", "Validated provider configuration.", "object", owner, "notification.manage"),
|
|
domainWritable("notification_provider", "enabled", "Enabled", "Whether notifications are enabled.", "boolean", owner, "notification.manage"),
|
|
domainWritable("notification_provider", "events", "Events", "Subscribed event types.", "array", owner, "notification.manage"),
|
|
)
|
|
}
|
|
|
|
func automationDomain() DomainDescriptor {
|
|
owner := "automations"
|
|
return supportedDomain("automations", "automation", "Workspace automations", "Workspace automation definitions.", owner, ScopeWorkspace, TargetRules{Scope: ScopeWorkspace, RequiresResourceID: true, AllowsWorkspaceID: true},
|
|
domainWritable("automation", "name", "Name", "Automation name.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "description", "Description", "Automation description.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "workflow_id", "Workflow", "Workflow binding.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "workflow_step_id", "Workflow step", "Workflow step binding.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "agent_profile_id", "Agent profile", "Agent profile binding.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "executor_profile_id", "Executor profile", "Executor profile binding.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "repositories", "Repositories", "Repository and base-branch selection.", "array", owner, "workspace.manage"),
|
|
domainWritable("automation", "prompt", "Prompt", "Automation prompt template.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "task_title_template", "Task title template", "Generated task title template.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "enabled", "Enabled", "Whether the automation is active.", "boolean", owner, "workspace.manage"),
|
|
domainWritable("automation", "max_concurrent_runs", "Concurrent runs", "Maximum simultaneous runs.", "integer", owner, "workspace.manage"),
|
|
domainWritable("automation", "continuation_policy", "Continuation policy", "How automation runs reuse tasks.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "task_mode", "Task mode", "Whether runs create visible tasks.", "string", owner, "workspace.manage"),
|
|
domainWritable("automation", "repository_mode", "Repository mode", "How runs select repositories.", "string", owner, "workspace.manage"),
|
|
)
|
|
}
|
|
|
|
func automationTriggerDomain() DomainDescriptor {
|
|
owner := "automations"
|
|
return supportedDomain("automations", "automation_trigger", "Automation triggers", "Triggers attached to a workspace automation.", owner, ScopeResource, targetRulesResourceWorkspace(),
|
|
domainSensitiveWritable("automation_trigger", "config", "Configuration", "Trigger configuration.", "object", owner, "workspace.manage"),
|
|
domainWritable("automation_trigger", "enabled", "Enabled", "Whether the trigger is active.", "boolean", owner, "workspace.manage"),
|
|
)
|
|
}
|
|
|
|
func runtimeFlagDomain() DomainDescriptor {
|
|
owner := "runtime"
|
|
field := domainWritable("runtime_flag", "override", "Override", "Explicit persisted runtime override. Null clears the override.", "boolean", owner, "org.settings.manage")
|
|
field.Nullable = true
|
|
return supportedDomain("runtime", "runtime_flag", "Runtime overrides", "Permitted persisted runtime flag overrides.", owner, ScopeInstallation, TargetRules{Scope: ScopeInstallation, RequiresResourceID: true}, field)
|
|
}
|
|
|
|
func storageMaintenanceDomain() DomainDescriptor {
|
|
owner := "storage"
|
|
target := TargetRules{Scope: ScopeInstallation, Singleton: true}
|
|
paths := []struct{ path, label, typ string }{
|
|
{"enabled", "Enabled", "boolean"}, {"check_interval_hours", "Check interval", "integer"}, {"idle_for_minutes", "Idle period", "integer"},
|
|
{"orphan_grace_hours", "Orphan grace", "integer"}, {"quarantine_retention_hours", "Quarantine retention", "integer"},
|
|
{"workspaces.enabled", "Workspace cleanup", "boolean"}, {"workspaces.dependency_cleanup_enabled", "Dependency cleanup", "boolean"},
|
|
{"kandev_containers.enabled", "Kandev containers", "boolean"}, {"go_cache.enabled", "Go cache", "boolean"}, {"go_cache.max_bytes", "Go cache limit", "integer"},
|
|
{"docker.dedicated_daemon_acknowledged", "Dedicated Docker acknowledgement", "boolean"}, {"docker.build_cache_enabled", "Docker build cache", "boolean"},
|
|
{"docker.build_cache_keep_bytes", "Docker build cache limit", "integer"}, {"docker.build_cache_unused_hours", "Docker build cache age", "integer"},
|
|
{"docker.unused_images_enabled", "Unused image cleanup", "boolean"}, {"docker.unused_images_hours", "Unused image age", "integer"},
|
|
}
|
|
fields := make([]FieldDescriptor, 0, len(paths))
|
|
for _, item := range paths {
|
|
fields = append(fields, domainWritable("storage_maintenance", item.path, item.label, "Storage maintenance policy.", item.typ, owner, "org.settings.manage"))
|
|
}
|
|
domain := supportedDomain("storage", "storage_maintenance", "Storage maintenance", "Install-wide storage maintenance policy.", owner, ScopeInstallation, target, fields...)
|
|
domain.Operations[0].Options = map[string]any{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": map[string]any{
|
|
"confirm_dedicated_docker": map[string]any{"type": "boolean"},
|
|
"adopt_go_cache": map[string]any{"type": "boolean"},
|
|
},
|
|
}
|
|
return domain
|
|
}
|
|
|
|
func userSettingsDomain() DomainDescriptor {
|
|
values := []string{
|
|
"workspace_id", "workspace", "string", "kanban_view_mode", "kanban view mode", "string", "startup_page", "startup page", "string",
|
|
"workflow_filter_id", "workflow filter", "string", "repository_ids", "repository selection", "array", "tasks_list_sort", "task sort", "string",
|
|
"tasks_list_group", "task grouping", "string", "tasks_list_show_details", "task details", "boolean", "initial_setup_complete", "setup complete", "boolean",
|
|
"preferred_shell", "preferred shell", "string", "default_editor_id", "default editor", "string", "enable_preview_on_click", "preview on click", "boolean",
|
|
"chat_submit_key", "chat submit key", "string", "review_auto_mark_on_scroll", "review auto mark", "boolean", "confirm_task_archive", "confirm task archive", "boolean",
|
|
"prevent_auto_start_agent_on_open", "prevent auto start", "boolean", "unread_divider", "unread divider", "boolean", "agent_generated_task_titles", "generated titles", "boolean", "auto_focus_new_tasks", "auto focus new tasks", "boolean",
|
|
"mcp_task_agent_profile_default", "MCP task profile", "string", "show_anchored_prompt_bar", "anchored prompt bar", "boolean", "show_scroll_to_last_prompt", "scroll to last prompt", "boolean",
|
|
"show_scroll_to_start", "scroll to start", "boolean", "show_transcript_auto_scroll_control", "transcript scroll control", "boolean", "show_todo_list_panel", "todo list panel", "boolean",
|
|
"show_todo_list_panel_only_when_not_empty", "todo list empty state", "boolean", "show_release_notification", "release notification", "boolean", "release_notes_last_seen_version", "release notes version", "string",
|
|
"lsp_auto_start_languages", "LSP auto start", "array", "lsp_auto_install_languages", "LSP auto install", "array", "lsp_server_configs", "LSP server configs", "object",
|
|
"lsp_status_location", "LSP status location", "string", "saved_layouts", "saved layouts", "array", "sidebar_views", "sidebar views", "array", "sidebar_layout_state", "sidebar layout state", "object",
|
|
"sidebar_active_view_id", "active sidebar view", "string", "sidebar_draft", "sidebar draft", "object", "thread_views", "thread views", "array",
|
|
"thread_active_view_id", "active thread view", "string", "thread_view_draft", "thread draft", "object", "sidebar_task_prefs", "sidebar task preferences", "object",
|
|
"sidebar_task_color_automation", "sidebar color automation", "object", "sidebar_task_colors", "sidebar task colors", "object", "sidebar_task_color_patch", "sidebar task color patch", "object", "task_create_last_used", "last task create values", "object",
|
|
"jira_saved_views", "Jira saved views", "object", "jira_task_presets", "Jira task presets", "object", "github_saved_presets", "GitHub saved presets", "object",
|
|
"github_default_query_presets", "GitHub query presets", "object", "gitlab_saved_presets", "GitLab saved presets", "object", "azure_devops_browse_preferences", "Azure DevOps browse preferences", "object",
|
|
"default_utility_agent_id", "default utility agent", "string", "default_utility_model", "default utility model", "string", "default_utility_agent_profile_id", "default utility profile", "string",
|
|
"keyboard_shortcuts", "keyboard shortcuts", "object", "terminal_link_behavior", "terminal link behavior", "string", "terminal_font_family", "terminal font family", "string",
|
|
"terminal_font_size", "terminal font size", "integer", "changes_panel_layout", "changes panel layout", "string", "last_seen_display", "last seen display", "string",
|
|
"sidebar_hover_enabled", "sidebar hover enabled", "boolean", "sidebar_hover_delay_ms", "sidebar hover delay", "integer",
|
|
"system_metrics_display", "system metrics display", "object", "app_status_bar_enabled", "status bar", "boolean", "resolve_session_hostnames", "resolve hostnames", "boolean",
|
|
"app_status_bar_order", "status bar order", "object", "quick_chat_tab_order_by_workspace", "quick chat tab order", "object", "kanban_hidden_step_ids", "hidden kanban steps", "object",
|
|
"workflow_ids_with_auto_hide_empty_steps", "auto-hide workflows", "array", "kanban_sort", "kanban board sort", "string", "kanban_priority_filter_tokens", "kanban priority filter", "array",
|
|
}
|
|
fields := make([]FieldDescriptor, 0, len(values)/3)
|
|
for index := 0; index+2 < len(values); index += 3 {
|
|
field := preferenceField(values[index], values[index+1], values[index+2])
|
|
if values[index] == "sidebar_layout_state" {
|
|
// The update key is an atomic workspace-scoped operation. Reads
|
|
// project the complete persisted map so settings discovery can
|
|
// inspect it without exposing a whole-map replacement contract.
|
|
field.FieldPath = "sidebar_layouts_by_workspace"
|
|
field.Schema = map[string]any{"type": "object"}
|
|
}
|
|
switch values[index] {
|
|
case "keyboard_shortcuts":
|
|
field.Schema = keyboardShortcutsSchema()
|
|
case "sidebar_task_color_patch":
|
|
field.Schema = map[string]any{"type": "object", "additionalProperties": false, "properties": map[string]any{
|
|
"if_missing": map[string]any{"type": "boolean"},
|
|
"colors": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string", "nullable": true}},
|
|
}}
|
|
}
|
|
switch values[index] {
|
|
case "sidebar_draft", "thread_view_draft", "jira_saved_views", "jira_task_presets", "github_saved_presets", "github_default_query_presets", "gitlab_saved_presets", "azure_devops_browse_preferences":
|
|
field.Nullable = true
|
|
}
|
|
fields = append(fields, field)
|
|
}
|
|
return DomainDescriptor{
|
|
Domain: "user_preferences", ResourceType: "user_settings", Label: "Personal preferences",
|
|
Description: "Portable settings belonging to the authenticated user.", Owner: "user-settings", Scope: ScopeCaller,
|
|
Target: TargetRules{Scope: ScopeCaller, Singleton: true}, SettingsHref: "/settings/preferences", Fields: fields,
|
|
Operations: []OperationDescriptor{{Name: "update", Binding: "user-settings.update", Authority: "user.self"}},
|
|
}
|
|
}
|
|
|
|
func preferenceField(path, label, jsonType string) FieldDescriptor {
|
|
return FieldDescriptor{
|
|
Key: "user_settings." + path, FieldPath: path, Label: label,
|
|
Description: "Portable preference owned by the current user.", JSONType: jsonType,
|
|
Support: SupportSupported, Classification: ClassificationWritable, Owner: "user-settings", Writable: true,
|
|
Validator: "user-settings", Authority: "user.self", ChangeTiming: "future_views", SettingsHref: "/settings/preferences",
|
|
}
|
|
}
|
|
|
|
func keyboardShortcutsSchema() map[string]any {
|
|
return map[string]any{
|
|
"type": "object",
|
|
"additionalProperties": map[string]any{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": map[string]any{
|
|
"key": map[string]any{"type": "string"},
|
|
"modifiers": map[string]any{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": map[string]any{
|
|
"alt": map[string]any{"type": "boolean"},
|
|
"ctrl": map[string]any{"type": "boolean"},
|
|
"meta": map[string]any{"type": "boolean"},
|
|
"shift": map[string]any{"type": "boolean"},
|
|
"command": map[string]any{"type": "boolean"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func DefaultRegistry() (*Registry, error) {
|
|
return NewRegistry(DefaultDomainDescriptors())
|
|
}
|
|
|
|
func profileDomain() DomainDescriptor {
|
|
return DomainDescriptor{
|
|
Domain: "profiles",
|
|
ResourceType: "agent_profile",
|
|
Label: "Agent profiles",
|
|
Description: "Saved agent profile settings used for future sessions.",
|
|
Owner: "agent-settings",
|
|
Scope: ScopeResource,
|
|
Target: TargetRules{Scope: ScopeResource, RequiresResourceID: true, AllowsWorkspaceID: true},
|
|
SettingsHref: "/settings/agents",
|
|
Operations: []OperationDescriptor{{
|
|
Name: "update",
|
|
Binding: "agent-settings.profile.update",
|
|
Authority: "org.config.manage",
|
|
Options: map[string]any{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": map[string]any{
|
|
"force": map[string]any{"type": "boolean"},
|
|
},
|
|
},
|
|
Description: "Validate and update one saved profile through the agent settings controller.",
|
|
}},
|
|
Fields: []FieldDescriptor{
|
|
profileWritable("agent_profile.name", "name", "Profile name", "string", "The saved display name.", false),
|
|
profileWritable("agent_profile.model", "model", "Model", "string", "Preferred model. Empty inherits the provider default.", false),
|
|
profileWritable("agent_profile.fallback_model", "fallback_model", "Fallback model", "string", "Optional fallback model.", false),
|
|
profileWritable("agent_profile.auto_fallback", "auto_fallback", "Automatic fallback", "boolean", "Enable automatic fallback behavior.", false),
|
|
profileWritable("agent_profile.require_exact_model", "require_exact_model", "Require exact model", "boolean", "Require the configured model to be advertised and applied.", false),
|
|
profileWritable("agent_profile.mode", "mode", "Mode", "string", "Agent operating mode.", false),
|
|
profileWritable("agent_profile.config_options", "config_options", "Configuration options", "object", "Typed provider options. Supplied maps replace the saved map.", true),
|
|
profileWritable("agent_profile.allow_indexing", "allow_indexing", "Allow indexing", "boolean", "Legacy compatibility permission.", false),
|
|
profileWritable("agent_profile.auto_approve", "auto_approve", "Auto approve", "boolean", "Automatically approve supported agent permissions.", false),
|
|
profileWritable("agent_profile.cli_passthrough", "cli_passthrough", "CLI passthrough", "boolean", "Enable CLI passthrough mode.", false),
|
|
profileWritableWithDefault("agent_profile.cursor_mcp_auth_enabled", "cursor_mcp_auth_enabled", "Share Cursor MCP credentials", "boolean", "Reuse local Cursor MCP credentials when a Cursor profile launches.", "true for new profiles"),
|
|
profileWritable("agent_profile.enabled", "enabled", "Enabled", "boolean", "Allow this profile for new work.", false),
|
|
profileWritable("agent_profile.cli_flags", "cli_flags", "CLI flags", "array", "Complete replacement list of validated CLI flags.", true),
|
|
profileWritableSensitive("agent_profile.env_vars", "env_vars", "Environment variables", "array", "Complete replacement list. Secret values remain references.", true),
|
|
profileWritable("agent_profile.command_prefix", "command_prefix", "Command prefix", "string", "Optional validated launcher prefix.", false),
|
|
profileWritable("agent_profile.dynamic", "dynamic", "Dynamic routing", "object", "Versioned dynamic routing document.", true),
|
|
},
|
|
}
|
|
}
|
|
|
|
func profileMCPDomain() DomainDescriptor {
|
|
return DomainDescriptor{
|
|
Domain: "profiles",
|
|
ResourceType: "agent_profile_mcp",
|
|
Label: "Profile MCP documents",
|
|
Description: "Separate MCP server settings for a saved agent profile.",
|
|
Owner: "agent-settings",
|
|
Scope: ScopeResource,
|
|
Target: TargetRules{Scope: ScopeResource, RequiresResourceID: true},
|
|
SettingsHref: "/settings/agents",
|
|
Operations: []OperationDescriptor{{Name: "update", Binding: "agent-settings.profile-mcp.update", Authority: "org.config.manage"}},
|
|
Fields: []FieldDescriptor{
|
|
profileWritable("agent_profile_mcp.enabled", "enabled", "MCP enabled", "boolean", "Enable the profile MCP document.", false),
|
|
profileWritableSensitive("agent_profile_mcp.servers", "servers", "MCP servers", "object", "Complete replacement map of validated MCP servers.", true),
|
|
{Key: "agent_profile_mcp.meta", FieldPath: "meta", Label: "MCP metadata", Description: "Preserved metadata from the MCP document.", JSONType: "object", Support: SupportReadOnly, Classification: ClassificationComputed, Owner: "agent-settings", Sensitive: true},
|
|
},
|
|
}
|
|
}
|
|
|
|
func profileWritable(key, path, label, jsonType, description string, replacement bool) FieldDescriptor {
|
|
field := FieldDescriptor{
|
|
Key: key,
|
|
FieldPath: path,
|
|
Label: label,
|
|
Description: description,
|
|
JSONType: jsonType,
|
|
Support: SupportSupported,
|
|
Classification: ClassificationWritable,
|
|
Owner: "agent-settings",
|
|
Writable: true,
|
|
Validator: "agent-settings.profile",
|
|
Authority: "org.config.manage",
|
|
Replacement: replacement,
|
|
ChangeTiming: "future_sessions",
|
|
SettingsHref: "/settings/agents",
|
|
}
|
|
if path == "config_options" {
|
|
field.Schema = map[string]any{
|
|
"type": "object",
|
|
"additionalProperties": map[string]any{"type": "string"},
|
|
"x-kandev-dynamic": "provider_config_options",
|
|
}
|
|
}
|
|
return field
|
|
}
|
|
|
|
func profileWritableWithDefault(key, path, label, jsonType, description, defaultBehavior string) FieldDescriptor {
|
|
field := profileWritable(key, path, label, jsonType, description, false)
|
|
field.DefaultBehavior = defaultBehavior
|
|
return field
|
|
}
|
|
|
|
func profileWritableSensitive(key, path, label, jsonType, description string, replacement bool) FieldDescriptor {
|
|
field := profileWritable(key, path, label, jsonType, description, replacement)
|
|
field.Sensitive = true
|
|
return field
|
|
}
|