crewly 1.20.259 → 1.20.261

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 (69) hide show
  1. package/dist/backend/backend/src/constants.d.ts +5 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +5 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  6. package/dist/backend/backend/src/controllers/team/team.controller.js +49 -15
  7. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  8. package/dist/backend/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
  9. package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js +2 -1
  10. package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
  11. package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
  12. package/dist/backend/backend/src/services/agent/claude-runtime.service.js +7 -3
  13. package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
  14. package/dist/backend/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -1
  15. package/dist/backend/backend/src/services/agent/gemini-runtime.service.js +4 -4
  16. package/dist/backend/backend/src/services/agent/gemini-runtime.service.js.map +1 -1
  17. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
  18. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +6 -5
  19. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  20. package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.d.ts +2 -1
  21. package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.d.ts.map +1 -1
  22. package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.js +5 -2
  23. package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.js.map +1 -1
  24. package/dist/backend/backend/src/services/agent/runtime-startup-screen.d.ts +57 -0
  25. package/dist/backend/backend/src/services/agent/runtime-startup-screen.d.ts.map +1 -0
  26. package/dist/backend/backend/src/services/agent/runtime-startup-screen.js +91 -0
  27. package/dist/backend/backend/src/services/agent/runtime-startup-screen.js.map +1 -0
  28. package/dist/backend/backend/src/services/decisions/decision.service.d.ts +8 -0
  29. package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/decisions/decision.service.js +21 -3
  31. package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
  32. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +5 -2
  33. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +15 -6
  35. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  36. package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.d.ts +23 -7
  37. package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.js +91 -24
  39. package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.js.map +1 -1
  40. package/dist/backend/build-info.json +2 -2
  41. package/dist/cli/backend/src/constants.d.ts +5 -0
  42. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  43. package/dist/cli/backend/src/constants.js +5 -0
  44. package/dist/cli/backend/src/constants.js.map +1 -1
  45. package/dist/cli/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
  46. package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js +2 -1
  47. package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
  48. package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
  49. package/dist/cli/backend/src/services/agent/claude-runtime.service.js +7 -3
  50. package/dist/cli/backend/src/services/agent/claude-runtime.service.js.map +1 -1
  51. package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -1
  52. package/dist/cli/backend/src/services/agent/gemini-runtime.service.js +4 -4
  53. package/dist/cli/backend/src/services/agent/gemini-runtime.service.js.map +1 -1
  54. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
  55. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +6 -5
  56. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  57. package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.d.ts +2 -1
  58. package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.d.ts.map +1 -1
  59. package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.js +5 -2
  60. package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.js.map +1 -1
  61. package/dist/cli/backend/src/services/agent/runtime-startup-screen.d.ts +57 -0
  62. package/dist/cli/backend/src/services/agent/runtime-startup-screen.d.ts.map +1 -0
  63. package/dist/cli/backend/src/services/agent/runtime-startup-screen.js +91 -0
  64. package/dist/cli/backend/src/services/agent/runtime-startup-screen.js.map +1 -0
  65. package/dist/cli/backend/src/services/decisions/decision.service.d.ts +8 -0
  66. package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  67. package/dist/cli/backend/src/services/decisions/decision.service.js +21 -3
  68. package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
  69. package/package.json +1 -1
