@caseyharalson/orrery 0.7.2 → 0.9.0

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.
@@ -410,6 +410,7 @@ async function invokeAgentWithTimeout(
410
410
  * @param {string[]} stepIds - Step IDs to execute
411
411
  * @param {string} repoRoot - Repository root path
412
412
  * @param {Object} options - Options including callbacks
413
+ * @param {number} [options.timeoutMs] - Timeout in milliseconds (overrides config.failover.timeoutMs)
413
414
  * @returns {Object} - Handle with completion promise
414
415
  */
415
416
  function invokeAgentWithFailover(
@@ -420,6 +421,10 @@ function invokeAgentWithFailover(
420
421
  options = {}
421
422
  ) {
422
423
  const failoverConfig = config.failover || { enabled: false };
424
+ const timeoutMs =
425
+ options.timeoutMs !== undefined
426
+ ? options.timeoutMs
427
+ : failoverConfig.timeoutMs;
423
428
 
424
429
  // If failover is disabled, use default agent directly
425
430
  if (!failoverConfig.enabled) {
@@ -487,7 +492,7 @@ function invokeAgentWithFailover(
487
492
  planFile,
488
493
  stepIds,
489
494
  repoRoot,
490
- failoverConfig.timeoutMs,
495
+ timeoutMs,
491
496
  options
492
497
  );
493
498
 
@@ -93,8 +93,11 @@ Step to review: {stepIds}
93
93
  ## Workflow
94
94
 
95
95
  1. Read the plan file to understand the step's description, requirements, and acceptance criteria
96
- 2. Run \`git diff\` to see all uncommitted changes
97
- 3. Read modified files for full context if needed
96
+ 2. Discover all changes:
97
+ - Run \`git status --porcelain\` to list all modified, staged, and untracked files
98
+ - Run \`git diff\` for unstaged changes to tracked files
99
+ - Run \`git diff --cached\` for staged changes
100
+ 3. Read modified/created files for full context
98
101
  4. Evaluate if changes correctly implement the requirements
99
102
 
100
103
  ## Output Format (JSON)
@@ -142,6 +145,7 @@ module.exports = {
142
145
  enabled: true,
143
146
 
144
147
  // Timeout in milliseconds before trying next agent (15 minutes)
148
+ // Can be overridden via ORRERY_AGENT_TIMEOUT environment variable
145
149
  timeoutMs: 900000,
146
150
 
147
151
  // Patterns to detect failover-triggering errors from stderr
@@ -165,6 +165,19 @@ function resolveReviewMaxIterations(cliValue) {
165
165
  return config.review.maxIterations;
166
166
  }
167
167
 
168
+ function resolveAgentTimeout(cliValue) {
169
+ if (typeof cliValue === "number" && cliValue > 0) {
170
+ return cliValue;
171
+ }
172
+
173
+ const envValue = parseEnvInteger(process.env.ORRERY_AGENT_TIMEOUT);
174
+ if (envValue !== undefined) {
175
+ return envValue;
176
+ }
177
+
178
+ return config.failover.timeoutMs;
179
+ }
180
+
168
181
  function resolvePlanFile(planArg, plansDir) {
169
182
  if (!planArg) return null;
170
183
 
@@ -760,6 +773,7 @@ async function startSteps(planFile, stepIds, activeAgents, tracker) {
760
773
  stepIds,
761
774
  REPO_ROOT,
762
775
  {
776
+ timeoutMs: resolveAgentTimeout(),
763
777
  onStdout: (text, ids) => {
764
778
  if (config.logging.streamOutput) {
765
779
  const prefix = `[${ids.join(",")}]`;
@@ -849,11 +863,14 @@ async function waitForAgentCompletion(
849
863
  stepResult = createDefaultResult(stepId, result.exitCode, result.stderr);
850
864
  }
851
865
 
866
+ let stepReviews = null;
852
867
  if (config.review.enabled && stepResult.status === "complete") {
853
868
  const maxIterations = resolveReviewMaxIterations();
854
869
  if (maxIterations > 0) {
855
870
  let approved = false;
856
871
  let currentResult = stepResult;
872
+ const reviews = [];
873
+ stepReviews = reviews;
857
874
 
858
875
  for (let iteration = 1; iteration <= maxIterations; iteration++) {
859
876
  console.log(
@@ -864,7 +881,7 @@ async function waitForAgentCompletion(
864
881
  tempPlanFile,
865
882
  [stepId],
866
883
  REPO_ROOT,
867
- { stepId }
884
+ { stepId, timeoutMs: resolveAgentTimeout() }
868
885
  );
869
886
 
870
887
  if (reviewResult.error) {
@@ -875,6 +892,11 @@ async function waitForAgentCompletion(
875
892
 
876
893
  if (reviewResult.approved) {
877
894
  console.log(`Review approved for step ${stepId}`);
895
+ reviews.push({
896
+ iteration,
897
+ approved: true,
898
+ feedback: []
899
+ });
878
900
  approved = true;
879
901
  break;
880
902
  }
@@ -884,6 +906,26 @@ async function waitForAgentCompletion(
884
906
  `Review needs changes for step ${stepId}: ${issueCount} issue(s)`
885
907
  );
886
908
 
909
+ for (const fb of reviewResult.feedback) {
910
+ const loc = fb.file
911
+ ? ` ${fb.file}${fb.line ? `:${fb.line}` : ""}`
912
+ : "";
913
+ const sev =
914
+ fb.severity === "blocking" ? "[blocking]" : "[suggestion]";
915
+ console.log(` ${sev}${loc}: ${fb.comment}`);
916
+ }
917
+
918
+ reviews.push({
919
+ iteration,
920
+ approved: false,
921
+ feedback: reviewResult.feedback.map((fb) => ({
922
+ severity: fb.severity,
923
+ file: fb.file || null,
924
+ line: fb.line || null,
925
+ comment: fb.comment
926
+ }))
927
+ });
928
+
887
929
  if (iteration >= maxIterations) {
888
930
  break;
889
931
  }
@@ -896,7 +938,8 @@ async function waitForAgentCompletion(
896
938
  REPO_ROOT,
897
939
  {
898
940
  stepId,
899
- stepIds: [stepId]
941
+ stepIds: [stepId],
942
+ timeoutMs: resolveAgentTimeout()
900
943
  }
901
944
  );
902
945
 
@@ -938,7 +981,7 @@ async function waitForAgentCompletion(
938
981
  updates.push(update);
939
982
 
940
983
  // Prepare report
941
- reports.push({
984
+ const reportData = {
942
985
  step_id: stepId,
943
986
  agent: agentName,
944
987
  outcome: stepResult.status === "complete" ? "success" : "failure",
@@ -947,7 +990,11 @@ async function waitForAgentCompletion(
947
990
  artifacts: stepResult.artifacts || [],
948
991
  blocked_reason: stepResult.blockedReason || null,
949
992
  test_results: stepResult.testResults || null
950
- });
993
+ };
994
+ if (stepReviews) {
995
+ reportData.reviews = stepReviews;
996
+ }
997
+ reports.push(reportData);
951
998
  }
952
999
 
953
1000
  // Update plan file
@@ -18,6 +18,7 @@ class ProgressTracker {
18
18
  this.startTime = Date.now();
19
19
  this.stepCompletionTimes = []; // Duration of each completed step
20
20
  this.stepStartTimes = new Map(); // stepId -> startTime
21
+ this.isFirstStep = true;
21
22
  }
22
23
 
23
24
  /**
@@ -148,6 +149,12 @@ class ProgressTracker {
148
149
  * @param {string[]} stepIds - Array of step IDs starting
149
150
  */
150
151
  logStepStart(stepIds) {
152
+ if (this.isFirstStep) {
153
+ this.isFirstStep = false;
154
+ } else {
155
+ console.log("");
156
+ console.log("----------------------------------------");
157
+ }
151
158
  this.recordStart(stepIds);
152
159
  const processed = this.completedCount + this.blockedCount;
153
160
  const stepList = stepIds.join(", ");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caseyharalson/orrery",
3
- "version": "0.7.2",
3
+ "version": "0.9.0",
4
4
  "description": "Workflow planning and orchestration CLI for AI agents",
5
5
  "license": "MIT",
6
6
  "author": "Casey Haralson",