@rallycry/conveyor-agent 7.1.9 → 7.2.1

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.
@@ -598,12 +598,14 @@ var ModeController = class {
598
598
  // src/runner/lifecycle.ts
599
599
  var DEFAULT_LIFECYCLE_CONFIG = {
600
600
  idleTimeoutMs: 30 * 60 * 1e3,
601
- heartbeatIntervalMs: 3e4
601
+ heartbeatIntervalMs: 3e4,
602
+ tokenRefreshIntervalMs: 45 * 60 * 1e3
602
603
  };
603
604
  var Lifecycle = class {
604
605
  config;
605
606
  callbacks;
606
607
  heartbeatTimer = null;
608
+ tokenRefreshTimer = null;
607
609
  idleTimer = null;
608
610
  idleCheckInterval = null;
609
611
  constructor(config, callbacks) {
@@ -623,6 +625,19 @@ var Lifecycle = class {
623
625
  this.heartbeatTimer = null;
624
626
  }
625
627
  }
628
+ // ── Token refresh ─────────────────────────────────────────────────
629
+ startTokenRefresh() {
630
+ this.stopTokenRefresh();
631
+ this.tokenRefreshTimer = setInterval(() => {
632
+ this.callbacks.onTokenRefresh();
633
+ }, this.config.tokenRefreshIntervalMs);
634
+ }
635
+ stopTokenRefresh() {
636
+ if (this.tokenRefreshTimer) {
637
+ clearInterval(this.tokenRefreshTimer);
638
+ this.tokenRefreshTimer = null;
639
+ }
640
+ }
626
641
  // ── Idle timer ─────────────────────────────────────────────────────
627
642
  startIdleTimer() {
628
643
  this.clearIdleTimers();
@@ -636,6 +651,7 @@ var Lifecycle = class {
636
651
  // ── Cleanup ────────────────────────────────────────────────────────
637
652
  destroy() {
638
653
  this.stopHeartbeat();
654
+ this.stopTokenRefresh();
639
655
  this.clearIdleTimers();
640
656
  }
641
657
  // ── Private ────────────────────────────────────────────────────────
@@ -3025,16 +3041,18 @@ function buildDiscoveryTools(connection) {
3025
3041
  title: z3.string().optional().describe("The new task title"),
3026
3042
  storyPointValue: z3.number().optional().describe(SP_DESCRIPTION2),
3027
3043
  tagIds: z3.array(z3.string()).optional().describe("Array of tag IDs to assign"),
3028
- githubPRUrl: z3.string().url().optional().describe("GitHub pull request URL to link to this task")
3044
+ githubPRUrl: z3.string().url().optional().describe("GitHub pull request URL to link to this task"),
3045
+ githubBranch: z3.string().optional().describe("Set the GitHub branch name for this task (e.g. 'conveyor/my-feature-abc123')")
3029
3046
  },
3030
- async ({ title, storyPointValue, tagIds, githubPRUrl }) => {
3047
+ async ({ title, storyPointValue, tagIds, githubPRUrl, githubBranch }) => {
3031
3048
  try {
3032
3049
  await connection.call("updateTaskProperties", {
3033
3050
  sessionId: connection.sessionId,
3034
3051
  title,
3035
3052
  storyPointValue,
3036
3053
  tagIds,
3037
- githubPRUrl
3054
+ githubPRUrl,
3055
+ githubBranch
3038
3056
  });
3039
3057
  const updatedFields = [];
3040
3058
  if (title !== void 0) updatedFields.push(`title to "${title}"`);
@@ -3042,6 +3060,7 @@ function buildDiscoveryTools(connection) {
3042
3060
  updatedFields.push(`story points to ${storyPointValue}`);
3043
3061
  if (tagIds !== void 0) updatedFields.push(`tags (${tagIds.length} tag(s))`);
3044
3062
  if (githubPRUrl !== void 0) updatedFields.push(`PR link to "${githubPRUrl}"`);
3063
+ if (githubBranch !== void 0) updatedFields.push(`branch to "${githubBranch}"`);
3045
3064
  return textResult(`Task properties updated: ${updatedFields.join(", ")}`);
3046
3065
  } catch (error) {
3047
3066
  return textResult(
@@ -4916,7 +4935,8 @@ async function handleExitPlanMode(host, input) {
4916
4935
  }
4917
4936
  if (host.agentMode === "discovery") {
4918
4937
  host.hasExitedPlanMode = true;
4919
- host.pendingModeRestart = true;
4938
+ host.discoveryCompleted = true;
4939
+ host.requestStop();
4920
4940
  void host.connection.triggerIdentification();
4921
4941
  host.connection.postChatMessage(
4922
4942
  "Plan complete. Running identification \u2014 icon and agent assignment will be set automatically."
@@ -5471,6 +5491,7 @@ var QueryBridge = class {
5471
5491
  activeQuery = null;
5472
5492
  pendingToolOutputs = [];
5473
5493
  _stopped = false;
5494
+ _discoveryCompleted = false;
5474
5495
  _isParentTask = false;
5475
5496
  _wasRateLimited = false;
5476
5497
  _abortController = null;
@@ -5481,6 +5502,9 @@ var QueryBridge = class {
5481
5502
  get isStopped() {
5482
5503
  return this._stopped;
5483
5504
  }
5505
+ get isDiscoveryCompleted() {
5506
+ return this._discoveryCompleted;
5507
+ }
5484
5508
  get isParentTask() {
5485
5509
  return this._isParentTask;
5486
5510
  }
@@ -5554,6 +5578,12 @@ var QueryBridge = class {
5554
5578
  set pendingModeRestart(val) {
5555
5579
  bridge.mode.pendingModeRestart = val;
5556
5580
  },
5581
+ get discoveryCompleted() {
5582
+ return bridge._discoveryCompleted;
5583
+ },
5584
+ set discoveryCompleted(val) {
5585
+ bridge._discoveryCompleted = val;
5586
+ },
5557
5587
  get wasRateLimited() {
5558
5588
  return bridge._wasRateLimited;
5559
5589
  },
@@ -5641,6 +5671,9 @@ var SessionRunner = class _SessionRunner {
5641
5671
  _state = "connecting";
5642
5672
  stopped = false;
5643
5673
  interrupted = false;
5674
+ /** Defense-in-depth: set when the agent emits a "completed" event.
5675
+ * Prevents the core loop from processing any further messages. */
5676
+ completedThisTurn = false;
5644
5677
  taskContext = null;
5645
5678
  fullContext = null;
5646
5679
  queryBridge = null;
@@ -5664,7 +5697,8 @@ var SessionRunner = class _SessionRunner {
5664
5697
  this.inputResolver = null;
5665
5698
  resolver(null);
5666
5699
  }
5667
- }
5700
+ },
5701
+ onTokenRefresh: () => void this.refreshGithubToken()
5668
5702
  });
5669
5703
  }
5670
5704
  get state() {
@@ -5689,6 +5723,7 @@ var SessionRunner = class _SessionRunner {
5689
5723
  this.connection.sendEvent({ type: "connected", sessionId: this.sessionId });
5690
5724
  this.wireConnectionCallbacks();
5691
5725
  this.lifecycle.startHeartbeat();
5726
+ this.lifecycle.startTokenRefresh();
5692
5727
  const { pendingMessages: serverMessages } = await this.connection.call("connectAgent", {
5693
5728
  sessionId: this.sessionId
5694
5729
  });
@@ -5771,6 +5806,13 @@ var SessionRunner = class _SessionRunner {
5771
5806
  // ── Core loop ──────────────────────────────────────────────────────
5772
5807
  async coreLoop() {
5773
5808
  while (!this.stopped) {
5809
+ if (this.completedThisTurn) {
5810
+ process.stderr.write(
5811
+ "[conveyor-agent] Completed \u2014 ignoring further messages (agent-side guard)\n"
5812
+ );
5813
+ this.stopped = true;
5814
+ break;
5815
+ }
5774
5816
  if (this._state === "idle") {
5775
5817
  this.lifecycle.startIdleTimer();
5776
5818
  const msg = await this.waitForMessage();
@@ -5790,6 +5832,13 @@ var SessionRunner = class _SessionRunner {
5790
5832
  userId: msg.userId
5791
5833
  });
5792
5834
  await this.executeQuery(msg.content);
5835
+ if (this.queryBridge?.isDiscoveryCompleted) {
5836
+ process.stderr.write(
5837
+ "[conveyor-agent] Discovery completed via ExitPlanMode, shutting down\n"
5838
+ );
5839
+ this.stopped = true;
5840
+ break;
5841
+ }
5793
5842
  if (this.stopped) break;
5794
5843
  if (this.interrupted) {
5795
5844
  this.interrupted = false;
@@ -6016,7 +6065,12 @@ var SessionRunner = class _SessionRunner {
6016
6065
  runnerConfig,
6017
6066
  {
6018
6067
  onStatusChange: (status) => this.callbacks.onStatusChange(status),
6019
- onEvent: (event) => this.callbacks.onEvent(event)
6068
+ onEvent: (event) => {
6069
+ if (event.type === "completed") {
6070
+ this.completedThisTurn = true;
6071
+ }
6072
+ return this.callbacks.onEvent(event);
6073
+ }
6020
6074
  },
6021
6075
  this.config.workspaceDir
6022
6076
  );
@@ -6067,6 +6121,22 @@ var SessionRunner = class _SessionRunner {
6067
6121
  }
6068
6122
  });
6069
6123
  }
6124
+ /** Proactively refresh the GitHub token before the 1-hour expiry. */
6125
+ async refreshGithubToken() {
6126
+ try {
6127
+ const res = await this.connection.call("refreshGithubToken", {
6128
+ sessionId: this.connection.sessionId
6129
+ });
6130
+ updateRemoteToken(this.config.workspaceDir, res.token);
6131
+ process.env.GITHUB_TOKEN = res.token;
6132
+ process.env.GH_TOKEN = res.token;
6133
+ process.stderr.write("[conveyor-agent] Proactively refreshed GitHub token\n");
6134
+ } catch (err) {
6135
+ const msg = err instanceof Error ? err.message : String(err);
6136
+ process.stderr.write(`[conveyor-agent] Warning: proactive token refresh failed: ${msg}
6137
+ `);
6138
+ }
6139
+ }
6070
6140
  /** Re-fetch task context to pick up a newly created branch and check it out. */
6071
6141
  async refreshBranchForBuilding() {
6072
6142
  try {
@@ -7145,7 +7215,7 @@ var ProjectRunner = class {
7145
7215
  async handleAuditTags(request) {
7146
7216
  this.connection.emitStatus("busy");
7147
7217
  try {
7148
- const { handleTagAudit } = await import("./tag-audit-handler-WPGSBNXO.js");
7218
+ const { handleTagAudit } = await import("./tag-audit-handler-ZJYIOGCJ.js");
7149
7219
  await handleTagAudit(request, this.connection, this.projectDir);
7150
7220
  } catch (error) {
7151
7221
  const msg = error instanceof Error ? error.message : String(error);
@@ -7168,7 +7238,7 @@ var ProjectRunner = class {
7168
7238
  async handleAuditTasks(request) {
7169
7239
  this.connection.emitStatus("busy");
7170
7240
  try {
7171
- const { handleTaskAudit } = await import("./task-audit-handler-AOYSFO5B.js");
7241
+ const { handleTaskAudit } = await import("./task-audit-handler-UL4HXCE4.js");
7172
7242
  await handleTaskAudit(request, this.connection, this.projectDir);
7173
7243
  } catch (error) {
7174
7244
  const msg = error instanceof Error ? error.message : String(error);
@@ -7201,6 +7271,11 @@ var ProjectRunner = class {
7201
7271
  } catch {
7202
7272
  }
7203
7273
  }
7274
+ await this.connection.call("reportTaskAuditBatchComplete", {
7275
+ projectId: this.connection.projectId,
7276
+ requestId: request.requestId
7277
+ }).catch(() => {
7278
+ });
7204
7279
  } finally {
7205
7280
  this.connection.emitStatus("idle");
7206
7281
  }
@@ -7608,4 +7683,4 @@ export {
7608
7683
  loadForwardPorts,
7609
7684
  loadConveyorConfig
7610
7685
  };
7611
- //# sourceMappingURL=chunk-5CGROG7V.js.map
7686
+ //# sourceMappingURL=chunk-2JONMCGY.js.map