Lines 104-144typescript
105 scope?: TaskViewSelection;
108const TASK_TRANSITIONS: Record<TaskTransition, { from: TaskStatus[]; to: TaskStatus }> = {
109 start: { from: ["todo"], to: "in-progress" },
110 submit: { from: ["in-progress"], to: "review" },
111 reject: { from: ["review"], to: "rejected" },
112 retry: { from: ["rejected"], to: "in-progress" },
113 cancel: { from: ["todo", "in-progress", "review", "rejected"], to: "canceled" },
118 private readonly artifacts: ArtifactStore,
119 private readonly gates: GateRunner,
120 private readonly focusStore: TaskFocusStore = new InMemoryTaskFocusStore(),
121 private readonly events: TaskEventStore = new InMemoryTaskEventStore(),
122 private readonly scopes: TaskScopeStore = new InMemoryTaskScopeStore(),
125 private require(id: string): Artifact {
126 const artifact = this.artifacts.get(id);
MediumDynamic Require
Package source references dynamic require/import behavior.
src/task-service.tsView on unpkg · L124 127 if (!artifact) throw new Error(`task artifact "${id}" not found`);
128 if (artifact.kind !== "task") throw new Error(`artifact "${id}" is not a task`);
132 create(input: CreateTaskInput, context: TaskEventContext = {}): Artifact {
133 return this.events.atomic(() => {
134 if ((input.dependsOn?.length ?? 0) > TASK_EXECUTION_MAX_DEGREE) {
135 throw new Error(`task cannot exceed ${TASK_EXECUTION_MAX_DEGREE} prerequisites`);
137 if (input.parentId) this.require(input.parentId);
138 for (const dependency of input.dependsOn ?? []) this.require(dependency);
139 const extra: Record<string, unknown> = { ...(input.extra ?? {}) };
140 if (input.gates !== undefined) extra["gates"] = input.gates;
141 if (input.checklist !== undefined) extra["checklist"] = validateChecklist(input.checklist);
142 const projectRoot = input.projectRoot === undefined ? undefined : normalizeProjectRoot(input.projectRoot);
143 if (input.parentId && this.scopes.get(input.parentId)?.projectRoot !== projectRoot) {
144 throw new Error(`parent task "${input.parentId}" is outside project scope`);