@shepai/cli 1.49.0 → 1.50.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.
Files changed (75) hide show
  1. package/apis/json-schema/RejectionFeedbackEntry.yaml +4 -1
  2. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +3 -0
  4. package/dist/packages/core/src/domain/generated/output.d.ts +5 -1
  5. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  6. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  7. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +34 -1
  8. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.d.ts.map +1 -1
  9. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.js +30 -0
  10. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.d.ts.map +1 -1
  11. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.js +8 -4
  12. package/dist/packages/core/src/infrastructure/services/notifications/notification-watcher.service.d.ts +1 -0
  13. package/dist/packages/core/src/infrastructure/services/notifications/notification-watcher.service.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/services/notifications/notification-watcher.service.js +20 -11
  15. package/dist/src/presentation/cli/commands/feat/ls.command.d.ts.map +1 -1
  16. package/dist/src/presentation/cli/commands/feat/ls.command.js +92 -39
  17. package/dist/src/presentation/cli/commands/feat/show.command.d.ts +6 -0
  18. package/dist/src/presentation/cli/commands/feat/show.command.d.ts.map +1 -1
  19. package/dist/src/presentation/cli/commands/feat/show.command.js +62 -24
  20. package/dist/tsconfig.build.tsbuildinfo +1 -1
  21. package/package.json +1 -1
  22. package/web/.next/BUILD_ID +1 -1
  23. package/web/.next/build-manifest.json +2 -2
  24. package/web/.next/cache/.previewinfo +1 -1
  25. package/web/.next/cache/.rscinfo +1 -1
  26. package/web/.next/cache/.tsbuildinfo +1 -1
  27. package/web/.next/cache/config.json +3 -3
  28. package/web/.next/fallback-build-manifest.json +2 -2
  29. package/web/.next/prerender-manifest.json +3 -3
  30. package/web/.next/required-server-files.js +1 -1
  31. package/web/.next/required-server-files.json +1 -1
  32. package/web/.next/server/app/_global-error.html +2 -2
  33. package/web/.next/server/app/_global-error.rsc +1 -1
  34. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  35. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  36. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  37. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  38. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  39. package/web/.next/server/app/page/server-reference-manifest.json +14 -14
  40. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  41. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +2 -2
  42. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +1 -1
  43. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  44. package/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +2 -2
  45. package/web/.next/server/chunks/ssr/_1fafa9db._.js.map +1 -1
  46. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  47. package/web/.next/server/pages/500.html +2 -2
  48. package/web/.next/server/server-reference-manifest.js +1 -1
  49. package/web/.next/server/server-reference-manifest.json +15 -15
  50. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  51. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  52. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  53. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  54. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  55. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  56. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  57. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  58. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  59. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  60. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  61. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +14 -14
  62. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  63. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +2 -2
  64. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  65. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +2 -2
  66. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  67. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  68. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +15 -15
  69. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  70. package/web/.next/static/chunks/{191ca1529c9868dd.js → 86340848468ecffa.js} +2 -2
  71. package/web/.next/trace +1 -1
  72. package/web/.next/trace-build +1 -1
  73. /package/web/.next/static/{UT60KjU8SOYIjqeqo2WT- → Hbv-BqJZOvcXHMnbSKEtM}/_buildManifest.js +0 -0
  74. /package/web/.next/static/{UT60KjU8SOYIjqeqo2WT- → Hbv-BqJZOvcXHMnbSKEtM}/_clientMiddlewareManifest.json +0 -0
  75. /package/web/.next/static/{UT60KjU8SOYIjqeqo2WT- → Hbv-BqJZOvcXHMnbSKEtM}/_ssgManifest.js +0 -0
@@ -23,14 +23,14 @@ const NODE_TO_PHASE = {
23
23
  implement: 'Implementing',
24
24
  merge: 'Merging',
25
25
  };
