@lsctech/polaris 0.5.10 → 0.5.12
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/dist/autoresearch/proposal.js +61 -0
- package/dist/autoresearch/score.js +124 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/qc.js +97 -0
- package/dist/config/validator.js +16 -6
- package/dist/finalize/artifact-policy.js +35 -3
- package/dist/finalize/index.js +23 -4
- package/dist/finalize/run-report.js +189 -19
- package/dist/finalize/steps/05-generate-report.js +5 -1
- package/dist/finalize/steps/06-commit.js +2 -1
- package/dist/finalize/steps/12-archive.js +6 -0
- package/dist/loop/adapters/terminal-cli.js +131 -25
- package/dist/loop/body-parser.js +69 -6
- package/dist/loop/continue.js +19 -1
- package/dist/loop/dispatch.js +102 -67
- package/dist/loop/parent.js +22 -3
- package/dist/loop/router/engine.js +1 -0
- package/dist/loop/run-preflight.js +4 -1
- package/dist/loop/worker-packet.js +81 -2
- package/dist/medic/routing-signals.js +60 -0
- package/dist/qc/policy.js +2 -0
- package/dist/qc/providers/coderabbit.js +153 -14
- package/dist/qc/repair-loop.js +147 -1
- package/dist/qc/repair-packets.js +16 -3
- package/dist/qc/routing.js +6 -0
- package/dist/qc/types.js +3 -0
- package/dist/tracker/local-graph.js +106 -3
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ const migration_js_1 = require("./migration.js");
|
|
|
15
15
|
*/
|
|
16
16
|
class LocalGraph {
|
|
17
17
|
graph;
|
|
18
|
+
orderingDependenciesMerged = false;
|
|
18
19
|
constructor(graph) {
|
|
19
20
|
this.graph = graph;
|
|
20
21
|
}
|
|
@@ -54,19 +55,76 @@ class LocalGraph {
|
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
57
|
* Persists the graph to `.polaris/clusters/{clusterId}/clusters.json`.
|
|
57
|
-
*
|
|
58
|
+
* Children are sorted topologically before writing so the saved cluster
|
|
59
|
+
* definition reflects dependency order.
|
|
58
60
|
*
|
|
59
61
|
* @param clusterId The cluster ID to use as the directory name (e.g., "POL-198").
|
|
60
62
|
* @param repoRoot The root directory of the repository.
|
|
61
63
|
* @returns The absolute path of the written file.
|
|
62
64
|
*/
|
|
63
65
|
async save(clusterId, repoRoot = process.cwd()) {
|
|
66
|
+
this.mergeOrderingDependencies();
|
|
67
|
+
const persistedGraph = {
|
|
68
|
+
...this.graph,
|
|
69
|
+
clusters: Object.fromEntries(Object.entries(this.graph.clusters).map(([id, cluster]) => [
|
|
70
|
+
id,
|
|
71
|
+
Array.isArray(cluster.children) && cluster.children.length > 1
|
|
72
|
+
? { ...cluster, children: this.topoSortChildren(cluster.children) }
|
|
73
|
+
: cluster,
|
|
74
|
+
])),
|
|
75
|
+
};
|
|
64
76
|
const dir = node_path_1.default.join(repoRoot, ".polaris", "clusters", clusterId);
|
|
65
77
|
await (0, promises_1.mkdir)(dir, { recursive: true });
|
|
66
78
|
const filePath = node_path_1.default.join(dir, "clusters.json");
|
|
67
|
-
await (0, promises_1.writeFile)(filePath, JSON.stringify(
|
|
79
|
+
await (0, promises_1.writeFile)(filePath, JSON.stringify(persistedGraph, null, 2), "utf-8");
|
|
68
80
|
return filePath;
|
|
69
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Sort a list of children topologically using the graph dependencies.
|
|
84
|
+
* Children with no in-cluster dependencies come first; if a cycle exists,
|
|
85
|
+
* the remaining nodes are appended in their original order.
|
|
86
|
+
*/
|
|
87
|
+
topoSortChildren(children) {
|
|
88
|
+
const childSet = new Set(children);
|
|
89
|
+
const inDegree = new Map();
|
|
90
|
+
const dependents = new Map();
|
|
91
|
+
for (const child of children) {
|
|
92
|
+
inDegree.set(child, 0);
|
|
93
|
+
dependents.set(child, []);
|
|
94
|
+
}
|
|
95
|
+
for (const child of children) {
|
|
96
|
+
for (const dep of this.getDependencies(child)) {
|
|
97
|
+
if (!childSet.has(dep))
|
|
98
|
+
continue;
|
|
99
|
+
inDegree.set(child, (inDegree.get(child) ?? 0) + 1);
|
|
100
|
+
dependents.get(dep).push(child);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const queue = [];
|
|
104
|
+
for (const [child, deg] of inDegree) {
|
|
105
|
+
if (deg === 0)
|
|
106
|
+
queue.push(child);
|
|
107
|
+
}
|
|
108
|
+
const sorted = [];
|
|
109
|
+
while (queue.length > 0) {
|
|
110
|
+
const node = queue.shift();
|
|
111
|
+
sorted.push(node);
|
|
112
|
+
for (const dependent of dependents.get(node) ?? []) {
|
|
113
|
+
const newDeg = (inDegree.get(dependent) ?? 1) - 1;
|
|
114
|
+
inDegree.set(dependent, newDeg);
|
|
115
|
+
if (newDeg === 0)
|
|
116
|
+
queue.push(dependent);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (sorted.length < children.length) {
|
|
120
|
+
const sortedSet = new Set(sorted);
|
|
121
|
+
for (const child of children) {
|
|
122
|
+
if (!sortedSet.has(child))
|
|
123
|
+
sorted.push(child);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return sorted;
|
|
127
|
+
}
|
|
70
128
|
/**
|
|
71
129
|
* Returns the full v2 execution graph.
|
|
72
130
|
*/
|
|
@@ -87,12 +145,57 @@ class LocalGraph {
|
|
|
87
145
|
return this.graph.nodes[id];
|
|
88
146
|
}
|
|
89
147
|
/**
|
|
90
|
-
* Returns the dependencies for a given node
|
|
148
|
+
* Returns the dependencies for a given node, merging any dependencies declared
|
|
149
|
+
* in the node's `## Ordering` body section.
|
|
91
150
|
* @param id The ID of the node to get dependencies for.
|
|
92
151
|
* @returns An array of node IDs that the given node is blocked by.
|
|
93
152
|
*/
|
|
94
153
|
getDependencies(id) {
|
|
154
|
+
this.mergeOrderingDependencies();
|
|
95
155
|
return this.graph.dependencies[id] ?? [];
|
|
96
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Extracts issue IDs from the `## Ordering` section of a node body.
|
|
159
|
+
*
|
|
160
|
+
* Only lines that explicitly declare ordering ("depends on" or "after" / "sequence after")
|
|
161
|
+
* contribute, and "before or after" clauses are ignored because they are not strict.
|
|
162
|
+
*/
|
|
163
|
+
extractOrderingIds(body) {
|
|
164
|
+
const sectionMatch = body.match(/##\s*Ordering\b([\s\S]*?)(?:\n##\s|\n\n(?=\n##\s)|$)/i);
|
|
165
|
+
if (!sectionMatch)
|
|
166
|
+
return [];
|
|
167
|
+
const section = sectionMatch[1];
|
|
168
|
+
const cleaned = section.replace(/before\s+or\s+after\s*\[[^\]]*\]/gi, "");
|
|
169
|
+
const ids = new Set();
|
|
170
|
+
const re = /(?:depends\s+on|after)\s*\[?\s*(\w+-\d+)\b/gi;
|
|
171
|
+
for (const line of cleaned.split("\n")) {
|
|
172
|
+
if (!/^\s*[-*]\s/.test(line))
|
|
173
|
+
continue;
|
|
174
|
+
for (const match of line.matchAll(re)) {
|
|
175
|
+
ids.add(match[1]);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return [...ids];
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Merges dependencies declared in node body `## Ordering` sections into the
|
|
182
|
+
* graph's explicit dependency map. This is idempotent for the loaded graph.
|
|
183
|
+
*/
|
|
184
|
+
mergeOrderingDependencies() {
|
|
185
|
+
if (this.orderingDependenciesMerged)
|
|
186
|
+
return;
|
|
187
|
+
for (const node of Object.values(this.graph.nodes)) {
|
|
188
|
+
const orderingIds = this.extractOrderingIds(node.body ?? "");
|
|
189
|
+
if (orderingIds.length === 0)
|
|
190
|
+
continue;
|
|
191
|
+
const existing = new Set(this.graph.dependencies[node.id] ?? []);
|
|
192
|
+
for (const dep of orderingIds) {
|
|
193
|
+
if (dep !== node.id)
|
|
194
|
+
existing.add(dep);
|
|
195
|
+
}
|
|
196
|
+
this.graph.dependencies[node.id] = [...existing].sort();
|
|
197
|
+
}
|
|
198
|
+
this.orderingDependenciesMerged = true;
|
|
199
|
+
}
|
|
97
200
|
}
|
|
98
201
|
exports.LocalGraph = LocalGraph;
|