mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Introduces the foundation for isolated task execution (Phase 3a of #12330): - TaskContext: immutable snapshot of mode, API config, and workspace for each task, replacing runtime reads from shared ClineProvider state - TaskPermissions: fine-grained permission boundaries (file patterns, command restrictions, read-only mode, tool allowlists) that the orchestrator can attach when spawning subtasks - TaskContextBuilder: factory functions to build TaskContext from provider state and to derive child contexts with merged permissions - Task constructor now accepts optional taskContext, using it for mode and API config initialization instead of provider.getState() - delegateParentAndOpenChild builds and passes a TaskContext to child tasks - Permission merging follows most-restrictive-wins semantics This is a pure refactor with no behavioral change -- tasks still execute sequentially, but they now carry their own isolated context. Enforcement of permission boundaries is deferred to Phase 3b/3d. Ref: #12330
63 lines
2.5 KiB
TypeScript
63 lines
2.5 KiB
TypeScript
import { type TaskContext, type TaskPermissions, mergePermissions } from "@roo-code/types"
|
|
|
|
import { defaultModeSlug } from "../../shared/modes"
|
|
import type { ClineProvider } from "../webview/ClineProvider"
|
|
|
|
/**
|
|
* Build a TaskContext from the current provider state.
|
|
*
|
|
* This factory snapshots the provider's current mode and API config
|
|
* into an immutable TaskContext that a child task can carry independently.
|
|
* This is the key enabler for Phase 3a: tasks no longer need to reach
|
|
* back into the provider for their mode/config during execution.
|
|
*
|
|
* @param provider - The ClineProvider to snapshot state from
|
|
* @param overrides - Optional overrides (e.g., mode from new_task tool)
|
|
* @returns A TaskContext snapshot
|
|
*/
|
|
export async function buildTaskContext(
|
|
provider: ClineProvider,
|
|
overrides?: Partial<TaskContext>,
|
|
): Promise<TaskContext> {
|
|
const state = await provider.getState()
|
|
|
|
const context: TaskContext = {
|
|
mode: overrides?.mode ?? state?.mode ?? defaultModeSlug,
|
|
apiConfigName: overrides?.apiConfigName ?? state?.currentApiConfigName ?? "default",
|
|
permissions: overrides?.permissions,
|
|
inheritSkills: overrides?.inheritSkills ?? true,
|
|
skillOverrides: overrides?.skillOverrides,
|
|
workspacePath: overrides?.workspacePath,
|
|
parentTaskId: overrides?.parentTaskId,
|
|
rootTaskId: overrides?.rootTaskId,
|
|
}
|
|
|
|
return context
|
|
}
|
|
|
|
/**
|
|
* Build a TaskContext for a child task, inheriting from a parent context
|
|
* and applying any child-specific overrides.
|
|
*
|
|
* Permission merging follows the "most restrictive" principle:
|
|
* the child's effective permissions are the intersection of the parent's
|
|
* permissions and any child-specific permissions.
|
|
*
|
|
* @param parentContext - The parent task's context
|
|
* @param childOverrides - Child-specific overrides
|
|
* @returns A new TaskContext for the child task
|
|
*/
|
|
export function buildChildTaskContext(parentContext: TaskContext, childOverrides: Partial<TaskContext>): TaskContext {
|
|
const mergedPermissions = mergePermissions(parentContext.permissions, childOverrides.permissions)
|
|
|
|
return {
|
|
mode: childOverrides.mode ?? parentContext.mode,
|
|
apiConfigName: childOverrides.apiConfigName ?? parentContext.apiConfigName,
|
|
permissions: mergedPermissions,
|
|
inheritSkills: childOverrides.inheritSkills ?? parentContext.inheritSkills,
|
|
skillOverrides: childOverrides.skillOverrides ?? parentContext.skillOverrides,
|
|
workspacePath: childOverrides.workspacePath ?? parentContext.workspacePath,
|
|
parentTaskId: childOverrides.parentTaskId,
|
|
rootTaskId: childOverrides.rootTaskId ?? parentContext.rootTaskId,
|
|
}
|
|
}
|