26
- /** Map graph node names to approval action labels. */
27
- const NODE_TO_APPROVE = {
28
- analyze: 'Approve Analysis',
29
- requirements: 'Approve PRD',
30
- research: 'Approve Research',
31
- plan: 'Approve Plan',
32
- implement: 'Approve Implementation',
33
- merge: 'Approve Merge',
26
+ /** Map graph node names to review action labels. */
27
+ const NODE_TO_REVIEW = {
28
+ analyze: 'Review Analysis',
29
+ requirements: 'Review Requirements',
30
+ research: 'Review Research',
31
+ plan: 'Review Plan',
32
+ implement: 'Review Merge',
33
+ merge: 'Review Merge',
34
34
  };
35
35
  /** Map lifecycle event phases to display labels and symbols. */
36
36
  const LIFECYCLE_EVENTS = {
@@ -63,8 +63,8 @@ function formatStatus(feature, run) {
63
63
  if (run.status === 'failed')
64
64
  return `${colors.error(symbols.error)} ${colors.error('Failed')}`;
65
65
  if (run.status === 'waiting_approval') {
66
- const action = nodeName ? (NODE_TO_APPROVE[nodeName] ?? phase) : phase;
67
- return `${colors.warning(symbols.warning)} ${colors.warning(action)}`;
66
+ const action = nodeName ? (NODE_TO_REVIEW[nodeName] ?? phase) : phase;
67
+ return `${colors.brand(symbols.pointer)} ${colors.brand(action)}`;
68
68
  }
69
69
  if (run.status === 'interrupted')
70
70
  return `${colors.error(symbols.error)} ${colors.error('Interrupted')}`;
@@ -133,7 +133,7 @@ function groupTimingsByRun(timings) {
133
133
  /**
134
134
  * Render a single timing entry (node phase, not lifecycle event).
135
135
  */
136
- function renderNodeTiming(t, isLast, isWaiting, isRunTerminal, run, maxDurationMs, maxBar) {
136
+ function renderNodeTiming(t, isLast, isWaiting, isRunTerminal, run, maxDurationMs, maxBar, rejectionMessage) {
137
137
  const lines = [];
138
138
  const isSubPhase = t.phase.includes(':');
139
139
  const label = isSubPhase
@@ -200,12 +200,21 @@ function renderNodeTiming(t, isLast, isWaiting, isRunTerminal, run, maxDurationM
200
200
  const waitBar = `${colors.warning('\u2588'.repeat(waitBarLen))}${colors.muted('\u2591'.repeat(maxBar - waitBarLen))}`;
201
201
  lines.push(`${waitLabel} ${waitBar} ${waitSecs}s (waiting)`);
202
202
  }
203
+ // Show rejection feedback after approval wait (if this phase was rejected)
204
+ if (rejectionMessage) {
205
+ const maxLen = 60;
206
+ const msg = rejectionMessage.length > maxLen
207
+ ? `${rejectionMessage.slice(0, maxLen)}\u2026`
208
+ : rejectionMessage;
209
+ lines.push(` ${colors.error(`\u21a9 rejected: "${msg}"`)}`);
210
+ }
203
211
  return lines;
204
212
  }
205
213
  /**
206
214
  * Render the full phase timing section, grouped by agent run with lifecycle events.
215
+ * @internal Exported for testing only.
207
216
  */
208
- function renderPhaseTimings(timings, currentRun, rejections = []) {
217
+ export function renderPhaseTimings(timings, currentRun, rejections = []) {
209
218
  const groups = groupTimingsByRun(timings);
210
219
  const multiRun = groups.length > 1;
211
220
  // Compute max duration across ALL timings for consistent bar scaling
@@ -240,23 +249,35 @@ function renderPhaseTimings(timings, currentRun, rejections = []) {
240
249
  currentRun?.status === 'failed' ||
241
250
  currentRun?.status === 'cancelled';
242
251
  const isWaiting = isCurrentRun && currentRun?.status === 'waiting_approval';
243
- let resumedIdx = 0;
252
+ // Build a map of phase timing IDs to rejection messages.
253
+ // A rejection belongs to the phase timing that has approvalWaitMs set
254
+ // and whose base phase matches the rejection's phase field.
255
+ // For each node timing with approvalWaitMs, find the next rejection
256
+ // for that base phase (consumed in order).
257
+ const rejectionsByPhase = new Map();
258
+ for (const r of rejections) {
259
+ const key = r.phase ?? '_legacy';
260
+ const list = rejectionsByPhase.get(key) ?? [];
261
+ list.push(r);
262
+ rejectionsByPhase.set(key, list);
263
+ }
264
+ // Track consumption index per phase
265
+ const rejectionIdx = new Map();
244
266
  for (const [idx, t] of group.timings.entries()) {
245
267
  const isLast = isLastGroup && idx === group.timings.length - 1;
246
268
  // Lifecycle event - render as a marker line
247
269
  if (isLifecycleEvent(t.phase)) {
248
270
  const event = LIFECYCLE_EVENTS[t.phase];
249
271
  if (event) {
250
- // For resumed events, show rejection feedback if available
251
- if (t.phase === 'run:resumed' && rejections.length > 0) {
252
- const feedback = rejections[resumedIdx];
253
- resumedIdx++;
254
- if (feedback?.message) {
255
- const maxLen = 60;
256
- const msg = feedback.message.length > maxLen
257
- ? `${feedback.message.slice(0, maxLen)}…`
258
- : feedback.message;
259
- lines.push(` ${colors.error(`↩ rejected: "${msg}"`)}`);
272
+ // For resumed events without a matching rejection, show as info marker
273
+ // (rejections are now rendered inline after approval wait)
274
+ if (t.phase === 'run:resumed') {
275
+ // Check if this resume was preceded by a rejection that we already rendered
276
+ // If so, skip the resumed marker to avoid visual duplication
277
+ const prevIdx = idx - 1;
278
+ const prevTiming = prevIdx >= 0 ? group.timings[prevIdx] : null;
279
+ if (prevTiming && !isLifecycleEvent(prevTiming.phase)) {
280
+ // The rejection was already shown inline, skip this marker
260
281
  continue;
261
282
  }
262
283
  }
@@ -271,8 +292,25 @@ function renderPhaseTimings(timings, currentRun, rejections = []) {
271
292
  }
272
293
  continue;
273
294
  }
295
+ // Determine if this phase timing was rejected (has approvalWaitMs and a matching rejection)
296
+ let rejectionMessage;
297
+ if (t.approvalWaitMs != null && Number(t.approvalWaitMs) > 0) {
298
+ const basePhase = t.phase.includes(':') ? t.phase.split(':')[0] : t.phase;
299
+ // Try phase-specific rejections first, then fall back to legacy (no phase)
300
+ for (const key of [basePhase, '_legacy']) {
301
+ const phaseRejections = rejectionsByPhase.get(key);
302
+ if (phaseRejections && phaseRejections.length > 0) {
303
+ const consumed = rejectionIdx.get(key) ?? 0;
304
+ if (consumed < phaseRejections.length) {
305
+ rejectionMessage = phaseRejections[consumed].message;
306
+ rejectionIdx.set(key, consumed + 1);
307
+ break;
308
+ }
309
+ }
310
+ }
311
+ }
274
312
  // Regular node phase
275
- const rendered = renderNodeTiming(t, isLast, isWaiting ?? false, isRunTerminal ?? false, isCurrentRun ? currentRun : null, maxDurationMs, MAX_BAR);
313
+ const rendered = renderNodeTiming(t, isLast, isWaiting ?? false, isRunTerminal ?? false, isCurrentRun ? currentRun : null, maxDurationMs, MAX_BAR, rejectionMessage);
276
314
  lines.push(...rendered);
277
315
  }
278
316
  }