@rallycry/conveyor-agent 7.2.3 → 7.2.5

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.
@@ -1142,9 +1142,10 @@ function isBinaryPath(filePath) {
1142
1142
  const ext = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
1143
1143
  return BINARY_EXTENSIONS.has(ext);
1144
1144
  }
1145
- function getContextBudgetChars(_model, betas) {
1145
+ function getContextBudgetChars(_model, betas, runnerMode) {
1146
1146
  const contextWindow = betas?.some((b) => b.includes("context-1m")) ? 1e6 : 2e5;
1147
- return contextWindow * 0.25 * 4;
1147
+ const budgetPct = runnerMode === "task" ? 0.15 : 0.25;
1148
+ return contextWindow * budgetPct * 4;
1148
1149
  }
1149
1150
  async function readFileContent(filePath, maxChars) {
1150
1151
  try {
@@ -1237,7 +1238,7 @@ ${formatEntry(entry)}`);
1237
1238
  }
1238
1239
  return parts.join("\n");
1239
1240
  }
1240
- async function resolveTagContext(projectTags, taskTagIds, model, betas) {
1241
+ async function resolveTagContext(projectTags, taskTagIds, model, betas, runnerMode) {
1241
1242
  if (!projectTags?.length || !taskTagIds.length) {
1242
1243
  return { injectedSection: "", stats: { injected: 0, skipped: 0 } };
1243
1244
  }
@@ -1260,7 +1261,7 @@ async function resolveTagContext(projectTags, taskTagIds, model, betas) {
1260
1261
  if (allEntries.length === 0) {
1261
1262
  return { injectedSection: "", stats: { injected: 0, skipped: 0 } };
1262
1263
  }
1263
- const budgetChars = getContextBudgetChars(model, betas);
1264
+ const budgetChars = getContextBudgetChars(model, betas, runnerMode);
1264
1265
  const budget = { remaining: budgetChars };
1265
1266
  let injected = 0;
1266
1267
  let skipped = 0;
@@ -1285,7 +1286,26 @@ async function resolveTagContext(projectTags, taskTagIds, model, betas) {
1285
1286
  }
1286
1287
 
1287
1288
  // src/execution/mode-prompt.ts
1288
- function buildPropertyInstructions(context) {
1289
+ var SP_DESC_MAX_CHARS = 80;
1290
+ function truncateDescription(desc, maxChars) {
1291
+ if (desc.length <= maxChars) return desc;
1292
+ return desc.slice(0, maxChars) + "\u2026";
1293
+ }
1294
+ function formatTagWithContextPaths(tag) {
1295
+ const desc = tag.description ? ` \u2014 ${tag.description}` : "";
1296
+ const lines = [`- Name: "${tag.name}"${desc}`];
1297
+ for (const link of tag.contextPaths ?? []) {
1298
+ const label = link.label ? ` (${link.label})` : "";
1299
+ lines.push(` \u2192 ${link.type}: ${link.path}${label}`);
1300
+ }
1301
+ return lines;
1302
+ }
1303
+ function formatTagNameOnly(tag) {
1304
+ const desc = tag.description ? ` \u2014 ${tag.description}` : "";
1305
+ return `- Name: "${tag.name}"${desc}`;
1306
+ }
1307
+ function buildPropertyInstructions(context, runnerMode) {
1308
+ const isTask = runnerMode === "task";
1289
1309
  const parts = [];
1290
1310
  parts.push(
1291
1311
  ``,
@@ -1298,29 +1318,29 @@ function buildPropertyInstructions(context) {
1298
1318
  `Don't wait for the user to ask \u2014 fill these in naturally as the plan takes shape.`,
1299
1319
  `If the user adjusts the plan significantly, update the properties to match.`
1300
1320
  );
1301
- if (context.storyPoints && context.storyPoints.length > 0) {
1321
+ if (!isTask && context.storyPoints && context.storyPoints.length > 0) {
1302
1322
  parts.push(``, `Available story point tiers:`);
1303
1323
  for (const sp of context.storyPoints) {
1304
- const desc = sp.description ? ` \u2014 ${sp.description}` : "";
1324
+ const desc = sp.description ? ` \u2014 ${truncateDescription(sp.description, SP_DESC_MAX_CHARS)}` : "";
1305
1325
  parts.push(`- Value ${sp.value}: "${sp.name}"${desc}`);
1306
1326
  }
1307
1327
  }
1308
1328
  if (context.projectTags && context.projectTags.length > 0) {
1309
- parts.push(``, `Available project tags:`);
1310
- for (const tag of context.projectTags) {
1311
- const desc = tag.description ? ` \u2014 ${tag.description}` : "";
1312
- parts.push(`- ID: "${tag.id}", Name: "${tag.name}"${desc}`);
1313
- if (tag.contextPaths?.length) {
1314
- for (const link of tag.contextPaths) {
1315
- const label = link.label ? ` (${link.label})` : "";
1316
- parts.push(` \u2192 ${link.type}: ${link.path}${label}`);
1317
- }
1318
- }
1329
+ const assignedIds = new Set(context.taskTagIds ?? []);
1330
+ const assigned = context.projectTags.filter((t) => assignedIds.has(t.id));
1331
+ const unassigned = context.projectTags.filter((t) => !assignedIds.has(t.id));
1332
+ if (assigned.length > 0) {
1333
+ parts.push(``, `Assigned tags:`);
1334
+ for (const tag of assigned) parts.push(...formatTagWithContextPaths(tag));
1335
+ }
1336
+ if (!isTask && unassigned.length > 0) {
1337
+ parts.push(``, `Available project tags:`);
1338
+ for (const tag of unassigned) parts.push(formatTagNameOnly(tag));
1319
1339
  }
1320
1340
  }
1321
1341
  return parts;
1322
1342
  }
1323
- function buildDiscoveryPrompt(context) {
1343
+ function buildDiscoveryPrompt(context, runnerMode) {
1324
1344
  const parts = [
1325
1345
  `
1326
1346
  ## Mode: Discovery`,
@@ -1379,10 +1399,10 @@ function buildDiscoveryPrompt(context) {
1379
1399
  `- It does NOT start building \u2014 the team controls when to switch to Build mode`,
1380
1400
  `- Do NOT call ExitPlanMode until you have thoroughly explored the codebase and saved a detailed plan`
1381
1401
  ];
1382
- if (context) parts.push(...buildPropertyInstructions(context));
1402
+ if (context) parts.push(...buildPropertyInstructions(context, runnerMode));
1383
1403
  return parts.join("\n");
1384
1404
  }
1385
- function buildAutoPrompt(context) {
1405
+ function buildAutoPrompt(context, runnerMode) {
1386
1406
  const parts = [
1387
1407
  `
1388
1408
  ## Mode: Auto`,
@@ -1425,13 +1445,13 @@ function buildAutoPrompt(context) {
1425
1445
  `- Only escalate when genuinely blocked (ambiguous requirements, missing access, conflicting instructions)`,
1426
1446
  `- Be thorough in discovery: read relevant files, understand the codebase architecture, then plan`
1427
1447
  ];
1428
- if (context) parts.push(...buildPropertyInstructions(context));
1448
+ if (context) parts.push(...buildPropertyInstructions(context, runnerMode));
1429
1449
  return parts.join("\n");
1430
1450
  }
1431
- function buildModePrompt(agentMode, context) {
1451
+ function buildModePrompt(agentMode, context, runnerMode) {
1432
1452
  switch (agentMode) {
1433
1453
  case "discovery":
1434
- return buildDiscoveryPrompt(context);
1454
+ return buildDiscoveryPrompt(context, runnerMode);
1435
1455
  case "building": {
1436
1456
  const parts = [
1437
1457
  `
@@ -1465,7 +1485,7 @@ function buildModePrompt(agentMode, context) {
1465
1485
  case "review":
1466
1486
  return buildReviewPrompt(context);
1467
1487
  case "auto":
1468
- return buildAutoPrompt(context);
1488
+ return buildAutoPrompt(context, runnerMode);
1469
1489
  default:
1470
1490
  return null;
1471
1491
  }
@@ -1587,14 +1607,6 @@ You are the Project Manager for this set of tasks.`,
1587
1607
  `Use the subtask tools (create_subtask, update_subtask, list_subtasks) to manage work breakdown.`
1588
1608
  );
1589
1609
  }
1590
- if (context.storyPoints && context.storyPoints.length > 0) {
1591
- parts.push(`
1592
- Story Point Tiers:`);
1593
- for (const sp of context.storyPoints) {
1594
- const desc = sp.description ? ` \u2014 ${sp.description}` : "";
1595
- parts.push(`- Value ${sp.value}: "${sp.name}"${desc}`);
1596
- }
1597
- }
1598
1610
  if (context.projectAgents && context.projectAgents.length > 0) {
1599
1611
  parts.push(`
1600
1612
  Project Agents:`);
@@ -1602,14 +1614,6 @@ Project Agents:`);
1602
1614
  parts.push(formatProjectAgentLine(pa));
1603
1615
  }
1604
1616
  }
1605
- if (context.projectObjectives && context.projectObjectives.length > 0) {
1606
- parts.push(`
1607
- Project Objectives:`);
1608
- for (const obj of context.projectObjectives) {
1609
- const dates = `${obj.startDate.split("T")[0]} to ${obj.endDate.split("T")[0]}`;
1610
- parts.push(`- **${obj.name}** (${dates})${obj.description ? ": " + obj.description : ""}`);
1611
- }
1612
- }
1613
1617
  return parts;
1614
1618
  }
1615
1619
  function buildActivePreamble(context, workspaceDir) {
@@ -1736,7 +1740,7 @@ Your responses are sent directly to the task chat \u2014 the team sees everythin
1736
1740
  if (options?.hasDebugTools) {
1737
1741
  parts.push(buildDebugModeSection(options.hypothesisTracker));
1738
1742
  }
1739
- const modePrompt = buildModePrompt(agentMode, context);
1743
+ const modePrompt = buildModePrompt(agentMode, context, mode);
1740
1744
  if (modePrompt) {
1741
1745
  parts.push(modePrompt);
1742
1746
  }
@@ -1744,7 +1748,8 @@ Your responses are sent directly to the task chat \u2014 the team sees everythin
1744
1748
  }
1745
1749
 
1746
1750
  // src/execution/prompt-builder.ts
1747
- var CHAT_HISTORY_LIMIT = 40;
1751
+ var PM_CHAT_HISTORY_LIMIT = 40;
1752
+ var TASK_CHAT_HISTORY_LIMIT = 20;
1748
1753
  function formatFileSize(bytes) {
1749
1754
  if (bytes === void 0) return "";
1750
1755
  if (bytes < 1024) return `${bytes}B`;
@@ -1766,7 +1771,7 @@ function detectRelaunchScenario(context, trustChatHistory = false) {
1766
1771
  const hasNewUserMessages = messagesAfterAgent.some((m) => m.role === "user");
1767
1772
  return hasNewUserMessages ? "feedback_relaunch" : "idle_relaunch";
1768
1773
  }
1769
- function buildPmRelaunchParts(context, lastAgentIdx, isAuto) {
1774
+ function buildPmRelaunchParts(context, lastAgentIdx, isAuto, agentMode) {
1770
1775
  const parts = [];
1771
1776
  const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
1772
1777
  if (newMessages.length > 0) {
@@ -1778,7 +1783,20 @@ function buildPmRelaunchParts(context, lastAgentIdx, isAuto) {
1778
1783
  parts.push(`You have been relaunched. No new messages since your last session.`);
1779
1784
  }
1780
1785
  if (isAuto) {
1781
- if (context.plan?.trim()) {
1786
+ if (agentMode === "building" || agentMode === "review") {
1787
+ parts.push(
1788
+ `
1789
+ Your plan has been approved. Begin implementing it now.`,
1790
+ `Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`,
1791
+ `Start by reading the relevant source files mentioned in the plan, then write code.`,
1792
+ `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`,
1793
+ `
1794
+ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,
1795
+ `Your FIRST action must be reading source files from the plan, then immediately writing code.`,
1796
+ `Do NOT summarize the plan or say "ready to implement" \u2014 start implementing.`,
1797
+ `If you are genuinely blocked, explain the specific blocker \u2014 do not go idle silently.`
1798
+ );
1799
+ } else if (context.plan?.trim()) {
1782
1800
  parts.push(
1783
1801
  `
1784
1802
  You are in auto mode. A plan already exists for this task.`,
@@ -1808,7 +1826,7 @@ function buildRelaunchWithSession(mode, context, agentMode, isAuto) {
1808
1826
  const parts = [];
1809
1827
  const lastAgentIdx = findLastAgentMessageIndex2(context.chatHistory);
1810
1828
  if (mode === "pm") {
1811
- parts.push(...buildPmRelaunchParts(context, lastAgentIdx, isAuto));
1829
+ parts.push(...buildPmRelaunchParts(context, lastAgentIdx, isAuto, agentMode));
1812
1830
  } else if (scenario === "feedback_relaunch") {
1813
1831
  const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
1814
1832
  parts.push(
@@ -1889,8 +1907,8 @@ function formatTaskFile(file) {
1889
1907
  }
1890
1908
  return [];
1891
1909
  }
1892
- function formatChatHistory(chatHistory) {
1893
- const relevant = chatHistory.slice(-CHAT_HISTORY_LIMIT);
1910
+ function formatChatHistory(chatHistory, limit) {
1911
+ const relevant = chatHistory.slice(-(limit ?? PM_CHAT_HISTORY_LIMIT));
1894
1912
  const parts = [`
1895
1913
  ## Recent Chat Context`];
1896
1914
  for (const msg of relevant) {
@@ -1904,13 +1922,14 @@ function formatChatHistory(chatHistory) {
1904
1922
  }
1905
1923
  return parts;
1906
1924
  }
1907
- async function resolveTaskTagContext(context) {
1925
+ async function resolveTaskTagContext(context, runnerMode) {
1908
1926
  if (!context.projectTags?.length || !context.taskTagIds?.length) return null;
1909
1927
  const { injectedSection } = await resolveTagContext(
1910
1928
  context.projectTags,
1911
1929
  context.taskTagIds,
1912
1930
  context.model,
1913
- context.agentSettings?.betas
1931
+ context.agentSettings?.betas,
1932
+ runnerMode
1914
1933
  );
1915
1934
  return injectedSection || null;
1916
1935
  }
@@ -1966,7 +1985,7 @@ function formatIncidents(incidents) {
1966
1985
  }
1967
1986
  return parts;
1968
1987
  }
1969
- async function buildTaskBody(context) {
1988
+ async function buildTaskBody(context, runnerMode) {
1970
1989
  const parts = [];
1971
1990
  parts.push(`# Task: ${context.title}`);
1972
1991
  if (context.projectName) {
@@ -1995,19 +2014,22 @@ ${context.plan}`);
1995
2014
  if (context.repoRefs && context.repoRefs.length > 0) {
1996
2015
  parts.push(...formatRepoRefs(context.repoRefs));
1997
2016
  }
1998
- const tagSection = await resolveTaskTagContext(context);
2017
+ const tagSection = await resolveTaskTagContext(context, runnerMode);
1999
2018
  if (tagSection) parts.push(tagSection);
2000
- if (context.projectObjectives && context.projectObjectives.length > 0) {
2001
- parts.push(...formatProjectObjectives(context.projectObjectives));
2002
- }
2003
- if (context.recentRelatedTasks && context.recentRelatedTasks.length > 0) {
2004
- parts.push(...formatRecentRelatedTasks(context.recentRelatedTasks));
2019
+ if (runnerMode !== "task") {
2020
+ if (context.projectObjectives && context.projectObjectives.length > 0) {
2021
+ parts.push(...formatProjectObjectives(context.projectObjectives));
2022
+ }
2023
+ if (context.recentRelatedTasks && context.recentRelatedTasks.length > 0) {
2024
+ parts.push(...formatRecentRelatedTasks(context.recentRelatedTasks));
2025
+ }
2005
2026
  }
2006
2027
  if (context.incidents && context.incidents.length > 0) {
2007
2028
  parts.push(...formatIncidents(context.incidents));
2008
2029
  }
2009
2030
  if (context.chatHistory.length > 0) {
2010
- parts.push(...formatChatHistory(context.chatHistory));
2031
+ const chatLimit = runnerMode === "task" ? TASK_CHAT_HISTORY_LIMIT : PM_CHAT_HISTORY_LIMIT;
2032
+ parts.push(...formatChatHistory(context.chatHistory, chatLimit));
2011
2033
  }
2012
2034
  return parts;
2013
2035
  }
@@ -2184,7 +2206,7 @@ async function buildInitialPrompt(mode, context, isAuto, agentMode) {
2184
2206
  if (isPm && agentMode === "building" && isAuto && !context.claudeSessionId && !context.githubPRUrl && scenario === "idle_relaunch") {
2185
2207
  scenario = "fresh";
2186
2208
  }
2187
- const body = await buildTaskBody(context);
2209
+ const body = await buildTaskBody(context, mode);
2188
2210
  const instructions = isPackRunner ? buildPackRunnerInstructions(context, scenario) : buildInstructions(mode, context, scenario, agentMode, isAuto);
2189
2211
  return [...body, ...instructions].join("\n");
2190
2212
  }
@@ -3058,17 +3080,17 @@ function buildDiscoveryTools(connection) {
3058
3080
  {
3059
3081
  title: z3.string().optional().describe("The new task title"),
3060
3082
  storyPointValue: z3.number().optional().describe(SP_DESCRIPTION2),
3061
- tagIds: z3.array(z3.string()).optional().describe("Array of tag IDs to assign"),
3083
+ tagNames: z3.array(z3.string()).optional().describe("Array of tag names to assign"),
3062
3084
  githubPRUrl: z3.string().url().optional().describe("GitHub pull request URL to link to this task"),
3063
3085
  githubBranch: z3.string().optional().describe("Set the GitHub branch name for this task (e.g. 'conveyor/my-feature-abc123')")
3064
3086
  },
3065
- async ({ title, storyPointValue, tagIds, githubPRUrl, githubBranch }) => {
3087
+ async ({ title, storyPointValue, tagNames, githubPRUrl, githubBranch }) => {
3066
3088
  try {
3067
3089
  await connection.call("updateTaskProperties", {
3068
3090
  sessionId: connection.sessionId,
3069
3091
  title,
3070
3092
  storyPointValue,
3071
- tagIds,
3093
+ tagNames,
3072
3094
  githubPRUrl,
3073
3095
  githubBranch
3074
3096
  });
@@ -3076,7 +3098,7 @@ function buildDiscoveryTools(connection) {
3076
3098
  if (title !== void 0) updatedFields.push(`title to "${title}"`);
3077
3099
  if (storyPointValue !== void 0)
3078
3100
  updatedFields.push(`story points to ${storyPointValue}`);
3079
- if (tagIds !== void 0) updatedFields.push(`tags (${tagIds.length} tag(s))`);
3101
+ if (tagNames !== void 0) updatedFields.push(`tags (${tagNames.length} tag(s))`);
3080
3102
  if (githubPRUrl !== void 0) updatedFields.push(`PR link to "${githubPRUrl}"`);
3081
3103
  if (githubBranch !== void 0) updatedFields.push(`branch to "${githubBranch}"`);
3082
3104
  return textResult(`Task properties updated: ${updatedFields.join(", ")}`);
@@ -5803,6 +5825,10 @@ var SessionRunner = class _SessionRunner {
5803
5825
  }
5804
5826
  this.mode.applyServerMode(this.fullContext?.agentMode, this.fullContext?.isAuto);
5805
5827
  this.mode.resolveInitialMode(this.taskContext);
5828
+ if (this.fullContext?.isAuto && this.taskContext.status === "Open" && this.mode.isBuildCapable) {
5829
+ void this.connection.triggerIdentification().catch(() => {
5830
+ });
5831
+ }
5806
5832
  this.queryBridge = this.createQueryBridge();
5807
5833
  this.logInitialization();
5808
5834
  const staleMessageCount = this.pendingMessages.length;
@@ -5995,7 +6021,7 @@ var SessionRunner = class _SessionRunner {
5995
6021
  softStop() {
5996
6022
  this.interrupted = true;
5997
6023
  this.queryBridge?.stop();
5998
- if (this.inputResolver) {
6024
+ if (this.inputResolver && this.pendingMessages.length === 0) {
5999
6025
  const resolver = this.inputResolver;
6000
6026
  this.inputResolver = null;
6001
6027
  resolver(null);
@@ -6147,9 +6173,10 @@ var SessionRunner = class _SessionRunner {
6147
6173
  if (this.fullContext && action.newMode === "review") {
6148
6174
  this.fullContext.claudeSessionId = null;
6149
6175
  }
6150
- if (this.fullContext && action.newMode === "building") {
6176
+ if (this.fullContext && (action.newMode === "building" || action.newMode === "auto" && this.mode.hasExitedPlanMode)) {
6151
6177
  void this.refreshBranchForBuilding();
6152
6178
  }
6179
+ this.completedThisTurn = false;
6153
6180
  this.connection.emitModeChanged(action.newMode);
6154
6181
  this.softStop();
6155
6182
  }
@@ -7281,7 +7308,7 @@ var ProjectRunner = class {
7281
7308
  async handleAuditTasks(request) {
7282
7309
  this.connection.emitStatus("busy");
7283
7310
  try {
7284
- const { handleTaskAudit } = await import("./task-audit-handler-UL4HXCE4.js");
7311
+ const { handleTaskAudit } = await import("./task-audit-handler-7Q7EJENK.js");
7285
7312
  await handleTaskAudit(request, this.connection, this.projectDir);
7286
7313
  } catch (error) {
7287
7314
  const msg = error instanceof Error ? error.message : String(error);
@@ -7726,4 +7753,4 @@ export {
7726
7753
  loadForwardPorts,
7727
7754
  loadConveyorConfig
7728
7755
  };
7729
- //# sourceMappingURL=chunk-N66QQFXY.js.map
7756
+ //# sourceMappingURL=chunk-JFWVIDQ2.js.map