@rallycry/conveyor-agent 7.0.9 → 7.0.11
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/{chunk-LKO3CBJU.js → chunk-OUARAX27.js} +135 -49
- package/dist/chunk-OUARAX27.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +1 -1
- package/dist/{tag-audit-handler-4RRGIHVB.js → tag-audit-handler-L7YPDXTA.js} +40 -8
- package/dist/tag-audit-handler-L7YPDXTA.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-LKO3CBJU.js.map +0 -1
- package/dist/tag-audit-handler-4RRGIHVB.js.map +0 -1
|
@@ -501,23 +501,17 @@ var ModeController = class {
|
|
|
501
501
|
this._mode = "code-review";
|
|
502
502
|
return this._mode;
|
|
503
503
|
}
|
|
504
|
-
if (this._mode === "auto") {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
this.transitionToBuilding(context);
|
|
508
|
-
return this._mode;
|
|
509
|
-
}
|
|
504
|
+
if (this._mode === "auto" && this.canBypassPlanning(context)) {
|
|
505
|
+
this.transitionToBuilding(context);
|
|
506
|
+
return this._mode;
|
|
510
507
|
}
|
|
511
508
|
return this._mode;
|
|
512
509
|
}
|
|
513
510
|
/** Check if auto-mode can bypass planning (task already has plan + properties) */
|
|
514
511
|
canBypassPlanning(context) {
|
|
515
512
|
if (this._mode !== "auto") return false;
|
|
516
|
-
|
|
517
|
-
if (
|
|
518
|
-
if (context.status === "Planning" && context.plan?.trim() && context.storyPointId) {
|
|
519
|
-
return true;
|
|
520
|
-
}
|
|
513
|
+
if (context.status !== "Planning") return true;
|
|
514
|
+
if (context.plan?.trim() && context.storyPointId) return true;
|
|
521
515
|
return false;
|
|
522
516
|
}
|
|
523
517
|
// ── Mode transitions ───────────────────────────────────────────────
|
|
@@ -678,6 +672,28 @@ function syncWithBaseBranch(cwd, baseBranch) {
|
|
|
678
672
|
`);
|
|
679
673
|
return true;
|
|
680
674
|
}
|
|
675
|
+
function ensureOnTaskBranch(cwd, taskBranch) {
|
|
676
|
+
if (!taskBranch) return true;
|
|
677
|
+
const current = getCurrentBranch(cwd);
|
|
678
|
+
if (current === taskBranch) return true;
|
|
679
|
+
try {
|
|
680
|
+
execSync(`git fetch origin ${taskBranch}`, { cwd, stdio: "ignore", timeout: 6e4 });
|
|
681
|
+
} catch {
|
|
682
|
+
process.stderr.write(`[conveyor-agent] Warning: git fetch origin ${taskBranch} failed
|
|
683
|
+
`);
|
|
684
|
+
return false;
|
|
685
|
+
}
|
|
686
|
+
try {
|
|
687
|
+
execSync(`git checkout ${taskBranch}`, { cwd, stdio: "ignore", timeout: 3e4 });
|
|
688
|
+
} catch {
|
|
689
|
+
process.stderr.write(`[conveyor-agent] Warning: git checkout ${taskBranch} failed
|
|
690
|
+
`);
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
process.stderr.write(`[conveyor-agent] Checked out task branch ${taskBranch}
|
|
694
|
+
`);
|
|
695
|
+
return true;
|
|
696
|
+
}
|
|
681
697
|
function hasUncommittedChanges(cwd) {
|
|
682
698
|
const status = execSync("git status --porcelain", {
|
|
683
699
|
cwd,
|
|
@@ -941,7 +957,8 @@ var GetSuggestionsRequestSchema = z.object({
|
|
|
941
957
|
sessionId: z.string()
|
|
942
958
|
});
|
|
943
959
|
var GetTaskIncidentsRequestSchema = z.object({
|
|
944
|
-
sessionId: z.string()
|
|
960
|
+
sessionId: z.string(),
|
|
961
|
+
taskId: z.string().optional()
|
|
945
962
|
});
|
|
946
963
|
var CreatePullRequestRequestSchema = CreatePRInputSchema.extend({ sessionId: z.string() });
|
|
947
964
|
var UpdateTaskStatusRequestSchema = z.object({
|
|
@@ -1022,7 +1039,8 @@ var UpdateTaskPropertiesRequestSchema = z.object({
|
|
|
1022
1039
|
sessionId: z.string(),
|
|
1023
1040
|
title: z.string().optional(),
|
|
1024
1041
|
storyPointValue: z.number().int().positive().optional(),
|
|
1025
|
-
tagIds: z.array(z.string()).optional()
|
|
1042
|
+
tagIds: z.array(z.string()).optional(),
|
|
1043
|
+
githubPRUrl: z.string().url().optional()
|
|
1026
1044
|
});
|
|
1027
1045
|
var ListIconsRequestSchema = z.object({
|
|
1028
1046
|
sessionId: z.string()
|
|
@@ -2308,6 +2326,33 @@ async function resolveTaskTagContext(context) {
|
|
|
2308
2326
|
);
|
|
2309
2327
|
return injectedSection || null;
|
|
2310
2328
|
}
|
|
2329
|
+
function formatRepoRefs(repoRefs) {
|
|
2330
|
+
const parts = [];
|
|
2331
|
+
parts.push(`
|
|
2332
|
+
## Repository References`);
|
|
2333
|
+
for (const ref of repoRefs) {
|
|
2334
|
+
const icon = ref.refType === "folder" ? "folder" : "file";
|
|
2335
|
+
parts.push(`- [${icon}] \`${ref.path}\``);
|
|
2336
|
+
}
|
|
2337
|
+
return parts;
|
|
2338
|
+
}
|
|
2339
|
+
function formatIncidents(incidents) {
|
|
2340
|
+
const parts = [];
|
|
2341
|
+
parts.push(`
|
|
2342
|
+
## Linked Incidents`);
|
|
2343
|
+
parts.push(
|
|
2344
|
+
`This task has linked incidents. Review them for context on the problem being addressed.
|
|
2345
|
+
`
|
|
2346
|
+
);
|
|
2347
|
+
for (const inc of incidents) {
|
|
2348
|
+
const severity = inc.severity ? ` [${inc.severity}]` : "";
|
|
2349
|
+
const status = inc.status ? ` (${inc.status})` : "";
|
|
2350
|
+
parts.push(`### ${inc.title}${severity}${status}`);
|
|
2351
|
+
if (inc.description) parts.push(inc.description);
|
|
2352
|
+
if (inc.source) parts.push(`Source: ${inc.source}`);
|
|
2353
|
+
}
|
|
2354
|
+
return parts;
|
|
2355
|
+
}
|
|
2311
2356
|
async function buildTaskBody(context) {
|
|
2312
2357
|
const parts = [];
|
|
2313
2358
|
parts.push(`# Task: ${context.title}`);
|
|
@@ -2335,15 +2380,13 @@ ${context.plan}`);
|
|
|
2335
2380
|
}
|
|
2336
2381
|
}
|
|
2337
2382
|
if (context.repoRefs && context.repoRefs.length > 0) {
|
|
2338
|
-
parts.push(
|
|
2339
|
-
## Repository References`);
|
|
2340
|
-
for (const ref of context.repoRefs) {
|
|
2341
|
-
const icon = ref.refType === "folder" ? "folder" : "file";
|
|
2342
|
-
parts.push(`- [${icon}] \`${ref.path}\``);
|
|
2343
|
-
}
|
|
2383
|
+
parts.push(...formatRepoRefs(context.repoRefs));
|
|
2344
2384
|
}
|
|
2345
2385
|
const tagSection = await resolveTaskTagContext(context);
|
|
2346
2386
|
if (tagSection) parts.push(tagSection);
|
|
2387
|
+
if (context.incidents && context.incidents.length > 0) {
|
|
2388
|
+
parts.push(...formatIncidents(context.incidents));
|
|
2389
|
+
}
|
|
2347
2390
|
if (context.chatHistory.length > 0) {
|
|
2348
2391
|
parts.push(...formatChatHistory(context.chatHistory));
|
|
2349
2392
|
}
|
|
@@ -3425,21 +3468,24 @@ function buildDiscoveryTools(connection) {
|
|
|
3425
3468
|
{
|
|
3426
3469
|
title: z4.string().optional().describe("The new task title"),
|
|
3427
3470
|
storyPointValue: z4.number().optional().describe(SP_DESCRIPTION2),
|
|
3428
|
-
tagIds: z4.array(z4.string()).optional().describe("Array of tag IDs to assign")
|
|
3471
|
+
tagIds: z4.array(z4.string()).optional().describe("Array of tag IDs to assign"),
|
|
3472
|
+
githubPRUrl: z4.string().url().optional().describe("GitHub pull request URL to link to this task")
|
|
3429
3473
|
},
|
|
3430
|
-
async ({ title, storyPointValue, tagIds }) => {
|
|
3474
|
+
async ({ title, storyPointValue, tagIds, githubPRUrl }) => {
|
|
3431
3475
|
try {
|
|
3432
3476
|
await connection.call("updateTaskProperties", {
|
|
3433
3477
|
sessionId: connection.sessionId,
|
|
3434
3478
|
title,
|
|
3435
3479
|
storyPointValue,
|
|
3436
|
-
tagIds
|
|
3480
|
+
tagIds,
|
|
3481
|
+
githubPRUrl
|
|
3437
3482
|
});
|
|
3438
3483
|
const updatedFields = [];
|
|
3439
3484
|
if (title !== void 0) updatedFields.push(`title to "${title}"`);
|
|
3440
3485
|
if (storyPointValue !== void 0)
|
|
3441
3486
|
updatedFields.push(`story points to ${storyPointValue}`);
|
|
3442
3487
|
if (tagIds !== void 0) updatedFields.push(`tags (${tagIds.length} tag(s))`);
|
|
3488
|
+
if (githubPRUrl !== void 0) updatedFields.push(`PR link to "${githubPRUrl}"`);
|
|
3443
3489
|
return textResult(`Task properties updated: ${updatedFields.join(", ")}`);
|
|
3444
3490
|
} catch (error) {
|
|
3445
3491
|
return textResult(
|
|
@@ -5769,6 +5815,7 @@ async function emitRetryStatus(host, attempt, delayMs) {
|
|
|
5769
5815
|
await host.callbacks.onStatusChange("running");
|
|
5770
5816
|
}
|
|
5771
5817
|
function handleRateLimitPause(host, rateLimitResetsAt) {
|
|
5818
|
+
host.wasRateLimited = true;
|
|
5772
5819
|
host.connection.emitRateLimitPause(rateLimitResetsAt);
|
|
5773
5820
|
host.connection.postChatMessage(
|
|
5774
5821
|
`Rate limited. The task will be automatically re-queued and resume after ${new Date(rateLimitResetsAt).toLocaleString()}.`
|
|
@@ -5889,6 +5936,7 @@ var QueryBridge = class {
|
|
|
5889
5936
|
pendingToolOutputs = [];
|
|
5890
5937
|
_stopped = false;
|
|
5891
5938
|
_isParentTask = false;
|
|
5939
|
+
_wasRateLimited = false;
|
|
5892
5940
|
_abortController = null;
|
|
5893
5941
|
/** Called by SessionRunner when ExitPlanMode triggers a mode transition. */
|
|
5894
5942
|
onModeTransition;
|
|
@@ -5903,6 +5951,9 @@ var QueryBridge = class {
|
|
|
5903
5951
|
set isParentTask(val) {
|
|
5904
5952
|
this._isParentTask = val;
|
|
5905
5953
|
}
|
|
5954
|
+
get wasRateLimited() {
|
|
5955
|
+
return this._wasRateLimited;
|
|
5956
|
+
}
|
|
5906
5957
|
stop() {
|
|
5907
5958
|
this._stopped = true;
|
|
5908
5959
|
this._abortController?.abort();
|
|
@@ -5917,6 +5968,7 @@ var QueryBridge = class {
|
|
|
5917
5968
|
*/
|
|
5918
5969
|
async execute(context, followUpContent) {
|
|
5919
5970
|
this._stopped = false;
|
|
5971
|
+
this._wasRateLimited = false;
|
|
5920
5972
|
this._abortController = new AbortController();
|
|
5921
5973
|
const host = this.buildHost();
|
|
5922
5974
|
try {
|
|
@@ -5966,6 +6018,12 @@ var QueryBridge = class {
|
|
|
5966
6018
|
set pendingModeRestart(val) {
|
|
5967
6019
|
bridge.mode.pendingModeRestart = val;
|
|
5968
6020
|
},
|
|
6021
|
+
get wasRateLimited() {
|
|
6022
|
+
return bridge._wasRateLimited;
|
|
6023
|
+
},
|
|
6024
|
+
set wasRateLimited(val) {
|
|
6025
|
+
bridge._wasRateLimited = val;
|
|
6026
|
+
},
|
|
5969
6027
|
get activeQuery() {
|
|
5970
6028
|
return bridge.activeQuery;
|
|
5971
6029
|
},
|
|
@@ -5998,6 +6056,27 @@ var QueryBridge = class {
|
|
|
5998
6056
|
};
|
|
5999
6057
|
|
|
6000
6058
|
// src/runner/session-runner.ts
|
|
6059
|
+
function mapChatHistory(messages) {
|
|
6060
|
+
if (!messages) return [];
|
|
6061
|
+
return messages.map((m) => ({
|
|
6062
|
+
role: m.role ?? "user",
|
|
6063
|
+
content: m.content ?? "",
|
|
6064
|
+
userId: m.userId,
|
|
6065
|
+
userName: m.user?.name ?? void 0,
|
|
6066
|
+
createdAt: m.createdAt,
|
|
6067
|
+
...m.files && m.files.length > 0 ? {
|
|
6068
|
+
files: m.files.map((f) => ({
|
|
6069
|
+
fileId: f.id,
|
|
6070
|
+
fileName: f.fileName,
|
|
6071
|
+
mimeType: f.mimeType,
|
|
6072
|
+
fileSize: f.fileSize,
|
|
6073
|
+
downloadUrl: f.downloadUrl ?? "",
|
|
6074
|
+
content: f.content,
|
|
6075
|
+
contentEncoding: f.contentEncoding
|
|
6076
|
+
}))
|
|
6077
|
+
} : {}
|
|
6078
|
+
}));
|
|
6079
|
+
}
|
|
6001
6080
|
var SessionRunner = class _SessionRunner {
|
|
6002
6081
|
connection;
|
|
6003
6082
|
mode;
|
|
@@ -6104,13 +6183,20 @@ var SessionRunner = class _SessionRunner {
|
|
|
6104
6183
|
await this.shutdown("error");
|
|
6105
6184
|
return;
|
|
6106
6185
|
}
|
|
6186
|
+
if (this.fullContext?.githubBranch) {
|
|
6187
|
+
ensureOnTaskBranch(this.config.workspaceDir, this.fullContext.githubBranch);
|
|
6188
|
+
}
|
|
6107
6189
|
if (this.fullContext?.baseBranch) {
|
|
6108
6190
|
syncWithBaseBranch(this.config.workspaceDir, this.fullContext.baseBranch);
|
|
6109
6191
|
}
|
|
6110
6192
|
this.mode.resolveInitialMode(this.taskContext);
|
|
6111
6193
|
this.queryBridge = this.createQueryBridge();
|
|
6112
6194
|
this.logInitialization();
|
|
6195
|
+
const staleMessageCount = this.pendingMessages.length;
|
|
6113
6196
|
await this.executeInitialMode();
|
|
6197
|
+
if (staleMessageCount > 0) {
|
|
6198
|
+
this.pendingMessages.splice(0, staleMessageCount);
|
|
6199
|
+
}
|
|
6114
6200
|
if (!this.stopped && this._state !== "error") {
|
|
6115
6201
|
this.hasCompleted = true;
|
|
6116
6202
|
}
|
|
@@ -6135,14 +6221,31 @@ var SessionRunner = class _SessionRunner {
|
|
|
6135
6221
|
await this.run();
|
|
6136
6222
|
}
|
|
6137
6223
|
// ── Message filtering ──────────────────────────────────────────────
|
|
6138
|
-
/**
|
|
6224
|
+
/**
|
|
6225
|
+
* Returns true if the message should be skipped (not processed).
|
|
6226
|
+
*
|
|
6227
|
+
* After the agent has completed, we only process:
|
|
6228
|
+
* 1. Critical automated sources (e.g. CI failure) — always process
|
|
6229
|
+
* 2. Messages with source: "user" — real user typed in chat
|
|
6230
|
+
* 3. Messages from flushAllCombined — have a real userId but no source
|
|
6231
|
+
*
|
|
6232
|
+
* Everything else (system messages, stale history replays) is skipped.
|
|
6233
|
+
*/
|
|
6139
6234
|
shouldSkipMessage(msg) {
|
|
6140
|
-
if (!this.hasCompleted
|
|
6235
|
+
if (!this.hasCompleted) return false;
|
|
6141
6236
|
const isCritical = !!msg.source && CRITICAL_AUTOMATED_SOURCES.has(msg.source);
|
|
6142
6237
|
if (isCritical) {
|
|
6143
6238
|
this.hasCompleted = false;
|
|
6144
6239
|
return false;
|
|
6145
6240
|
}
|
|
6241
|
+
if (msg.source === "user") {
|
|
6242
|
+
this.hasCompleted = false;
|
|
6243
|
+
return false;
|
|
6244
|
+
}
|
|
6245
|
+
if (!msg.source && msg.userId !== "system") {
|
|
6246
|
+
this.hasCompleted = false;
|
|
6247
|
+
return false;
|
|
6248
|
+
}
|
|
6146
6249
|
return true;
|
|
6147
6250
|
}
|
|
6148
6251
|
// ── Core loop ──────────────────────────────────────────────────────
|
|
@@ -6160,9 +6263,6 @@ var SessionRunner = class _SessionRunner {
|
|
|
6160
6263
|
break;
|
|
6161
6264
|
}
|
|
6162
6265
|
if (this.shouldSkipMessage(msg)) continue;
|
|
6163
|
-
if (msg.userId !== "system") {
|
|
6164
|
-
this.hasCompleted = false;
|
|
6165
|
-
}
|
|
6166
6266
|
await this.setState("running");
|
|
6167
6267
|
this.interrupted = false;
|
|
6168
6268
|
await this.callbacks.onEvent({
|
|
@@ -6271,6 +6371,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
6271
6371
|
static MAX_PR_NUDGES = 3;
|
|
6272
6372
|
needsPRNudge() {
|
|
6273
6373
|
if (!this.config.isAuto || this.stopped) return false;
|
|
6374
|
+
if (this.queryBridge?.wasRateLimited) return false;
|
|
6274
6375
|
if (this.prNudgeCount > _SessionRunner.MAX_PR_NUDGES) return false;
|
|
6275
6376
|
if (!this.taskContext) return false;
|
|
6276
6377
|
return this.taskContext.status === "InProgress" && !this.taskContext.githubPRUrl;
|
|
@@ -6323,24 +6424,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
6323
6424
|
}
|
|
6324
6425
|
// ── Context & bridge construction ────────────────────────────────
|
|
6325
6426
|
buildFullContext(ctx) {
|
|
6326
|
-
const chatHistory = (ctx.chatHistory
|
|
6327
|
-
role: m.role ?? "user",
|
|
6328
|
-
content: m.content ?? "",
|
|
6329
|
-
userId: m.userId,
|
|
6330
|
-
userName: m.user?.name ?? void 0,
|
|
6331
|
-
createdAt: m.createdAt,
|
|
6332
|
-
...m.files && m.files.length > 0 ? {
|
|
6333
|
-
files: m.files.map((f) => ({
|
|
6334
|
-
fileId: f.id,
|
|
6335
|
-
fileName: f.fileName,
|
|
6336
|
-
mimeType: f.mimeType,
|
|
6337
|
-
fileSize: f.fileSize,
|
|
6338
|
-
downloadUrl: f.downloadUrl ?? "",
|
|
6339
|
-
content: f.content,
|
|
6340
|
-
contentEncoding: f.contentEncoding
|
|
6341
|
-
}))
|
|
6342
|
-
} : {}
|
|
6343
|
-
}));
|
|
6427
|
+
const chatHistory = mapChatHistory(ctx.chatHistory);
|
|
6344
6428
|
return {
|
|
6345
6429
|
taskId: ctx.id,
|
|
6346
6430
|
projectId: ctx.projectId ?? "",
|
|
@@ -6349,7 +6433,8 @@ var SessionRunner = class _SessionRunner {
|
|
|
6349
6433
|
plan: ctx.plan,
|
|
6350
6434
|
status: ctx.status,
|
|
6351
6435
|
chatHistory,
|
|
6352
|
-
agentId: null,
|
|
6436
|
+
agentId: ctx.agentId ?? null,
|
|
6437
|
+
_runnerSessionId: this.sessionId,
|
|
6353
6438
|
agentInstructions: ctx.agentInstructions ?? "",
|
|
6354
6439
|
model: ctx.model,
|
|
6355
6440
|
githubBranch: ctx.githubBranch ?? "",
|
|
@@ -6363,7 +6448,8 @@ var SessionRunner = class _SessionRunner {
|
|
|
6363
6448
|
projectAgents: ctx.projectAgents ?? void 0,
|
|
6364
6449
|
projectTags: ctx.projectTags ?? void 0,
|
|
6365
6450
|
taskTagIds: ctx.taskTagIds ?? void 0,
|
|
6366
|
-
projectObjectives: ctx.projectObjectives ?? void 0
|
|
6451
|
+
projectObjectives: ctx.projectObjectives ?? void 0,
|
|
6452
|
+
incidents: ctx.incidents ?? void 0
|
|
6367
6453
|
};
|
|
6368
6454
|
}
|
|
6369
6455
|
createQueryBridge() {
|
|
@@ -7450,7 +7536,7 @@ var ProjectRunner = class {
|
|
|
7450
7536
|
async handleAuditTags(request) {
|
|
7451
7537
|
this.connection.emitStatus("busy");
|
|
7452
7538
|
try {
|
|
7453
|
-
const { handleTagAudit } = await import("./tag-audit-handler-
|
|
7539
|
+
const { handleTagAudit } = await import("./tag-audit-handler-L7YPDXTA.js");
|
|
7454
7540
|
await handleTagAudit(request, this.connection, this.projectDir);
|
|
7455
7541
|
} catch (error) {
|
|
7456
7542
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -7871,4 +7957,4 @@ export {
|
|
|
7871
7957
|
loadForwardPorts,
|
|
7872
7958
|
loadConveyorConfig
|
|
7873
7959
|
};
|
|
7874
|
-
//# sourceMappingURL=chunk-
|
|
7960
|
+
//# sourceMappingURL=chunk-OUARAX27.js.map
|