pi-loop 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/code-reviewer.md +82 -0
- package/agents/coder.md +82 -0
- package/agents/decomposer.md +55 -0
- package/agents/judge.md +90 -0
- package/agents/review-optimizer.md +44 -0
- package/dist/agents/adapter.d.ts +9 -0
- package/dist/agents/adapter.d.ts.map +1 -0
- package/dist/agents/adapter.js +41 -0
- package/dist/agents/adapter.js.map +1 -0
- package/dist/agents/factory.d.ts +7 -0
- package/dist/agents/factory.d.ts.map +1 -0
- package/dist/agents/factory.js +49 -0
- package/dist/agents/factory.js.map +1 -0
- package/dist/agents/registry.d.ts +4 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +98 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.d.ts +21 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +39 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/cli/args.d.ts +38 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +160 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands.d.ts +29 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +362 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/output.d.ts +33 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +99 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +31 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +70 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/types.d.ts +41 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +5 -0
- package/dist/config/types.js.map +1 -0
- package/dist/core/checkpoint.d.ts +18 -0
- package/dist/core/checkpoint.d.ts.map +1 -0
- package/dist/core/checkpoint.js +32 -0
- package/dist/core/checkpoint.js.map +1 -0
- package/dist/core/judge.d.ts +11 -0
- package/dist/core/judge.d.ts.map +1 -0
- package/dist/core/judge.js +91 -0
- package/dist/core/judge.js.map +1 -0
- package/dist/core/learnings.d.ts +4 -0
- package/dist/core/learnings.d.ts.map +1 -0
- package/dist/core/learnings.js +33 -0
- package/dist/core/learnings.js.map +1 -0
- package/dist/core/orchestrator.d.ts +64 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +499 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/plan.d.ts +7 -0
- package/dist/core/plan.d.ts.map +1 -0
- package/dist/core/plan.js +15 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/readiness-policy.d.ts +11 -0
- package/dist/core/readiness-policy.d.ts.map +1 -0
- package/dist/core/readiness-policy.js +24 -0
- package/dist/core/readiness-policy.js.map +1 -0
- package/dist/core/scheduling-policy.d.ts +9 -0
- package/dist/core/scheduling-policy.d.ts.map +1 -0
- package/dist/core/scheduling-policy.js +56 -0
- package/dist/core/scheduling-policy.js.map +1 -0
- package/dist/core/task-backend.d.ts +55 -0
- package/dist/core/task-backend.d.ts.map +1 -0
- package/dist/core/task-backend.js +76 -0
- package/dist/core/task-backend.js.map +1 -0
- package/dist/core/task-state.d.ts +26 -0
- package/dist/core/task-state.d.ts.map +1 -0
- package/dist/core/task-state.js +182 -0
- package/dist/core/task-state.js.map +1 -0
- package/dist/core/wiring.d.ts +12 -0
- package/dist/core/wiring.d.ts.map +1 -0
- package/dist/core/wiring.js +131 -0
- package/dist/core/wiring.js.map +1 -0
- package/dist/git/conflict.d.ts +6 -0
- package/dist/git/conflict.d.ts.map +1 -0
- package/dist/git/conflict.js +25 -0
- package/dist/git/conflict.js.map +1 -0
- package/dist/git/repo.d.ts +13 -0
- package/dist/git/repo.d.ts.map +1 -0
- package/dist/git/repo.js +74 -0
- package/dist/git/repo.js.map +1 -0
- package/dist/git/same-branch.d.ts +9 -0
- package/dist/git/same-branch.d.ts.map +1 -0
- package/dist/git/same-branch.js +55 -0
- package/dist/git/same-branch.js.map +1 -0
- package/dist/git/worktree.d.ts +14 -0
- package/dist/git/worktree.d.ts.map +1 -0
- package/dist/git/worktree.js +78 -0
- package/dist/git/worktree.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/linear/backend.d.ts +38 -0
- package/dist/integrations/linear/backend.d.ts.map +1 -0
- package/dist/integrations/linear/backend.js +374 -0
- package/dist/integrations/linear/backend.js.map +1 -0
- package/dist/integrations/linear/client.d.ts +19 -0
- package/dist/integrations/linear/client.d.ts.map +1 -0
- package/dist/integrations/linear/client.js +86 -0
- package/dist/integrations/linear/client.js.map +1 -0
- package/dist/integrations/linear/comment-templates.d.ts +14 -0
- package/dist/integrations/linear/comment-templates.d.ts.map +1 -0
- package/dist/integrations/linear/comment-templates.js +50 -0
- package/dist/integrations/linear/comment-templates.js.map +1 -0
- package/dist/integrations/linear/contract.d.ts +15 -0
- package/dist/integrations/linear/contract.d.ts.map +1 -0
- package/dist/integrations/linear/contract.js +86 -0
- package/dist/integrations/linear/contract.js.map +1 -0
- package/dist/integrations/linear/types.d.ts +39 -0
- package/dist/integrations/linear/types.d.ts.map +1 -0
- package/dist/integrations/linear/types.js +2 -0
- package/dist/integrations/linear/types.js.map +1 -0
- package/dist/swarm/pool.d.ts +33 -0
- package/dist/swarm/pool.d.ts.map +1 -0
- package/dist/swarm/pool.js +182 -0
- package/dist/swarm/pool.js.map +1 -0
- package/dist/swarm/scheduler.d.ts +38 -0
- package/dist/swarm/scheduler.d.ts.map +1 -0
- package/dist/swarm/scheduler.js +191 -0
- package/dist/swarm/scheduler.js.map +1 -0
- package/dist/swarm/worker.d.ts +49 -0
- package/dist/swarm/worker.d.ts.map +1 -0
- package/dist/swarm/worker.js +180 -0
- package/dist/swarm/worker.js.map +1 -0
- package/dist/tools/bash-tool.d.ts +24 -0
- package/dist/tools/bash-tool.d.ts.map +1 -0
- package/dist/tools/bash-tool.js +177 -0
- package/dist/tools/bash-tool.js.map +1 -0
- package/dist/tools/file-tools.d.ts +3 -0
- package/dist/tools/file-tools.d.ts.map +1 -0
- package/dist/tools/file-tools.js +68 -0
- package/dist/tools/file-tools.js.map +1 -0
- package/dist/tools/git-tools.d.ts +3 -0
- package/dist/tools/git-tools.d.ts.map +1 -0
- package/dist/tools/git-tools.js +44 -0
- package/dist/tools/git-tools.js.map +1 -0
- package/dist/tools/learnings-tool.d.ts +3 -0
- package/dist/tools/learnings-tool.d.ts.map +1 -0
- package/dist/tools/learnings-tool.js +48 -0
- package/dist/tools/learnings-tool.js.map +1 -0
- package/dist/tools/plan-tool.d.ts +3 -0
- package/dist/tools/plan-tool.d.ts.map +1 -0
- package/dist/tools/plan-tool.js +24 -0
- package/dist/tools/plan-tool.js.map +1 -0
- package/dist/tools/task-tools.d.ts +3 -0
- package/dist/tools/task-tools.d.ts.map +1 -0
- package/dist/tools/task-tools.js +108 -0
- package/dist/tools/task-tools.js.map +1 -0
- package/dist/tools/test-tool.d.ts +3 -0
- package/dist/tools/test-tool.d.ts.map +1 -0
- package/dist/tools/test-tool.js +43 -0
- package/dist/tools/test-tool.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { formatBuilderWorklog, formatVerifierWorklog } from "../integrations/linear/comment-templates.js";
|
|
3
|
+
import { clearCheckpoint, loadCheckpoint, saveCheckpoint, } from "./checkpoint.js";
|
|
4
|
+
import { buildJudgePrompt, parseJudgeVerdict } from "./judge.js";
|
|
5
|
+
import { appendLearning, readLearnings } from "./learnings.js";
|
|
6
|
+
import { readPlan, verifyPlanUnchanged } from "./plan.js";
|
|
7
|
+
import { evaluateTaskReadiness } from "./readiness-policy.js";
|
|
8
|
+
import { selectExecutionOrder } from "./scheduling-policy.js";
|
|
9
|
+
import { createSubtasks, parseTasks, serializeTasks } from "./task-state.js";
|
|
10
|
+
export class Orchestrator {
|
|
11
|
+
phase = "init";
|
|
12
|
+
cycle = 0;
|
|
13
|
+
planHash = "";
|
|
14
|
+
planPath;
|
|
15
|
+
tasksPath;
|
|
16
|
+
learningsPath;
|
|
17
|
+
config;
|
|
18
|
+
deps;
|
|
19
|
+
workDir;
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.planPath = options.planPath;
|
|
22
|
+
this.tasksPath = options.tasksPath;
|
|
23
|
+
this.learningsPath = options.learningsPath;
|
|
24
|
+
this.config = options.config;
|
|
25
|
+
this.deps = options.deps;
|
|
26
|
+
this.workDir = options.workDir ?? process.cwd();
|
|
27
|
+
}
|
|
28
|
+
async run() {
|
|
29
|
+
// Check for existing checkpoint
|
|
30
|
+
const checkpoint = await loadCheckpoint(this.workDir);
|
|
31
|
+
if (checkpoint) {
|
|
32
|
+
return this.resume(checkpoint);
|
|
33
|
+
}
|
|
34
|
+
return this.executeFromPhase("init");
|
|
35
|
+
}
|
|
36
|
+
async resume(checkpoint) {
|
|
37
|
+
this.phase = checkpoint.phase;
|
|
38
|
+
this.cycle = checkpoint.cycle;
|
|
39
|
+
this.planHash = checkpoint.planHash;
|
|
40
|
+
await this.deps.taskBackend.initializeCycle(this.cycle);
|
|
41
|
+
await this.deps.taskBackend.applyCheckpointContext(checkpoint.backendContext);
|
|
42
|
+
return this.executeFromPhase(checkpoint.phase);
|
|
43
|
+
}
|
|
44
|
+
log(message) {
|
|
45
|
+
const ts = new Date().toISOString().slice(11, 19);
|
|
46
|
+
console.error(`[pi-loop ${ts}] ${message}`);
|
|
47
|
+
}
|
|
48
|
+
async executeFromPhase(startPhase) {
|
|
49
|
+
// Phase execution order
|
|
50
|
+
const phaseOrder = [
|
|
51
|
+
"init",
|
|
52
|
+
"decomposing",
|
|
53
|
+
"reviewing-tasks",
|
|
54
|
+
"sub-decomposing",
|
|
55
|
+
"executing",
|
|
56
|
+
"judging",
|
|
57
|
+
"re-planning",
|
|
58
|
+
];
|
|
59
|
+
let startIndex = phaseOrder.indexOf(startPhase);
|
|
60
|
+
if (startIndex === -1)
|
|
61
|
+
startIndex = 0;
|
|
62
|
+
for (let i = startIndex; i < phaseOrder.length; i++) {
|
|
63
|
+
this.phase = phaseOrder[i];
|
|
64
|
+
this.log(`cycle ${this.cycle} → phase: ${this.phase}`);
|
|
65
|
+
await this.saveCurrentCheckpoint();
|
|
66
|
+
switch (this.phase) {
|
|
67
|
+
case "init":
|
|
68
|
+
await this.phaseInit();
|
|
69
|
+
break;
|
|
70
|
+
case "decomposing":
|
|
71
|
+
await this.phaseDecompose();
|
|
72
|
+
break;
|
|
73
|
+
case "reviewing-tasks":
|
|
74
|
+
await this.phaseReviewTasks();
|
|
75
|
+
break;
|
|
76
|
+
case "sub-decomposing":
|
|
77
|
+
await this.phaseSubDecompose();
|
|
78
|
+
break;
|
|
79
|
+
case "executing":
|
|
80
|
+
await this.phaseExecute();
|
|
81
|
+
break;
|
|
82
|
+
case "judging": {
|
|
83
|
+
const verdict = await this.phaseJudge();
|
|
84
|
+
if (verdict.status === "done") {
|
|
85
|
+
this.phase = "completed";
|
|
86
|
+
await this.saveCurrentCheckpoint();
|
|
87
|
+
await clearCheckpoint(this.workDir);
|
|
88
|
+
return verdict;
|
|
89
|
+
}
|
|
90
|
+
if (verdict.feedback.includes("DRIFT_STOP:")) {
|
|
91
|
+
this.phase = "completed";
|
|
92
|
+
await this.saveCurrentCheckpoint();
|
|
93
|
+
await clearCheckpoint(this.workDir);
|
|
94
|
+
return verdict;
|
|
95
|
+
}
|
|
96
|
+
// Continue to re-planning
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case "re-planning":
|
|
100
|
+
await this.phaseRePlan();
|
|
101
|
+
// After re-planning, check cycle limit
|
|
102
|
+
if (this.cycle >= this.config.maxCycles) {
|
|
103
|
+
const finalVerdict = {
|
|
104
|
+
status: "not_done",
|
|
105
|
+
completedGoals: [],
|
|
106
|
+
remainingGoals: ["Max cycles reached"],
|
|
107
|
+
driftDetected: false,
|
|
108
|
+
feedback: `Reached maximum cycle limit of ${this.config.maxCycles}`,
|
|
109
|
+
testsPass: false,
|
|
110
|
+
};
|
|
111
|
+
this.phase = "completed";
|
|
112
|
+
await this.saveCurrentCheckpoint();
|
|
113
|
+
await clearCheckpoint(this.workDir);
|
|
114
|
+
return finalVerdict;
|
|
115
|
+
}
|
|
116
|
+
// Loop back to decomposing
|
|
117
|
+
i = phaseOrder.indexOf("decomposing") - 1;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Should not reach here
|
|
122
|
+
throw new Error(`Orchestrator ended in unexpected phase: ${this.phase}`);
|
|
123
|
+
}
|
|
124
|
+
async phaseInit() {
|
|
125
|
+
const { hash } = await readPlan(this.planPath);
|
|
126
|
+
this.planHash = hash;
|
|
127
|
+
this.cycle = 1;
|
|
128
|
+
await this.deps.taskBackend.initializeCycle(this.cycle);
|
|
129
|
+
}
|
|
130
|
+
async phaseDecompose() {
|
|
131
|
+
if (this.config.taskBackend === "linear") {
|
|
132
|
+
this.log("decompose: skipped in linear backend mode");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const plan = await readFile(this.planPath, "utf8");
|
|
136
|
+
const learnings = await readLearnings(this.learningsPath);
|
|
137
|
+
const agent = await this.deps.createAgentFn("decomposer", learnings);
|
|
138
|
+
const prompt = `Decompose the following plan into tasks.
|
|
139
|
+
|
|
140
|
+
CRITICAL: Your entire response must be valid Tasks.md markdown. Do not include any preamble, commentary, or explanation — only the Tasks.md content.
|
|
141
|
+
|
|
142
|
+
## Required Format
|
|
143
|
+
|
|
144
|
+
Your output MUST use exactly this format for each task:
|
|
145
|
+
|
|
146
|
+
\`\`\`
|
|
147
|
+
# Tasks
|
|
148
|
+
|
|
149
|
+
<!-- plan-hash: ${this.planHash} -->
|
|
150
|
+
<!-- updated: ${new Date().toISOString()} -->
|
|
151
|
+
<!-- cycle: ${this.cycle} -->
|
|
152
|
+
|
|
153
|
+
## T-001: Task title here [pending]
|
|
154
|
+
- **Estimate**: 3min
|
|
155
|
+
- **Dependencies**: none
|
|
156
|
+
- **Attempts**: 0
|
|
157
|
+
- **Cycle**: ${this.cycle}
|
|
158
|
+
|
|
159
|
+
## T-002: Another task [pending]
|
|
160
|
+
- **Estimate**: 5min
|
|
161
|
+
- **Dependencies**: T-001
|
|
162
|
+
- **Attempts**: 0
|
|
163
|
+
- **Cycle**: ${this.cycle}
|
|
164
|
+
\`\`\`
|
|
165
|
+
|
|
166
|
+
Rules:
|
|
167
|
+
- Each task heading MUST be: ## T-NNN: Title [status]
|
|
168
|
+
- Status must be one of: pending, needs-decomposition
|
|
169
|
+
- Dependencies is a comma-separated list of task IDs, or "none"
|
|
170
|
+
- Use T-001, T-002, etc. for top-level tasks
|
|
171
|
+
- For subtasks use T-001-a, T-001-b format
|
|
172
|
+
- Each task must be completable in under 5 minutes
|
|
173
|
+
- Include ALL required fields: Estimate, Dependencies, Attempts, Cycle
|
|
174
|
+
|
|
175
|
+
Plan:
|
|
176
|
+
${plan}
|
|
177
|
+
|
|
178
|
+
Current cycle: ${this.cycle}
|
|
179
|
+
Plan hash: ${this.planHash}`;
|
|
180
|
+
const tasksMarkdown = await agent.run(prompt);
|
|
181
|
+
this.log(`decomposer produced ${tasksMarkdown.length} chars`);
|
|
182
|
+
await writeFile(this.tasksPath, tasksMarkdown, "utf8");
|
|
183
|
+
// Verify the output is parseable
|
|
184
|
+
const verifyDoc = parseTasks(tasksMarkdown);
|
|
185
|
+
this.log(`decomposer → ${verifyDoc.tasks.length} parseable tasks`);
|
|
186
|
+
}
|
|
187
|
+
async phaseReviewTasks() {
|
|
188
|
+
if (this.config.taskBackend === "linear") {
|
|
189
|
+
this.log("review-tasks: skipped in linear backend mode");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const plan = await readFile(this.planPath, "utf8");
|
|
193
|
+
const tasksContent = await readFile(this.tasksPath, "utf8");
|
|
194
|
+
const learnings = await readLearnings(this.learningsPath);
|
|
195
|
+
const agent = await this.deps.createAgentFn("review-optimizer", learnings);
|
|
196
|
+
const prompt = `Review and optimize the following task decomposition against the plan.
|
|
197
|
+
|
|
198
|
+
CRITICAL: Your entire response must be the corrected Tasks.md content. Do not include any review commentary, critique summaries, or explanation — only the corrected Tasks.md.
|
|
199
|
+
|
|
200
|
+
Rules:
|
|
201
|
+
- You MUST include EVERY task from the input. Do not drop or omit any tasks.
|
|
202
|
+
- If a task has issues (wrong dependencies, bad estimates), fix the fields directly.
|
|
203
|
+
- If a task should be rejected, change its status from [pending] to [rejected].
|
|
204
|
+
- If tasks are missing from the plan, add them with [pending] status.
|
|
205
|
+
- Do NOT add inline notes, bullet lists, or commentary between tasks.
|
|
206
|
+
- Do NOT add any text before "# Tasks" or after the last task entry.
|
|
207
|
+
|
|
208
|
+
The output MUST preserve this exact format for every task:
|
|
209
|
+
|
|
210
|
+
## T-NNN: Task title [status]
|
|
211
|
+
- **Estimate**: Xmin
|
|
212
|
+
- **Dependencies**: T-001, T-002 (or "none")
|
|
213
|
+
- **Attempts**: 0
|
|
214
|
+
- **Cycle**: N
|
|
215
|
+
|
|
216
|
+
Include the metadata comments (plan-hash, updated, cycle) at the top.
|
|
217
|
+
|
|
218
|
+
Plan:
|
|
219
|
+
${plan}
|
|
220
|
+
|
|
221
|
+
Current Tasks:
|
|
222
|
+
${tasksContent}`;
|
|
223
|
+
const reviewedTasks = await agent.run(prompt);
|
|
224
|
+
// Verify task count is preserved
|
|
225
|
+
const beforeDoc = parseTasks(tasksContent);
|
|
226
|
+
const afterDoc = parseTasks(reviewedTasks);
|
|
227
|
+
this.log(`review: ${beforeDoc.tasks.length} tasks → ${afterDoc.tasks.length} tasks`);
|
|
228
|
+
if (afterDoc.tasks.length < beforeDoc.tasks.length) {
|
|
229
|
+
this.log(`WARNING: review-optimizer dropped ${beforeDoc.tasks.length - afterDoc.tasks.length} tasks`);
|
|
230
|
+
}
|
|
231
|
+
await writeFile(this.tasksPath, reviewedTasks, "utf8");
|
|
232
|
+
}
|
|
233
|
+
async phaseSubDecompose() {
|
|
234
|
+
if (this.config.taskBackend === "linear") {
|
|
235
|
+
this.log("sub-decompose: skipped in linear backend mode");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const tasksContent = await readFile(this.tasksPath, "utf8");
|
|
239
|
+
const doc = parseTasks(tasksContent);
|
|
240
|
+
// Find tasks that need decomposition AND don't already have subtasks
|
|
241
|
+
const needsDecomp = doc.tasks.filter((t) => {
|
|
242
|
+
if (t.status !== "needs-decomposition")
|
|
243
|
+
return false;
|
|
244
|
+
// Skip if subtasks already exist in the doc (from the initial decomposer)
|
|
245
|
+
const hasExistingSubtasks = doc.tasks.some((other) => other.id.startsWith(`${t.id}-`) && other.status === "pending");
|
|
246
|
+
return !hasExistingSubtasks;
|
|
247
|
+
});
|
|
248
|
+
this.log(`sub-decompose: ${needsDecomp.length} tasks need decomposition (of ${doc.tasks.length} total)`);
|
|
249
|
+
if (needsDecomp.length === 0)
|
|
250
|
+
return;
|
|
251
|
+
const learnings = await readLearnings(this.learningsPath);
|
|
252
|
+
const agent = await this.deps.createAgentFn("decomposer", learnings);
|
|
253
|
+
for (const task of needsDecomp) {
|
|
254
|
+
this.log(`sub-decompose: breaking down ${task.id} "${task.title}"`);
|
|
255
|
+
const prompt = `Break down task ${task.id}: "${task.title}" into smaller subtasks.
|
|
256
|
+
|
|
257
|
+
CRITICAL: Your entire response must be ONLY the subtask definitions. No preamble or explanation.
|
|
258
|
+
|
|
259
|
+
Use this exact format for each subtask:
|
|
260
|
+
|
|
261
|
+
## ${task.id}-a: First subtask title [pending]
|
|
262
|
+
- **Estimate**: 2min
|
|
263
|
+
- **Dependencies**: none
|
|
264
|
+
- **Attempts**: 0
|
|
265
|
+
- **Cycle**: ${doc.cycle}
|
|
266
|
+
|
|
267
|
+
## ${task.id}-b: Second subtask title [pending]
|
|
268
|
+
- **Estimate**: 3min
|
|
269
|
+
- **Dependencies**: ${task.id}-a
|
|
270
|
+
- **Attempts**: 0
|
|
271
|
+
- **Cycle**: ${doc.cycle}
|
|
272
|
+
|
|
273
|
+
Rules:
|
|
274
|
+
- Use ${task.id}-a, ${task.id}-b, ${task.id}-c, etc. for subtask IDs
|
|
275
|
+
- Each subtask must be completable in under 5 minutes
|
|
276
|
+
- Include ALL fields: Estimate, Dependencies, Attempts, Cycle
|
|
277
|
+
- Dependencies can reference other subtask IDs or parent task dependencies`;
|
|
278
|
+
const subtasksMarkdown = await agent.run(prompt);
|
|
279
|
+
const subtaskDoc = parseTasks(subtasksMarkdown);
|
|
280
|
+
this.log(`sub-decompose: ${task.id} → ${subtaskDoc.tasks.length} parseable subtasks`);
|
|
281
|
+
if (subtaskDoc.tasks.length > 0) {
|
|
282
|
+
createSubtasks(doc, task.id, subtaskDoc.tasks);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
this.log(`sub-decompose: final task count: ${doc.tasks.length}`);
|
|
286
|
+
await writeFile(this.tasksPath, serializeTasks(doc), "utf8");
|
|
287
|
+
}
|
|
288
|
+
async phaseExecute() {
|
|
289
|
+
try {
|
|
290
|
+
const reconciliation = await this.deps.taskBackend.reconcileState();
|
|
291
|
+
this.log(`execute: reconcile ${reconciliation}`);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
295
|
+
this.log(`execute: reconcile failed: ${message}`);
|
|
296
|
+
}
|
|
297
|
+
const ready = await this.deps.taskBackend.getReadyTasks("coder");
|
|
298
|
+
const scheduled = selectExecutionOrder(ready, {
|
|
299
|
+
role: "coder",
|
|
300
|
+
roleLabelPrefix: this.config.linear.roleLabelPrefix,
|
|
301
|
+
});
|
|
302
|
+
this.log(`execute: backend=${this.deps.taskBackend.mode}, ready=${ready.length}, scheduled=${scheduled.length}`);
|
|
303
|
+
if (scheduled.length === 0) {
|
|
304
|
+
if (this.deps.taskBackend.mode === "markdown") {
|
|
305
|
+
const snapshot = await this.deps.taskBackend.snapshotForJudge();
|
|
306
|
+
const doc = parseTasks(snapshot);
|
|
307
|
+
const statusCounts = doc.tasks.reduce((acc, t) => {
|
|
308
|
+
acc[t.status] = (acc[t.status] ?? 0) + 1;
|
|
309
|
+
return acc;
|
|
310
|
+
}, {});
|
|
311
|
+
this.log(`execute: task statuses: ${JSON.stringify(statusCounts)}`);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
this.log("execute: no ready issues in linear queue");
|
|
315
|
+
}
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const eligible = [];
|
|
319
|
+
for (const task of scheduled) {
|
|
320
|
+
const backendReadiness = await this.deps.taskBackend.validateDefinitionOfReady(task);
|
|
321
|
+
const readiness = evaluateTaskReadiness(task, backendReadiness, {
|
|
322
|
+
requireDescription: this.deps.taskBackend.mode === "linear",
|
|
323
|
+
disallowAmbiguousPlaceholders: this.deps.taskBackend.mode === "linear",
|
|
324
|
+
});
|
|
325
|
+
if (!readiness.ok) {
|
|
326
|
+
const reasonText = readiness.reasons.join("; ") || "Readiness validation failed";
|
|
327
|
+
this.log(`execute: ${task.id} failed DoR: ${reasonText}`);
|
|
328
|
+
await this.withBackendRetry(() => this.deps.taskBackend.markNeedsDecision(task.id, reasonText), `markNeedsDecision(${task.id})`);
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
eligible.push(task);
|
|
332
|
+
}
|
|
333
|
+
if (eligible.length === 0) {
|
|
334
|
+
this.log("execute: no eligible tasks after DoR validation");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
this.log(`execute: dispatching ${eligible.map((t) => t.id).join(", ")}`);
|
|
338
|
+
// Mark tasks as in-progress
|
|
339
|
+
const dispatchable = [];
|
|
340
|
+
for (const task of eligible) {
|
|
341
|
+
try {
|
|
342
|
+
await this.withBackendRetry(() => this.deps.taskBackend.markInProgress(task.id), `markInProgress(${task.id})`);
|
|
343
|
+
dispatchable.push(task);
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
347
|
+
this.log(`execute: ${task.id} could not transition to in-progress: ${reason}`);
|
|
348
|
+
await this.safeMarkNeedsDecision(task.id, `IN_PROGRESS_TRANSITION_FAILED: ${reason}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (dispatchable.length === 0) {
|
|
352
|
+
this.log("execute: no dispatchable tasks after in-progress transitions");
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
// Dispatch to worker pool
|
|
356
|
+
const results = await this.deps.dispatchBatchFn(dispatchable, this.config);
|
|
357
|
+
const succeeded = results.filter((r) => r.success).length;
|
|
358
|
+
const failed = results.filter((r) => !r.success).length;
|
|
359
|
+
this.log(`execute: ${succeeded} succeeded, ${failed} failed`);
|
|
360
|
+
for (const result of results) {
|
|
361
|
+
if (result.success) {
|
|
362
|
+
const worklog = formatBuilderWorklog({
|
|
363
|
+
summary: result.output || "Task completed successfully",
|
|
364
|
+
filesChanged: result.changedFiles ?? [],
|
|
365
|
+
commandsRun: [],
|
|
366
|
+
});
|
|
367
|
+
const verifierLog = formatVerifierWorklog({
|
|
368
|
+
passed: true,
|
|
369
|
+
checks: ["Worker review verdict PASS", "Code committed successfully"],
|
|
370
|
+
notes: "Autonomous verifier accepted this issue.",
|
|
371
|
+
});
|
|
372
|
+
try {
|
|
373
|
+
await this.withBackendRetry(() => this.deps.taskBackend.markInReview(result.taskId, worklog), `markInReview(${result.taskId})`);
|
|
374
|
+
await this.withBackendRetry(() => this.deps.taskBackend.markDone(result.taskId, verifierLog), `markDone(${result.taskId})`);
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
378
|
+
this.log(`execute: ${result.taskId} post-commit transition failed: ${reason}`);
|
|
379
|
+
await this.safeMarkNeedsDecision(result.taskId, `POST_COMMIT_TRANSITION_FAILED: ${reason}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
this.log(`execute: ${result.taskId} FAILED: ${result.output}`);
|
|
384
|
+
if (result.output.startsWith("FILE_BUDGET_EXCEEDED:")) {
|
|
385
|
+
await this.safeMarkNeedsDecision(result.taskId, result.output);
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
const verifierLog = formatVerifierWorklog({
|
|
389
|
+
passed: false,
|
|
390
|
+
checks: ["Worker review verdict FAIL"],
|
|
391
|
+
notes: result.output,
|
|
392
|
+
});
|
|
393
|
+
try {
|
|
394
|
+
await this.withBackendRetry(() => this.deps.taskBackend.markFailed(result.taskId, verifierLog), `markFailed(${result.taskId})`);
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
398
|
+
this.log(`execute: ${result.taskId} failed transition failed: ${reason}`);
|
|
399
|
+
await this.safeMarkNeedsDecision(result.taskId, `FAILED_TRANSITION_ERROR: ${reason}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async phaseJudge() {
|
|
406
|
+
const plan = await readFile(this.planPath, "utf8");
|
|
407
|
+
const tasks = await this.deps.taskBackend.snapshotForJudge();
|
|
408
|
+
const learnings = await readLearnings(this.learningsPath);
|
|
409
|
+
// Verify plan hasn't drifted
|
|
410
|
+
const planUnchanged = await verifyPlanUnchanged(this.planPath, this.planHash);
|
|
411
|
+
const prompt = buildJudgePrompt(plan, tasks, learnings, "", "");
|
|
412
|
+
const agent = await this.deps.createAgentFn("judge", learnings);
|
|
413
|
+
const response = await agent.run(prompt);
|
|
414
|
+
const verdict = parseJudgeVerdict(response);
|
|
415
|
+
if (!planUnchanged) {
|
|
416
|
+
verdict.driftDetected = true;
|
|
417
|
+
}
|
|
418
|
+
if (this.config.taskBackend === "linear" && this.config.linear.driftStopThreshold > 0) {
|
|
419
|
+
const blockedCount = this.countRejectedTasks(tasks);
|
|
420
|
+
if (blockedCount >= this.config.linear.driftStopThreshold) {
|
|
421
|
+
verdict.status = "not_done";
|
|
422
|
+
verdict.driftDetected = true;
|
|
423
|
+
verdict.feedback = `DRIFT_STOP: blocked issue count ${blockedCount} reached threshold ${this.config.linear.driftStopThreshold}`;
|
|
424
|
+
if (!verdict.remainingGoals.includes("Resolve blocked issues requiring decisions")) {
|
|
425
|
+
verdict.remainingGoals.push("Resolve blocked issues requiring decisions");
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
// Record verdict as a learning
|
|
430
|
+
await appendLearning(this.learningsPath, `Cycle ${this.cycle} judge verdict: ${verdict.status}. ${verdict.feedback}`);
|
|
431
|
+
return verdict;
|
|
432
|
+
}
|
|
433
|
+
async phaseRePlan() {
|
|
434
|
+
this.cycle += 1;
|
|
435
|
+
// Re-read plan hash in case it was updated
|
|
436
|
+
const { hash } = await readPlan(this.planPath);
|
|
437
|
+
this.planHash = hash;
|
|
438
|
+
await this.deps.taskBackend.initializeCycle(this.cycle);
|
|
439
|
+
}
|
|
440
|
+
async saveCurrentCheckpoint() {
|
|
441
|
+
let tasksSnapshot = "";
|
|
442
|
+
try {
|
|
443
|
+
tasksSnapshot = await readFile(this.tasksPath, "utf8");
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
// Tasks file may not exist yet during init
|
|
447
|
+
}
|
|
448
|
+
const state = {
|
|
449
|
+
phase: this.phase,
|
|
450
|
+
cycle: this.cycle,
|
|
451
|
+
planHash: this.planHash,
|
|
452
|
+
planPath: this.planPath,
|
|
453
|
+
tasksSnapshot,
|
|
454
|
+
backendContext: await this.deps.taskBackend.getCheckpointContext(),
|
|
455
|
+
timestamp: new Date().toISOString(),
|
|
456
|
+
};
|
|
457
|
+
await saveCheckpoint(state, this.workDir);
|
|
458
|
+
}
|
|
459
|
+
async withBackendRetry(operation, label) {
|
|
460
|
+
const maxAttempts = this.config.taskBackend === "linear" ? 3 : 1;
|
|
461
|
+
let lastError;
|
|
462
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
463
|
+
try {
|
|
464
|
+
await operation();
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
lastError = error;
|
|
469
|
+
if (attempt >= maxAttempts) {
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
const delayMs = 200 * 2 ** (attempt - 1);
|
|
473
|
+
this.log(`${label} failed on attempt ${attempt}, retrying in ${delayMs}ms`);
|
|
474
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
const message = lastError instanceof Error ? lastError.message : String(lastError);
|
|
478
|
+
throw new Error(`${label} failed after ${maxAttempts} attempts: ${message}`);
|
|
479
|
+
}
|
|
480
|
+
async safeMarkNeedsDecision(taskId, reason) {
|
|
481
|
+
try {
|
|
482
|
+
await this.withBackendRetry(() => this.deps.taskBackend.markNeedsDecision(taskId, reason), `markNeedsDecision(${taskId})`);
|
|
483
|
+
}
|
|
484
|
+
catch (error) {
|
|
485
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
486
|
+
this.log(`execute: unable to mark ${taskId} as needs decision: ${message}`);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
countRejectedTasks(tasksSnapshot) {
|
|
490
|
+
let count = 0;
|
|
491
|
+
for (const line of tasksSnapshot.split("\n")) {
|
|
492
|
+
if (line.includes("[rejected]")) {
|
|
493
|
+
count += 1;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return count;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface PlanData {
|
|
2
|
+
content: string;
|
|
3
|
+
hash: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function readPlan(path: string): Promise<PlanData>;
|
|
6
|
+
export declare function verifyPlanUnchanged(path: string, expectedHash: string): Promise<boolean>;
|
|
7
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/core/plan.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACb;AAMD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9D;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG9F"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
function computeHash(content) {
|
|
4
|
+
return `sha256:${createHash("sha256").update(content, "utf8").digest("hex")}`;
|
|
5
|
+
}
|
|
6
|
+
export async function readPlan(path) {
|
|
7
|
+
const content = await readFile(path, "utf8");
|
|
8
|
+
const hash = computeHash(content);
|
|
9
|
+
return { content, hash };
|
|
10
|
+
}
|
|
11
|
+
export async function verifyPlanUnchanged(path, expectedHash) {
|
|
12
|
+
const { hash } = await readPlan(path);
|
|
13
|
+
return hash === expectedHash;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/core/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC,SAAS,WAAW,CAAC,OAAe;IACnC,OAAO,UAAU,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY;IAC1C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAY,EAAE,YAAoB;IAC3E,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,IAAI,KAAK,YAAY,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BackendTask, ReadinessValidation } from "./task-backend.js";
|
|
2
|
+
export interface ReadinessOptions {
|
|
3
|
+
requireDescription?: boolean;
|
|
4
|
+
disallowAmbiguousPlaceholders?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface ReadinessEvaluation {
|
|
7
|
+
ok: boolean;
|
|
8
|
+
reasons: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function evaluateTaskReadiness(task: BackendTask, backendValidation: ReadinessValidation, options?: ReadinessOptions): ReadinessEvaluation;
|
|
11
|
+
//# sourceMappingURL=readiness-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness-policy.d.ts","sourceRoot":"","sources":["../../src/core/readiness-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,WAAW,EACjB,iBAAiB,EAAE,mBAAmB,EACtC,OAAO,GAAE,gBAAqB,GAC5B,mBAAmB,CA0BrB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function evaluateTaskReadiness(task, backendValidation, options = {}) {
|
|
2
|
+
const reasons = [...backendValidation.reasons];
|
|
3
|
+
if (!task.title.trim()) {
|
|
4
|
+
reasons.push("Task title is empty");
|
|
5
|
+
}
|
|
6
|
+
if (options.requireDescription && !(task.description ?? "").trim()) {
|
|
7
|
+
reasons.push("Task description is required");
|
|
8
|
+
}
|
|
9
|
+
if (options.disallowAmbiguousPlaceholders) {
|
|
10
|
+
const content = `${task.title}\n${task.description ?? ""}`.toLowerCase();
|
|
11
|
+
const placeholders = ["tbd", "todo", "to be decided"];
|
|
12
|
+
for (const placeholder of placeholders) {
|
|
13
|
+
if (content.includes(placeholder)) {
|
|
14
|
+
reasons.push(`Task includes ambiguous placeholder: ${placeholder}`);
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
ok: backendValidation.ok && reasons.length === 0,
|
|
21
|
+
reasons,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=readiness-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness-policy.js","sourceRoot":"","sources":["../../src/core/readiness-policy.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,qBAAqB,CACpC,IAAiB,EACjB,iBAAsC,EACtC,UAA4B,EAAE;IAE9B,MAAM,OAAO,GAAa,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEzD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,OAAO,CAAC,kBAAkB,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,6BAA6B,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC;QACzE,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;QACtD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACxC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,wCAAwC,WAAW,EAAE,CAAC,CAAC;gBACpE,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO;QACN,EAAE,EAAE,iBAAiB,CAAC,EAAE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAChD,OAAO;KACP,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentRole } from "../agents/types.js";
|
|
2
|
+
import type { BackendTask } from "./task-backend.js";
|
|
3
|
+
export interface SchedulingOptions {
|
|
4
|
+
role: AgentRole;
|
|
5
|
+
roleLabelPrefix?: string;
|
|
6
|
+
limit?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function selectExecutionOrder(tasks: BackendTask[], options: SchedulingOptions): BackendTask[];
|
|
9
|
+
//# sourceMappingURL=scheduling-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduling-policy.d.ts","sourceRoot":"","sources":["../../src/core/scheduling-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,WAAW,EAAE,CAMpG"}
|