revise-and-resubmit-cc 2.1.13 → 2.1.14
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/bin/rnr-tools.js +91 -55
- package/package.json +2 -2
package/bin/rnr-tools.js
CHANGED
|
@@ -167,40 +167,76 @@ if (command === 'execute-tasks') {
|
|
|
167
167
|
const classifications = JSON.parse(fs.readFileSync(classificationPath, 'utf8'));
|
|
168
168
|
|
|
169
169
|
// Helper function to safely escape quotes without cmd.exe string mangling
|
|
170
|
-
const
|
|
170
|
+
const executeAgentAsync = (taskString, logLabel) => {
|
|
171
171
|
const escapedPrompt = taskString.replace(/\n/g, ' ');
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
return new Promise((resolve) => {
|
|
173
|
+
try {
|
|
174
|
+
// Using stdio: 'pipe' to suppress loud output from clogging the main orchestrator's context.
|
|
175
|
+
const child = require('cross-spawn')('npx', ['@anthropic-ai/claude-code', '--dangerously-skip-permissions', '-p', escapedPrompt], { stdio: 'pipe' });
|
|
176
|
+
|
|
177
|
+
let stderrData = '';
|
|
178
|
+
if (child.stderr) {
|
|
179
|
+
child.stderr.on('data', (data) => {
|
|
180
|
+
stderrData += data.toString();
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
child.on('close', (code) => {
|
|
185
|
+
if (code !== 0) {
|
|
186
|
+
console.error(`❌ Error executing subagent for ${logLabel}: ${stderrData || 'Unknown spawn error'}`);
|
|
187
|
+
resolve(false);
|
|
188
|
+
} else {
|
|
189
|
+
resolve(true);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
child.on('error', (error) => {
|
|
194
|
+
console.error(`❌ Error executing subagent for ${logLabel}: ${error.message}`);
|
|
195
|
+
resolve(false);
|
|
196
|
+
});
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error(`❌ Error executing subagent for ${logLabel}: ${error.message}`);
|
|
199
|
+
resolve(false);
|
|
178
200
|
}
|
|
179
|
-
|
|
180
|
-
} catch (error) {
|
|
181
|
-
console.error(`Error executing subagent: ${error.message}`);
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
201
|
+
});
|
|
184
202
|
};
|
|
185
203
|
|
|
204
|
+
async function processWithConcurrency(items, concurrency, processor) {
|
|
205
|
+
const results = [];
|
|
206
|
+
const executing = new Set();
|
|
207
|
+
for (const item of items) {
|
|
208
|
+
const p = processor(item).then(res => {
|
|
209
|
+
executing.delete(p);
|
|
210
|
+
return res;
|
|
211
|
+
});
|
|
212
|
+
executing.add(p);
|
|
213
|
+
results.push(p);
|
|
214
|
+
if (executing.size >= concurrency) {
|
|
215
|
+
await Promise.race(executing);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return Promise.all(results);
|
|
219
|
+
}
|
|
220
|
+
|
|
186
221
|
console.log(`\n### Executing Tasks via Node Orchestrator ###\n`);
|
|
187
222
|
const pidPath = path.join(process.cwd(), '.rnr', 'orchestrator.pid');
|
|
188
223
|
if (fs.existsSync(path.dirname(pidPath))) {
|
|
189
224
|
fs.writeFileSync(pidPath, process.pid.toString());
|
|
190
225
|
}
|
|
191
226
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
227
|
+
(async () => {
|
|
228
|
+
// Wave 1: Isolated
|
|
229
|
+
if (classifications.isolated && classifications.isolated.length > 0) {
|
|
230
|
+
console.log(`\n#### Wave 1: Executing Isolated Comments ####\n`);
|
|
231
|
+
await processWithConcurrency(classifications.isolated, 8, async (id) => {
|
|
232
|
+
const resolvedPath = path.join(process.cwd(), 'data', 'resolved', `COMMENT_${id}_RESOLVED.md`);
|
|
233
|
+
if (fs.existsSync(resolvedPath)) {
|
|
234
|
+
console.log(`✅ COMMENT_${id} already resolved. Skipping.`);
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
console.log(`⏳ Spawning subagent for COMMENT_${id}...`);
|
|
239
|
+
const taskStr = `Task(
|
|
204
240
|
subagent_type=\`rnr-processor-isolated\`,
|
|
205
241
|
model=\`claude-3-7-sonnet-20250219\`,
|
|
206
242
|
prompt=\`
|
|
@@ -229,30 +265,30 @@ if (command === 'execute-tasks') {
|
|
|
229
265
|
</rules>
|
|
230
266
|
\`
|
|
231
267
|
)`;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Wave 2: Interlaced Groups
|
|
242
|
-
if (classifications.interlaced && classifications.interlaced.length > 0) {
|
|
243
|
-
console.log(`\n#### Wave 2: Executing Interlaced Groups ####\n`);
|
|
244
|
-
classifications.interlaced.forEach((group, index) => {
|
|
245
|
-
// Check if all are resolved
|
|
246
|
-
const allResolved = group.every(id => fs.existsSync(path.join(process.cwd(), 'data', 'resolved', `COMMENT_${id}_RESOLVED.md`)));
|
|
247
|
-
if (allResolved) {
|
|
248
|
-
console.log(`✅ Group ${index} already resolved. Skipping.`);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const filesList = group.map(id => `- data/extracted/COMMENT_${id}.md`).join('\\n ');
|
|
253
|
-
console.log(`⏳ Spawning subagent for Group ${index} [${group.join(', ')}]...`);
|
|
268
|
+
const success = await executeAgentAsync(taskStr, `COMMENT_${id}`);
|
|
269
|
+
if (success) {
|
|
270
|
+
console.log(`✅ Processed COMMENT_${id} successfully.`);
|
|
271
|
+
}
|
|
272
|
+
return success;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
254
275
|
|
|
255
|
-
|
|
276
|
+
// Wave 2: Interlaced Groups
|
|
277
|
+
if (classifications.interlaced && classifications.interlaced.length > 0) {
|
|
278
|
+
console.log(`\n#### Wave 2: Executing Interlaced Groups ####\n`);
|
|
279
|
+
await processWithConcurrency(classifications.interlaced, 8, async (group) => {
|
|
280
|
+
const groupStr = `Group [${group.join(', ')}]`;
|
|
281
|
+
// Check if all are resolved
|
|
282
|
+
const allResolved = group.every(id => fs.existsSync(path.join(process.cwd(), 'data', 'resolved', `COMMENT_${id}_RESOLVED.md`)));
|
|
283
|
+
if (allResolved) {
|
|
284
|
+
console.log(`✅ ${groupStr} already resolved. Skipping.`);
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const filesList = group.map(id => `- data/extracted/COMMENT_${id}.md`).join('\\n ');
|
|
289
|
+
console.log(`⏳ Spawning subagent for ${groupStr}...`);
|
|
290
|
+
|
|
291
|
+
const taskStr = `Task(
|
|
256
292
|
subagent_type=\`rnr-processor-interlaced\`,
|
|
257
293
|
model=\`claude-3-7-sonnet-20250219\`,
|
|
258
294
|
prompt=\`
|
|
@@ -281,14 +317,14 @@ if (command === 'execute-tasks') {
|
|
|
281
317
|
</rules>
|
|
282
318
|
\`
|
|
283
319
|
)`;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
320
|
+
const success = await executeAgentAsync(taskStr, groupStr);
|
|
321
|
+
if (success) {
|
|
322
|
+
console.log(`✅ Processed ${groupStr} successfully.`);
|
|
323
|
+
}
|
|
324
|
+
return success;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
})();
|
|
292
328
|
}
|
|
293
329
|
|
|
294
330
|
if (command === 'health-check') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "revise-and-resubmit-cc",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.14",
|
|
4
4
|
"description": "An automated, agent-based academic revision ecosystem powered by Claude Code.",
|
|
5
5
|
"main": "bin/install.js",
|
|
6
6
|
"bin": {
|
|
@@ -30,4 +30,4 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"cross-spawn": "^7.0.6"
|
|
32
32
|
}
|
|
33
|
-
}
|
|
33
|
+
}
|