feat(FN-4723): complete Step 1 — add worktrunk transition classifier
Fusion-Task-Id: FN-4723 Fusion-Task-Lineage: b79b42a0-c65d-4e02-938f-d1ffabc272ee
This commit is contained in:
committed by
gsxdsm
parent
6afd2737ad
commit
43e3fbf60d
@@ -1,6 +1,10 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { DEFAULT_GLOBAL_SETTINGS, DEFAULT_PROJECT_SETTINGS } from "../settings-schema.js";
|
||||
import { resolveWorktrunkSettings, validateWorktrunkSettings } from "../worktrunk-settings.js";
|
||||
import {
|
||||
resolveWorktrunkSettings,
|
||||
requiresWorktrunkInstallVerification,
|
||||
validateWorktrunkSettings,
|
||||
} from "../worktrunk-settings.js";
|
||||
|
||||
describe("settings defaults invariants", () => {
|
||||
it("keeps worktrunk default off in global and project defaults", () => {
|
||||
@@ -25,4 +29,15 @@ describe("settings defaults invariants", () => {
|
||||
it("does not implicitly enable worktrunk when validating undefined", () => {
|
||||
expect(validateWorktrunkSettings(undefined)).toEqual({});
|
||||
});
|
||||
|
||||
it("flags off→on transition from fresh defaults", () => {
|
||||
const freshProject = resolveWorktrunkSettings(DEFAULT_GLOBAL_SETTINGS.worktrunk, DEFAULT_PROJECT_SETTINGS.worktrunk);
|
||||
expect(freshProject.enabled).toBe(false);
|
||||
expect(
|
||||
requiresWorktrunkInstallVerification({
|
||||
current: freshProject,
|
||||
next: { ...freshProject, enabled: true },
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
resolveWorktrunkSettings,
|
||||
requiresWorktrunkInstallVerification,
|
||||
validateWorktrunkSettings,
|
||||
} from "../worktrunk-settings.js";
|
||||
|
||||
@@ -40,6 +41,14 @@ describe("worktrunk-settings", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("classifies enable transitions that require install verification", () => {
|
||||
expect(requiresWorktrunkInstallVerification({ current: { enabled: false }, next: { enabled: true } })).toBe(true);
|
||||
expect(requiresWorktrunkInstallVerification({ current: { enabled: true }, next: { enabled: true } })).toBe(false);
|
||||
expect(requiresWorktrunkInstallVerification({ current: { enabled: true }, next: { enabled: false } })).toBe(false);
|
||||
expect(requiresWorktrunkInstallVerification({ current: undefined, next: undefined })).toBe(false);
|
||||
expect(requiresWorktrunkInstallVerification({ current: undefined, next: { enabled: true } })).toBe(true);
|
||||
});
|
||||
|
||||
it("validator rejects invalid values", () => {
|
||||
expect(() => validateWorktrunkSettings({ onFailure: "ignore" })).toThrow(
|
||||
"worktrunk.onFailure must be one of",
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
export { COLUMNS, DEFAULT_COLUMN, isColumn, normalizeColumn, COLUMN_LABELS, COLUMN_DESCRIPTIONS, VALID_TRANSITIONS, DEFAULT_SETTINGS, DEFAULT_GLOBAL_SETTINGS, DEFAULT_PROJECT_SETTINGS, GLOBAL_SETTINGS_KEYS, PROJECT_SETTINGS_KEYS, isGlobalSettingsKey, isProjectSettingsKey, resolvePersistAgentThinkingLog, THINKING_LEVELS, THEME_MODES, COLOR_THEMES, WORKFLOW_STEP_TEMPLATES, AGENT_PERMISSIONS, PERMANENT_AGENT_ACTION_CATEGORIES, AGENT_PERMISSION_POLICY_ACTION_CATEGORIES, AGENT_PROVISIONING_APPROVAL_MODES, SANDBOX_PROVISIONING_APPROVAL_MODES, AGENT_PERMISSION_POLICY_PRESET_IDS, LEGACY_AGENT_PERMISSION_POLICY_ACTION_CATEGORY_ALIASES, APPROVAL_REQUEST_STATUSES, APPROVAL_REQUEST_AUDIT_EVENT_TYPES, normalizeApprovalRequestActionCategory, isValidApprovalRequestTransition, agentToConfigSnapshot, diffConfigSnapshots, isEphemeralAgent, hasAgentIdentity, CheckoutConflictError, DEFAULT_HEARTBEAT_PROCEDURE_PATH, getDefaultHeartbeatProcedurePath, EXECUTION_MODES, DEFAULT_EXECUTION_MODE, TASK_PRIORITIES, DEFAULT_TASK_PRIORITY, HIGH_FANOUT_BLOCKER_TODO_THRESHOLD, STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS, DASHBOARD_USER_ID, normalizeMessageParticipant, validateMessageMetadata, validateDockerNodeConfig, sanitizeDockerNodeConfigForResponse, normalizeMergeConflictStrategy, normalizeMergeStrategyOverlapBehavior, normalizePostMergeAuditMode, POST_MERGE_AUDIT_MODES, normalizeMergeAuditAutoRecovery, MERGE_AUDIT_AUTO_RECOVERY_MODES, normalizeAutoRecovery, AUTO_RECOVERY_MODES, buildResearchDocumentKey, REPO_OVERRIDE_RE, SHARED_STATE_SNAPSHOT_VERSION } from "./types.js";
|
||||
export type { Column, IssueInfo, IssueState, TaskSourceIssue, PrInfo, PrStatus, Task, TaskTokenUsage, TaskAttachment, TaskComment, TaskCommentInput, TaskDocument, TaskDocumentRevision, TaskDocumentCreateInput, TaskDocumentWithTask, TaskCreateInput, MeshReplicatedTaskCreatePayload, MeshReplicatedTaskApplyResult, TaskSource, SourceType, TaskDetail, RetrySummary, InboxTask, TodoList, TodoItem, TodoListCreateInput, TodoListUpdateInput, TodoItemCreateInput, TodoItemUpdateInput, TodoListWithItems, AgentLogEntry, AgentLogType, AgentRole, BoardConfig, DistributedTaskIdReserveInput, DistributedTaskIdReserveResult, DistributedTaskIdCommitInput, DistributedTaskIdCommitResult, DistributedTaskIdAbortInput, DistributedTaskIdAbortResult, DistributedTaskIdStateInput, DistributedTaskIdStateResult, AutostashOrphanRecord, AutostashOutcome, MergeDetails, MergeResult, MergeConflictStrategy, CanonicalMergeConflictStrategy, MergeStrategyOverlapBehavior, PostMergeAuditMode, MergeAuditAutoRecoveryMode, AutoRecoveryMode, AutoRecoveryFailureClass, AutoRecoverySettings, DirectMergeCommitStrategy, Settings, GlobalSettings, ProjectSettings, WebSearchBackend, ResearchEnabledSources, ResearchGlobalDefaults, ResearchProjectLimits, ResearchProjectSettings, SandboxBackendName, SandboxFailureMode, SandboxPolicy, SandboxProjectSettings, EvalFollowUpPolicy, EvalProjectSettings, ResolvedEvalSettings, SettingsScope, DaemonTokenSettings, TaskStep, StepStatus, TaskLogEntry, RunMutationContext, ActivityLogEntry, ActivityEventType, ThinkingLevel, ThemeMode, ColorTheme, ExecutionMode, TaskPriority, UnavailableNodePolicy, PlanningQuestion, PlanningSummary, PlanningResponse, PlanningQuestionType, ArchivedTaskEntry, BatchStatusRequest, BatchStatusResponse, BatchStatusEntry, BatchStatusResult, GithubIssueAction, ModelPreset, WorkflowStep, WorkflowStepMode, WorkflowStepGateMode, WorkflowStepPhase, WorkflowStepInput, WorkflowStepResult, WorkflowStepTemplate, Agent, OrgTreeNode, AgentState, AgentDetail, AgentCreateInput, AgentUpdateInput, AgentApiKey, AgentApiKeyCreateResult, AgentCapability, AgentPromptTemplate, AgentPromptsConfig, AgentPermission, PermanentAgentActionCategory, PermanentAgentSensitiveActionCategory, PermanentAgentGatingContext, AgentPermissionPolicy, AgentPermissionPolicyRules, AgentPermissionPolicyActionCategory, AgentProvisioningApprovalMode, SandboxProvisioningApprovalMode, LegacyAgentPermissionPolicyActionCategory, ApprovalRequestActionCategoryInput, ApprovalRequestActionCategory, AgentPermissionPolicyDisposition, AgentPermissionPolicyPresetId, ApprovalRequestStatus, ApprovalRequestAuditEventType, ApprovalRequestActorSnapshot, ApprovalRequestTargetAction, ApprovalRequestAuditEvent, ApprovalRequest, ApprovalRequestCreateInput, ApprovalRequestDecisionInput, ApprovalRequestCompletionInput, ApprovalRequestListInput, TaskAssignSource, AgentAccessState, AgentHeartbeatConfig, AgentBudgetConfig, AgentBudgetStatus, InstructionsBundleConfig, MessageResponseMode, AgentHeartbeatEvent, AgentHeartbeatRun, BlockedStateSnapshot, HeartbeatInvocationSource, AgentTaskSession, AgentRating, AgentRatingSummary, AgentRatingInput, AgentConfigSnapshot, RevisionFieldDiff, AgentConfigRevision, AgentStats, ReflectionTrigger, ReflectionMetrics, AgentReflection, AgentPerformanceSummary, NtfyNotificationEvent, NotificationEvent, NotificationPayload, NotificationProviderConfig, CustomProvider, SteeringComment, ParticipantType, MessageType, Message, MessageCreateInput, MessageFilter, MessageMetadata, MessageReplyReference, Mailbox, CheckoutLease, RunAuditDomain, RunAuditEvent, RunAuditEventInput, RunAuditEventFilter, AgentMemoryInclusionMode, HeartbeatPromptTemplate, HeartbeatScopeDisciplineMode, WorktrunkSettings, WorktrunkOnFailure } from "./types.js";
|
||||
export { AGENT_VALID_TRANSITIONS } from "./types.js";
|
||||
export { resolveWorktrunkSettings, validateWorktrunkSettings, DEFAULT_WORKTRUNK_SETTINGS } from "./worktrunk-settings.js";
|
||||
export {
|
||||
resolveWorktrunkSettings,
|
||||
requiresWorktrunkInstallVerification,
|
||||
validateWorktrunkSettings,
|
||||
DEFAULT_WORKTRUNK_SETTINGS,
|
||||
} from "./worktrunk-settings.js";
|
||||
export {
|
||||
resolveAgentMemoryInclusionMode,
|
||||
type AgentMemoryInclusionModeSource,
|
||||
|
||||
@@ -38,6 +38,16 @@ export function resolveWorktrunkSettings(
|
||||
};
|
||||
}
|
||||
|
||||
/** Strict validator used by GlobalSettingsStore writes and CLI parsing. */
|
||||
export function requiresWorktrunkInstallVerification(params: {
|
||||
current: WorktrunkSettings | undefined;
|
||||
next: WorktrunkSettings | undefined;
|
||||
}): boolean {
|
||||
const currentEnabled = params.current?.enabled ?? DEFAULT_WORKTRUNK_SETTINGS.enabled;
|
||||
const nextEnabled = params.next?.enabled ?? DEFAULT_WORKTRUNK_SETTINGS.enabled;
|
||||
return currentEnabled !== true && nextEnabled === true;
|
||||
}
|
||||
|
||||
/** Strict validator used by GlobalSettingsStore writes and CLI parsing. */
|
||||
export function validateWorktrunkSettings(value: unknown): WorktrunkSettings {
|
||||
if (value === undefined || value === null) {
|
||||
|
||||
Reference in New Issue
Block a user