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.
- package/dist/backend/backend/src/constants.d.ts +5 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +5 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +49 -15
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js +2 -1
- package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js +7 -3
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.js +4 -4
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +6 -5
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.d.ts +2 -1
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.js +5 -2
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-startup-screen.d.ts +57 -0
- package/dist/backend/backend/src/services/agent/runtime-startup-screen.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/runtime-startup-screen.js +91 -0
- package/dist/backend/backend/src/services/agent/runtime-startup-screen.js.map +1 -0
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts +8 -0
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +21 -3
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +5 -2
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js +15 -6
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.d.ts +23 -7
- package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.js +91 -24
- package/dist/backend/backend/src/services/reconciler/stalled-agent-recovery.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +5 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +5 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js +2 -1
- package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/claude-runtime.service.js +7 -3
- package/dist/cli/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/gemini-runtime.service.js +4 -4
- package/dist/cli/backend/src/services/agent/gemini-runtime.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +6 -5
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.d.ts +2 -1
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.js +5 -2
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-startup-screen.d.ts +57 -0
- package/dist/cli/backend/src/services/agent/runtime-startup-screen.d.ts.map +1 -0
- package/dist/cli/backend/src/services/agent/runtime-startup-screen.js +91 -0
- package/dist/cli/backend/src/services/agent/runtime-startup-screen.js.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts +8 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js +21 -3
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
- 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
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
//
|
|
795
|
-
|
|
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
|
-
|
|
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
|
};
|