@@ -35,6 +35,26 @@ const logger = LoggerService.getInstance().createComponentLogger('TeamController
35
35
  * Used to auto-subscribe the orchestrator to agent lifecycle events.
36
36
  */
37
37
  let eventBusService = null;
38
+ /**
39
+ * WorkItem statuses in which the target agent holds the work: a STOPPED agent
40
+ * holding one is exactly who must be started (2026-10-07: Nova held ticket
41
+ * CE-206 as `running` after her start failed, and nothing restarted her).
42
+ */
43
+ const WAKE_GATE_HELD_STATUSES = new Set(['running', 'accepted', 'proposed']);
44
+ /**
45
+ * Whether a WorkItem justifies starting `sessionName`: queued/blocked work
46
+ * (any target for an explicit id, see rule 1), or work this member holds.
47
+ *
48
+ * @param w - WorkItem
49
+ * @param sessionName - Member session
50
+ * @param explicit - The caller named this WorkItem
51
+ * @returns True when it satisfies the gate
52
+ */
53
+ function isWakeEvidence(w, sessionName, explicit) {
54
+ if (w.status === 'queued' || w.status === 'blocked')
55
+ return explicit || w.target === sessionName;
56
+ return WAKE_GATE_HELD_STATUSES.has(w.status) && w.target === sessionName;
57
+ }
38
58
  /**
39
59
  * Wake-gate predicate for the `POST /api/teams/:teamId/members/:memberId/start`
40
60
  * endpoint.
@@ -117,7 +137,7 @@ async function checkWakeGate(sessionName, body) {
117
137
  const explicitWorkItemId = typeof bodyObj?.workItemId === 'string' ? bodyObj.workItemId : null;
118
138
  if (explicitWorkItemId) {
119
139
  const referenced = items.find((w) => w.id === explicitWorkItemId);
120
- if (referenced && (referenced.status === 'queued' || referenced.status === 'blocked')) {
140
+ if (referenced && isWakeEvidence(referenced, sessionName, true)) {
121
141
  return {
122
142
  allowed: true,
123
143
  reason: `caller provided workItemId=${explicitWorkItemId} (status=${referenced.status})`,
@@ -148,11 +168,9 @@ async function checkWakeGate(sessionName, body) {
148
168
  // routes to this caller. Workers spawned via the delegate-task
149
169
  // skill flow take path (2) because that flow creates the WI with
150
170
  // `target=worker` BEFORE calling start.
151
- const eligible = items.filter((w) => {
152
- if (w.status !== 'queued' && w.status !== 'blocked')
153
- return false;
154
- return w.target === sessionName;
155
- });
171
+ // Work this member holds (running / accepted / proposed) counts too: a
172
+ // stopped holder must be restarted to finish it.
173
+ const eligible = items.filter((w) => isWakeEvidence(w, sessionName, false));
156
174
  if (eligible.length > 0) {
157
175
  return {
158
176
  allowed: true,
@@ -162,7 +180,7 @@ async function checkWakeGate(sessionName, body) {
162
180
  return {
163
181
  allowed: false,
164
182
  reason: `Cannot wake '${sessionName}': pool has no queued/blocked WorkItem ` +
165
- `with target=${sessionName} and no caller-provided workItemId. Pool is ` +
183
+ `(and no work it holds) with target=${sessionName} and no caller-provided workItemId. Pool is ` +
166
184
  `the source of truth for what is in flight; either create a WorkItem ` +
167
185
  `with target set explicitly to this member, or pass workItemId in the ` +
168
186
  `request body to indicate which orphan WI you intend this wake to fulfil.`,
@@ -690,12 +708,16 @@ async function _startTeamMemberCore(context, team, member, projectPath, options
690
708
  break;
691
709
  }
692
710
  lastError = createResult.error;
711
+ // Waited for a slot behind the running-agent cap: retrying here only
712
+ // waits again (CREW-304). It is deferred, not broken — the reconciler and
713
+ // the stalled-agent recovery start it once a slot frees.
714
+ if (createResult.errorCode === RESOURCE_MODE_CONSTANTS.START_DEFERRED_ERROR_CODE) {
715
+ logger.info('Start deferred by the running-agent cap; it is retried when a slot frees', { sessionName });
716
+ break;
717
+ }
693
718
  // Don't retry non-recoverable errors (e.g. missing CLI binary, or a
694
719
  // start-up blocked on the user such as Claude Code as root / never set up)
695
720
  if (createResult.errorCode === CLAUDE_STARTUP_CONSTANTS.BLOCKED_ERROR_CODE ||
696
- // Waited for a slot behind the running-agent cap: retrying only waits
697
- // again (CREW-304); the caller treats it as deferred.
698
- createResult.errorCode === RESOURCE_MODE_CONSTANTS.START_DEFERRED_ERROR_CODE ||
699
721
  (lastError && NON_RECOVERABLE_ERROR_PATTERNS.some(p => lastError.includes(p)))) {
700
722
  logger.error('Non-recoverable error detected, skipping retries', { sessionName, lastError });
701
723
  break;
@@ -786,22 +808,34 @@ async function _startTeamMemberCore(context, team, member, projectPath, options
786
808
  const failureTeam = failureTeams.find(t => t.id === team.id);
787
809
  const failureMember = failureTeam?.members.find(m => m.id === member.id);
788
810
  const failureReason = lastError || createResult?.error || `Failed to create team member session after ${MAX_CREATION_RETRIES} attempts`;
811
+ const deferred = createResult?.errorCode === RESOURCE_MODE_CONSTANTS.START_DEFERRED_ERROR_CODE;
789
812
  if (failureTeam && failureMember) {
790
813
  // Reset to inactive if session creation failed
791
814
  failureMember.agentStatus = CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE;
792
- failureMember.sessionName = '';
793
815
  failureMember.updatedAt = new Date().toISOString();
794
- // O2: keep the reason so the dashboard can show it after a refresh.
795
- failureMember.lastStartError = { reason: failureReason, at: failureMember.updatedAt };
816
+ // A start deferred by the running-agent cap is not broken: it stays
817
+ // stopped the way an idle stop leaves it (session name kept), so the
818
+ // reconciler and the stalled-agent recovery still see it and start it
819
+ // once a slot frees. Clearing the name hid it from both (Nova, 2026-10-07).
820
+ if (!deferred) {
821
+ failureMember.sessionName = '';
822
+ // O2: keep the reason so the dashboard can show it after a refresh.
823
+ failureMember.lastStartError = { reason: failureReason, at: failureMember.updatedAt };
824
+ }
796
825
  await context.storageService.saveTeam(failureTeam);
797
826
  }
798
- logger.error('All session creation attempts failed', { retries: MAX_CREATION_RETRIES, memberName: member.name, lastError });
827
+ if (deferred) {
828
+ logger.info('Session start deferred by the running-agent cap', { memberName: member.name, sessionName });
829
+ }
830
+ else {
831
+ logger.error('All session creation attempts failed', { retries: MAX_CREATION_RETRIES, memberName: member.name, lastError });
832
+ }
799
833
  return {
800
834
  success: false,
801
835
  memberName: member.name,
802
836
  memberId: member.id,
803
837
  sessionName: null,
804
- status: 'failed',
838
+ status: deferred ? 'deferred' : 'failed',
805
839
  error: failureReason,
806
840
  errorCode: createResult?.errorCode,
807
841
  };