crewly 1.20.355 → 1.20.358
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/config/constants.ts +11 -0
- package/config/roles/team-leader/prompt.md +1 -1
- package/config/roles/team-leader/tl-addon.md +1 -1
- package/config/skills/team-leader/delegate-task/SKILL.md +23 -1
- package/config/skills/team-leader/delegate-task/execute.sh +44 -1
- package/config/skills/team-leader/delegate-task/execute.test.sh +95 -1
- package/dist/backend/backend/src/constants.d.ts +319 -17
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +322 -17
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +10 -0
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js +7 -0
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.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 +5 -0
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +15 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +138 -15
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +21 -2
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +100 -3
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts +34 -1
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js +69 -13
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts +8 -0
- package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/idle-detection.service.js +26 -2
- package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +9 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +60 -4
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts +22 -0
- package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode-protection.js +33 -0
- package/dist/backend/backend/src/services/agent/resource-mode-protection.js.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts +59 -3
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.js +108 -10
- package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts +44 -3
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.js +126 -11
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +2 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +9 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts +23 -0
- package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-relogin.service.js +47 -6
- package/dist/backend/backend/src/services/harness/harness-relogin.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts +150 -0
- package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js +319 -0
- package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js.map +1 -0
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +9 -7
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +19 -17
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/memory.service.js +11 -0
- package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts +104 -0
- package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/memory/startup-briefing.service.js +302 -0
- package/dist/backend/backend/src/services/memory/startup-briefing.service.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +14 -2
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +21 -4
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +33 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js +69 -4
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.d.ts +24 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.js +54 -3
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js +10 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +8 -0
- package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.js +33 -0
- package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.wiring.js +2 -2
- package/dist/backend/backend/src/services/open-items/open-items.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/question-card-gate.d.ts +49 -0
- package/dist/backend/backend/src/services/open-items/question-card-gate.d.ts.map +1 -0
- package/dist/backend/backend/src/services/open-items/question-card-gate.js +77 -0
- package/dist/backend/backend/src/services/open-items/question-card-gate.js.map +1 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts +9 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.js +16 -2
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +10 -0
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +2 -0
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +17 -0
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts +7 -0
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +22 -10
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.d.ts +30 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.d.ts.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.js +48 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.js.map +1 -0
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +8 -0
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js +29 -8
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts +16 -0
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js +23 -0
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts +2 -1
- package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/reset-time.js +3 -2
- package/dist/backend/backend/src/services/runtime-fallback/reset-time.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts +128 -5
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js +320 -38
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts +23 -0
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js +48 -3
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +78 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js +159 -1
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.d.ts +63 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.js +104 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.js.map +1 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.d.ts +166 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.js +207 -0
- package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.js.map +1 -0
- package/dist/backend/backend/src/services/slack/agent-coordination.d.ts +119 -0
- package/dist/backend/backend/src/services/slack/agent-coordination.d.ts.map +1 -0
- package/dist/backend/backend/src/services/slack/agent-coordination.js +174 -0
- package/dist/backend/backend/src/services/slack/agent-coordination.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +7 -0
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +167 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +619 -9
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts +22 -0
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +49 -12
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +7 -0
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +25 -4
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts +21 -1
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-chat.js +54 -2
- package/dist/backend/backend/src/services/team-move/team-move-chat.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts +9 -4
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js +32 -10
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts +19 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-importer.js +78 -3
- package/dist/backend/backend/src/services/team-move/team-move-importer.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js +8 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-transcripts.d.ts +106 -0
- package/dist/backend/backend/src/services/team-move/team-move-transcripts.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-transcripts.js +212 -0
- package/dist/backend/backend/src/services/team-move/team-move-transcripts.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts +20 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move.types.js.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts +2 -2
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +11 -4
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +13 -0
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js +3 -0
- package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js +4 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js +4 -0
- package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +33 -4
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js +75 -7
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-lint.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-lint.service.js +3 -1
- package/dist/backend/backend/src/services/wiki/wiki-lint.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts +116 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js +227 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts +142 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-entries.js +222 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-entries.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts +93 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js +142 -0
- package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts +104 -0
- package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js +192 -0
- package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts +3 -2
- package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-query.service.js +23 -39
- package/dist/backend/backend/src/services/wiki/wiki-query.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.d.ts +105 -0
- package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.js +195 -0
- package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-recent.service.js +3 -0
- package/dist/backend/backend/src/services/wiki/wiki-recent.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts +28 -5
- package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-search.service.js +96 -25
- package/dist/backend/backend/src/services/wiki/wiki-search.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-vault-walk.d.ts +11 -0
- package/dist/backend/backend/src/services/wiki/wiki-vault-walk.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-vault-walk.js +17 -1
- package/dist/backend/backend/src/services/wiki/wiki-vault-walk.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +22 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.js +35 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +12 -0
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.d.ts +1 -0
- package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/backend/config/constants.d.ts +11 -0
- package/dist/backend/config/constants.d.ts.map +1 -1
- package/dist/backend/config/constants.js +11 -0
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +319 -17
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +322 -17
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +21 -2
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js +100 -3
- package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts +34 -1
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js +69 -13
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +9 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +60 -4
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts +59 -3
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.js +108 -10
- package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts +44 -3
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.js +126 -11
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +2 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +9 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts +23 -0
- package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-relogin.service.js +47 -6
- package/dist/cli/backend/src/services/harness/harness-relogin.service.js.map +1 -1
- package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/memory/memory.service.js +11 -0
- package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
- package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts +104 -0
- package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/memory/startup-briefing.service.js +302 -0
- package/dist/cli/backend/src/services/memory/startup-briefing.service.js.map +1 -0
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +33 -1
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js +69 -4
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js +10 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +8 -0
- package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-items.service.js +33 -0
- package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
- package/dist/cli/backend/src/services/open-items/question-card-gate.d.ts +49 -0
- package/dist/cli/backend/src/services/open-items/question-card-gate.d.ts.map +1 -0
- package/dist/cli/backend/src/services/open-items/question-card-gate.js +77 -0
- package/dist/cli/backend/src/services/open-items/question-card-gate.js.map +1 -0
- package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +2 -0
- package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js +17 -0
- package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
- package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts +7 -0
- package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js +22 -10
- package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts +16 -0
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js +23 -0
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts +2 -1
- package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/reset-time.js +3 -2
- package/dist/cli/backend/src/services/runtime-fallback/reset-time.js.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +78 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js +159 -1
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.d.ts +63 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.js +104 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.d.ts +166 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.js +207 -0
- package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.js.map +1 -0
- package/dist/cli/backend/src/services/slack/agent-coordination.d.ts +119 -0
- package/dist/cli/backend/src/services/slack/agent-coordination.d.ts.map +1 -0
- package/dist/cli/backend/src/services/slack/agent-coordination.js +174 -0
- package/dist/cli/backend/src/services/slack/agent-coordination.js.map +1 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +167 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +619 -9
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts +22 -0
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +49 -12
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +7 -0
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +25 -4
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +33 -4
- package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js +75 -7
- package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts +142 -0
- package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -0
- package/dist/cli/backend/src/services/wiki/wiki-log-entries.js +222 -0
- package/dist/cli/backend/src/services/wiki/wiki-log-entries.js.map +1 -0
- package/dist/cli/backend/src/services/wiki/wiki-recent.service.d.ts +51 -0
- package/dist/cli/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/wiki/wiki-recent.service.js +105 -0
- package/dist/cli/backend/src/services/wiki/wiki-recent.service.js.map +1 -0
- package/dist/cli/backend/src/services/wiki/wiki-search.service.d.ts +28 -5
- package/dist/cli/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-search.service.js +96 -25
- package/dist/cli/backend/src/services/wiki/wiki-search.service.js.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-vault-walk.d.ts +11 -0
- package/dist/cli/backend/src/services/wiki/wiki-vault-walk.d.ts.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-vault-walk.js +17 -1
- package/dist/cli/backend/src/services/wiki/wiki-vault-walk.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +12 -0
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/backend/src/types/team-template.types.d.ts +1 -0
- package/dist/cli/backend/src/types/team-template.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/team-template.types.js.map +1 -1
- package/dist/cli/config/constants.d.ts +11 -0
- package/dist/cli/config/constants.d.ts.map +1 -1
- package/dist/cli/config/constants.js +11 -0
- package/dist/cli/config/constants.js.map +1 -1
- package/package.json +1 -1
|
@@ -24,6 +24,17 @@
|
|
|
24
24
|
* most every BILLING_PROBE_INTERVAL_MS. A switch-back that fails (the limit
|
|
25
25
|
* comes straight back) doubles the next probe interval.
|
|
26
26
|
* 7. **Tell the owner once** per event, and once when it is over.
|
|
27
|
+
* 8. **Prefer the better target.** While the configured runtime is still out,
|
|
28
|
+
* an agent on a fallback moves (at an idle boundary, or when it is next
|
|
29
|
+
* started) to the earliest available entry of its chain when that is
|
|
30
|
+
* earlier than the one it is on — orc on `claude-code@work` goes back to
|
|
31
|
+
* `claude-code` once the default login has usage, even though its own
|
|
32
|
+
* runtime (DeepSeek, out of credit) is not back.
|
|
33
|
+
* 9. **Stale marks are cleared** when the reset time passes and a probe
|
|
34
|
+
* answers, when the owner signs that login in again
|
|
35
|
+
* ({@link RuntimeFallbackService.onRuntimeLogin} /
|
|
36
|
+
* {@link RuntimeFallbackService.onAccountLogin}), or when another session
|
|
37
|
+
* on that target is seen working ({@link RuntimeFallbackService.reportWorking}).
|
|
27
38
|
*
|
|
28
39
|
* A chain entry may be one of the owner's other Claude Code accounts
|
|
29
40
|
* (`claude-code@work`, issue #942): it is a runtime target of its own — out
|
|
@@ -41,6 +52,7 @@
|
|
|
41
52
|
*/
|
|
42
53
|
import { ORCHESTRATOR_SESSION_NAME, RUNTIME_FALLBACK_CONSTANTS, RUNTIME_TYPES } from '../../constants.js';
|
|
43
54
|
import { detectUsageLimit } from './usage-limit-rules.js';
|
|
55
|
+
import { clearUsageLimit } from './usage-limit-state.js';
|
|
44
56
|
import { traceRuntimeBlocked } from '../trace/trace-recorder.js';
|
|
45
57
|
import { accountOf, baseRuntimeOf, parseRuntimeTarget, runtimeTarget } from '../harness/claude-accounts.js';
|
|
46
58
|
import { applySettingsPatch, runtimeLabel, runtimeShortLabel, } from './runtime-fallback.types.js';
|
|
@@ -76,6 +88,8 @@ export class RuntimeFallbackService {
|
|
|
76
88
|
noticeDue = new Map();
|
|
77
89
|
/** Kickoff notes waiting for a session's next launch */
|
|
78
90
|
kickoffNotes = new Map();
|
|
91
|
+
/** Last working-evidence look per session (throttle) */
|
|
92
|
+
workingSeen = new Map();
|
|
79
93
|
/** Last switch-back per runtime, to recognise one that failed */
|
|
80
94
|
recentRecoveries = new Map();
|
|
81
95
|
availability = null;
|
|
@@ -179,7 +193,7 @@ export class RuntimeFallbackService {
|
|
|
179
193
|
this.availability = null;
|
|
180
194
|
const target = runtimeTarget(RUNTIME_TYPES.CLAUDE_CODE, account);
|
|
181
195
|
try {
|
|
182
|
-
await this.
|
|
196
|
+
await this.recheckAfterLogin(target);
|
|
183
197
|
}
|
|
184
198
|
finally {
|
|
185
199
|
// The owner is away: a freshly signed-in account must be usable at once,
|
|
@@ -254,27 +268,94 @@ export class RuntimeFallbackService {
|
|
|
254
268
|
}
|
|
255
269
|
}
|
|
256
270
|
/**
|
|
257
|
-
*
|
|
271
|
+
* The owner signed a harness's default login in again (the re-login flow
|
|
272
|
+
* finished for it). A mark on that runtime — signed out, or out of usage:
|
|
273
|
+
* the new login may be another account, or the same one with usage bought
|
|
274
|
+
* — is probed now instead of at its reset time, and cleared when the
|
|
275
|
+
* probe answers.
|
|
258
276
|
*
|
|
259
|
-
* @param
|
|
277
|
+
* @param runtime - Runtime id (`claude-code`, `codex-cli`, …; the harness id)
|
|
278
|
+
* @returns Resolves when done; never rejects
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```ts
|
|
282
|
+
* relogin.setHarnessLoginHandler((harnessId) => service.onRuntimeLogin(harnessId));
|
|
283
|
+
* ```
|
|
260
284
|
*/
|
|
261
|
-
async
|
|
285
|
+
async onRuntimeLogin(runtime) {
|
|
286
|
+
this.availability = null;
|
|
287
|
+
try {
|
|
288
|
+
await this.recheckAfterLogin(runtime);
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
this.logger.warn('Re-checking a runtime after a sign-in failed', { runtime, error: err instanceof Error ? err.message : String(err) });
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* A login of a runtime target was signed in again: if it is marked (signed
|
|
296
|
+
* out or out of usage), probe it and bring it back when it answers.
|
|
297
|
+
*
|
|
298
|
+
* @param target - Runtime target (`claude-code`, `claude-code@<account>`)
|
|
299
|
+
*/
|
|
300
|
+
async recheckAfterLogin(target) {
|
|
262
301
|
const entry = this.state.exhausted[target];
|
|
263
|
-
if (!entry
|
|
302
|
+
if (!entry)
|
|
264
303
|
return;
|
|
265
304
|
const result = await this.deps.probe(target).catch(() => 'unknown');
|
|
266
305
|
entry.lastProbeAt = new Date(this.now()).toISOString();
|
|
267
306
|
if (result === 'available') {
|
|
307
|
+
this.logger.info('Signed in again and the probe answers — clearing the out-of-usage mark', { runtime: target, kind: entry.kind ?? 'usage_limit' });
|
|
268
308
|
await this.recover(target);
|
|
269
309
|
return;
|
|
270
310
|
}
|
|
271
|
-
if (result === 'limited') {
|
|
311
|
+
if (result === 'limited' && entry.kind === 'login') {
|
|
272
312
|
// Signed in again, but that account is out of usage too.
|
|
273
313
|
entry.kind = 'usage_limit';
|
|
274
314
|
entry.ruleId = 'probe_limited';
|
|
275
315
|
}
|
|
276
316
|
this.save();
|
|
277
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* A session's model just answered with a tool call (Claude Code
|
|
320
|
+
* PreToolUse hook). A model cannot do that while its account is out of
|
|
321
|
+
* usage, so a mark on the target the session runs on is stale: it is
|
|
322
|
+
* cleared (agents moved off it come back at their idle boundary). Marks
|
|
323
|
+
* newer than WORKING_EVIDENCE_GRACE_MS are kept (a turn already streaming
|
|
324
|
+
* when the limit hit proves nothing). Looked at most once a minute per
|
|
325
|
+
* session, and only while a Claude Code target is marked.
|
|
326
|
+
*
|
|
327
|
+
* @param sessionName - Session the hook came from
|
|
328
|
+
*/
|
|
329
|
+
reportWorking(sessionName) {
|
|
330
|
+
if (!this.state.settings.enabled || this.isExempt(sessionName))
|
|
331
|
+
return;
|
|
332
|
+
if (!Object.keys(this.state.exhausted).some((r) => baseRuntimeOf(r) === RUNTIME_TYPES.CLAUDE_CODE))
|
|
333
|
+
return;
|
|
334
|
+
if (this.switching.has(sessionName))
|
|
335
|
+
return;
|
|
336
|
+
const now = this.now();
|
|
337
|
+
if (now - (this.workingSeen.get(sessionName) ?? Number.NEGATIVE_INFINITY) < C.WORKING_EVIDENCE_THROTTLE_MS)
|
|
338
|
+
return;
|
|
339
|
+
this.workingSeen.set(sessionName, now);
|
|
340
|
+
void this.onWorking(sessionName).catch((err) => this.logger.warn('Runtime fallback could not use a working signal', { sessionName, error: err instanceof Error ? err.message : String(err) }));
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Clear the mark on the target a working session runs on.
|
|
344
|
+
*
|
|
345
|
+
* @param sessionName - Session
|
|
346
|
+
*/
|
|
347
|
+
async onWorking(sessionName) {
|
|
348
|
+
const target = this.state.overrides[sessionName]?.runtime ?? (await this.deps.getAgent(sessionName).catch(() => null))?.primary;
|
|
349
|
+
if (!target || baseRuntimeOf(target) !== RUNTIME_TYPES.CLAUDE_CODE)
|
|
350
|
+
return;
|
|
351
|
+
const entry = this.state.exhausted[target];
|
|
352
|
+
if (!entry)
|
|
353
|
+
return;
|
|
354
|
+
if (this.now() - Date.parse(entry.since) < C.WORKING_EVIDENCE_GRACE_MS)
|
|
355
|
+
return;
|
|
356
|
+
this.logger.info('A session is working on a runtime marked out of usage — clearing the mark', { runtime: target, sessionName, since: entry.since });
|
|
357
|
+
await this.recover(target);
|
|
358
|
+
}
|
|
278
359
|
/**
|
|
279
360
|
* Take the note for a session's next kickoff.
|
|
280
361
|
*
|
|
@@ -356,10 +437,23 @@ export class RuntimeFallbackService {
|
|
|
356
437
|
}
|
|
357
438
|
else if (existing.revertPending && !this.state.exhausted[existing.primary]) {
|
|
358
439
|
// A stopped agent being started after its runtime came back.
|
|
359
|
-
this.finishRevertOffline(input.sessionName, existing);
|
|
440
|
+
await this.finishRevertOffline(input.sessionName, existing);
|
|
360
441
|
return configured;
|
|
361
442
|
}
|
|
443
|
+
else if (!this.state.exhausted[existing.primary]) {
|
|
444
|
+
// Its runtime is back but not yet marked for revert: the next tick reverts it.
|
|
445
|
+
return this.decision(existing.runtime);
|
|
446
|
+
}
|
|
362
447
|
else {
|
|
448
|
+
// Starting anyway: on the best target of its chain, not on one that ran
|
|
449
|
+
// out meanwhile or below one that came back.
|
|
450
|
+
const agent = await this.launchAgent(input);
|
|
451
|
+
const better = await this.betterTarget(agent, existing.runtime, true);
|
|
452
|
+
if (better) {
|
|
453
|
+
await this.recordSwitch(agent, existing.runtime, better, null, this.state.exhausted[existing.runtime] ? 'switch' : 'upgrade');
|
|
454
|
+
this.logger.info('Starting an agent on a better fallback runtime', { sessionName: input.sessionName, from: existing.runtime, runtime: better });
|
|
455
|
+
return this.decision(better);
|
|
456
|
+
}
|
|
363
457
|
return this.decision(existing.runtime);
|
|
364
458
|
}
|
|
365
459
|
}
|
|
@@ -373,14 +467,7 @@ export class RuntimeFallbackService {
|
|
|
373
467
|
}
|
|
374
468
|
if (input.isOrchestrator && !this.state.settings.orcFollows)
|
|
375
469
|
return configured;
|
|
376
|
-
const agent =
|
|
377
|
-
sessionName: input.sessionName,
|
|
378
|
-
name: input.sessionName,
|
|
379
|
-
primary: input.configured,
|
|
380
|
-
memberId: input.memberId,
|
|
381
|
-
teamId: input.teamId,
|
|
382
|
-
isOrchestrator: input.isOrchestrator,
|
|
383
|
-
};
|
|
470
|
+
const agent = await this.launchAgent(input);
|
|
384
471
|
const target = await this.pickFallback(agent, input.configured);
|
|
385
472
|
if (!target) {
|
|
386
473
|
this.markNoFallback(input.configured);
|
|
@@ -394,6 +481,22 @@ export class RuntimeFallbackService {
|
|
|
394
481
|
});
|
|
395
482
|
return this.decision(target);
|
|
396
483
|
}
|
|
484
|
+
/**
|
|
485
|
+
* The agent behind a launch (from the launch input when it is not known).
|
|
486
|
+
*
|
|
487
|
+
* @param input - Launch input
|
|
488
|
+
* @returns Agent
|
|
489
|
+
*/
|
|
490
|
+
async launchAgent(input) {
|
|
491
|
+
return ((await this.deps.getAgent(input.sessionName).catch(() => null)) ?? {
|
|
492
|
+
sessionName: input.sessionName,
|
|
493
|
+
name: input.sessionName,
|
|
494
|
+
primary: input.configured,
|
|
495
|
+
memberId: input.memberId,
|
|
496
|
+
teamId: input.teamId,
|
|
497
|
+
isOrchestrator: input.isOrchestrator,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
397
500
|
/**
|
|
398
501
|
* The configured runtime of a launching agent is not installed / not signed
|
|
399
502
|
* in on this machine: record it like a signed-out account so the agent starts
|
|
@@ -510,8 +613,11 @@ export class RuntimeFallbackService {
|
|
|
510
613
|
}
|
|
511
614
|
else {
|
|
512
615
|
const confirmed = await this.confirm(runtime);
|
|
513
|
-
if (!confirmed)
|
|
616
|
+
if (!confirmed) {
|
|
617
|
+
// The probe answered normally: the session is not out of usage either.
|
|
618
|
+
clearUsageLimit(sessionName);
|
|
514
619
|
return;
|
|
620
|
+
}
|
|
515
621
|
if (!this.state.exhausted[runtime]) {
|
|
516
622
|
// The limit came straight back after a switch-back: back off the
|
|
517
623
|
// next probe, and do not tell the owner a second time.
|
|
@@ -590,6 +696,10 @@ export class RuntimeFallbackService {
|
|
|
590
696
|
}
|
|
591
697
|
finally {
|
|
592
698
|
this.switching.delete(sessionName);
|
|
699
|
+
// On another runtime now (or back on one that has usage again): the
|
|
700
|
+
// session's own usage-limit state no longer holds.
|
|
701
|
+
if (outcome === 'switched' || outcome === 'reverted')
|
|
702
|
+
clearUsageLimit(sessionName);
|
|
593
703
|
await this.afterSwitch(sessionName, outcome, opts.flushAfter);
|
|
594
704
|
}
|
|
595
705
|
}
|
|
@@ -653,18 +763,26 @@ export class RuntimeFallbackService {
|
|
|
653
763
|
* @param from - Runtime it leaves (out of usage)
|
|
654
764
|
* @param target - Runtime it goes to
|
|
655
765
|
* @param handover - Handover file, when written
|
|
766
|
+
* @param direction - `switch` (`from` ran out) or `upgrade` (`target` ranks higher in the chain)
|
|
656
767
|
*/
|
|
657
|
-
async recordSwitch(agent, from, target, handover = null) {
|
|
768
|
+
async recordSwitch(agent, from, target, handover = null, direction = 'switch') {
|
|
658
769
|
const sessionName = agent.sessionName;
|
|
659
770
|
const existing = this.state.overrides[sessionName];
|
|
660
771
|
const exhausted = this.state.exhausted[from];
|
|
661
|
-
|
|
662
|
-
//
|
|
663
|
-
|
|
772
|
+
const currentId = this.deps.conversation.get(sessionName);
|
|
773
|
+
// The primary's conversation is kept for the switch back. Between two
|
|
774
|
+
// Claude Code targets (the default login and another account) the
|
|
775
|
+
// conversation itself travels: its transcript is copied into the target
|
|
776
|
+
// account's config dir and resumed there (crewly#1344). Any other hop
|
|
777
|
+
// starts fresh with the handover.
|
|
778
|
+
const primarySessionId = existing?.primarySessionId ?? (from === agent.primary ? currentId : undefined);
|
|
779
|
+
const carried = currentId ? await this.carryConversation(sessionName, from, target, currentId) : false;
|
|
664
780
|
this.deps.conversation.clear(sessionName);
|
|
781
|
+
if (carried)
|
|
782
|
+
this.deps.conversation.set(sessionName, currentId);
|
|
665
783
|
if (target === agent.primary) {
|
|
666
784
|
delete this.state.overrides[sessionName];
|
|
667
|
-
if (primarySessionId)
|
|
785
|
+
if (!carried && primarySessionId)
|
|
668
786
|
this.deps.conversation.set(sessionName, primarySessionId);
|
|
669
787
|
}
|
|
670
788
|
else {
|
|
@@ -685,9 +803,37 @@ export class RuntimeFallbackService {
|
|
|
685
803
|
}
|
|
686
804
|
this.save();
|
|
687
805
|
const workItem = await this.deps.getActiveWorkItem(sessionName).catch(() => null);
|
|
688
|
-
this.kickoffNotes.set(sessionName,
|
|
806
|
+
this.kickoffNotes.set(sessionName, direction === 'upgrade'
|
|
807
|
+
? this.upgradeNote(agent.primary, from, target, handover, workItem, carried)
|
|
808
|
+
: this.switchNote(from, target, exhausted?.until, handover, workItem, carried));
|
|
809
|
+
if (carried)
|
|
810
|
+
this.logger.info('Conversation carried to the target Claude Code account', { sessionName, from, to: target, conversationId: currentId });
|
|
689
811
|
this.scheduleNotice(from);
|
|
690
812
|
}
|
|
813
|
+
/**
|
|
814
|
+
* Whether the conversation can continue on the target: both targets run
|
|
815
|
+
* Claude Code (different accounts or the default login) and the wiring
|
|
816
|
+
* copied its transcript there. Never throws.
|
|
817
|
+
*
|
|
818
|
+
* @param sessionName - Session
|
|
819
|
+
* @param from - Target it leaves
|
|
820
|
+
* @param to - Target it goes to
|
|
821
|
+
* @param conversationId - Its conversation on `from`
|
|
822
|
+
* @returns True when `--resume <conversationId>` works on `to`
|
|
823
|
+
*/
|
|
824
|
+
async carryConversation(sessionName, from, to, conversationId) {
|
|
825
|
+
if (!this.deps.carryConversation)
|
|
826
|
+
return false;
|
|
827
|
+
if (baseRuntimeOf(from) !== RUNTIME_TYPES.CLAUDE_CODE || baseRuntimeOf(to) !== RUNTIME_TYPES.CLAUDE_CODE)
|
|
828
|
+
return false;
|
|
829
|
+
try {
|
|
830
|
+
return await this.deps.carryConversation({ sessionName, from, to, conversationId });
|
|
831
|
+
}
|
|
832
|
+
catch (err) {
|
|
833
|
+
this.logger.warn('Could not carry the conversation to the target account; it starts fresh with the handover', { sessionName, from, to, error: err instanceof Error ? err.message : String(err) });
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
691
837
|
/**
|
|
692
838
|
* Wait until the agent is not mid-turn (bounded: a usage limit ends the turn anyway).
|
|
693
839
|
*
|
|
@@ -731,6 +877,33 @@ export class RuntimeFallbackService {
|
|
|
731
877
|
const own = agent.memberId ? this.state.settings.memberChains[agent.memberId] : undefined;
|
|
732
878
|
return own && own.length > 0 ? own : this.state.settings.chain;
|
|
733
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* Where an agent whose configured runtime is out should be instead of
|
|
882
|
+
* `current`: the earliest available entry of its chain (never its
|
|
883
|
+
* configured runtime, never one marked out of usage), when that ranks
|
|
884
|
+
* before `current` — or, with `orAnyWhenCurrentOut`, any available entry
|
|
885
|
+
* when `current` itself is marked out.
|
|
886
|
+
*
|
|
887
|
+
* @param agent - Agent (its configured runtime is out)
|
|
888
|
+
* @param current - Runtime target it is on
|
|
889
|
+
* @param orAnyWhenCurrentOut - Also move off a `current` that ran out to a lower-ranked entry
|
|
890
|
+
* @returns Better target, or null to stay
|
|
891
|
+
*/
|
|
892
|
+
async betterTarget(agent, current, orAnyWhenCurrentOut) {
|
|
893
|
+
const best = await this.pickFallback(agent, agent.primary);
|
|
894
|
+
if (!best || best === current)
|
|
895
|
+
return null;
|
|
896
|
+
const chain = this.chainFor(agent);
|
|
897
|
+
const rank = (r) => {
|
|
898
|
+
const i = chain.indexOf(r);
|
|
899
|
+
return i < 0 ? Number.POSITIVE_INFINITY : i;
|
|
900
|
+
};
|
|
901
|
+
if (rank(best) < rank(current))
|
|
902
|
+
return best;
|
|
903
|
+
if (orAnyWhenCurrentOut && this.state.exhausted[current])
|
|
904
|
+
return best;
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
734
907
|
/**
|
|
735
908
|
* Whether some runtime could take over (synchronous; uses the cached
|
|
736
909
|
* availability, optimistic when nothing is cached yet).
|
|
@@ -894,11 +1067,17 @@ export class RuntimeFallbackService {
|
|
|
894
1067
|
}
|
|
895
1068
|
await this.revertIdle();
|
|
896
1069
|
}
|
|
897
|
-
/**
|
|
1070
|
+
/**
|
|
1071
|
+
* Revert every pending override whose agent is idle (or not running), and
|
|
1072
|
+
* move an idle agent whose configured runtime is still out to a better
|
|
1073
|
+
* entry of its chain ({@link betterTarget}).
|
|
1074
|
+
*/
|
|
898
1075
|
async revertIdle() {
|
|
899
1076
|
for (const [sessionName, override] of Object.entries(this.state.overrides)) {
|
|
900
|
-
if (this.state.exhausted[override.primary])
|
|
1077
|
+
if (this.state.exhausted[override.primary]) {
|
|
1078
|
+
await this.upgradeIfBetter(sessionName, override);
|
|
901
1079
|
continue;
|
|
1080
|
+
}
|
|
902
1081
|
if (!override.revertPending) {
|
|
903
1082
|
// State from before a restart whose primary is no longer marked out of usage.
|
|
904
1083
|
override.revertPending = true;
|
|
@@ -907,7 +1086,7 @@ export class RuntimeFallbackService {
|
|
|
907
1086
|
if (this.switching.has(sessionName))
|
|
908
1087
|
continue;
|
|
909
1088
|
if (!this.deps.isLive(sessionName)) {
|
|
910
|
-
this.finishRevertOffline(sessionName, override);
|
|
1089
|
+
await this.finishRevertOffline(sessionName, override);
|
|
911
1090
|
continue;
|
|
912
1091
|
}
|
|
913
1092
|
if (await this.deps.isBusy(sessionName).catch(() => true))
|
|
@@ -915,20 +1094,100 @@ export class RuntimeFallbackService {
|
|
|
915
1094
|
await this.revertSession(sessionName);
|
|
916
1095
|
}
|
|
917
1096
|
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Move an idle, running agent to a better entry of its chain. A stopped
|
|
1099
|
+
* agent is left alone: its next start picks the best target.
|
|
1100
|
+
*
|
|
1101
|
+
* @param sessionName - Session
|
|
1102
|
+
* @param override - Its override (the configured runtime is out)
|
|
1103
|
+
*/
|
|
1104
|
+
async upgradeIfBetter(sessionName, override) {
|
|
1105
|
+
if (this.switching.has(sessionName) || this.isExempt(sessionName) || !this.deps.isLive(sessionName))
|
|
1106
|
+
return;
|
|
1107
|
+
// Cheap filter before reading the agent: some other chain entry must be open.
|
|
1108
|
+
const { chain, memberChains } = this.state.settings;
|
|
1109
|
+
const open = [...chain, ...Object.values(memberChains).flat()].some((r) => r !== override.runtime && r !== override.primary && !this.state.exhausted[r]);
|
|
1110
|
+
if (!open)
|
|
1111
|
+
return;
|
|
1112
|
+
const agent = await this.deps.getAgent(sessionName).catch(() => null);
|
|
1113
|
+
if (!agent || agent.primary !== override.primary)
|
|
1114
|
+
return;
|
|
1115
|
+
if (agent.isOrchestrator && !this.state.settings.orcFollows)
|
|
1116
|
+
return;
|
|
1117
|
+
const better = await this.betterTarget(agent, override.runtime, false);
|
|
1118
|
+
if (!better)
|
|
1119
|
+
return;
|
|
1120
|
+
if (await this.deps.isBusy(sessionName).catch(() => true))
|
|
1121
|
+
return;
|
|
1122
|
+
if (this.switching.has(sessionName))
|
|
1123
|
+
return;
|
|
1124
|
+
this.switching.add(sessionName);
|
|
1125
|
+
let outcome = 'skipped';
|
|
1126
|
+
try {
|
|
1127
|
+
outcome = await this.doUpgrade(agent, override.runtime, better);
|
|
1128
|
+
}
|
|
1129
|
+
catch (err) {
|
|
1130
|
+
this.logger.warn('Moving an agent to a better fallback runtime failed', { sessionName, error: err instanceof Error ? err.message : String(err) });
|
|
1131
|
+
outcome = 'failed';
|
|
1132
|
+
}
|
|
1133
|
+
finally {
|
|
1134
|
+
this.switching.delete(sessionName);
|
|
1135
|
+
await this.afterSwitch(sessionName, outcome, false);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Hand over and relaunch an idle agent on a better target.
|
|
1140
|
+
*
|
|
1141
|
+
* @param agent - Agent
|
|
1142
|
+
* @param from - Target it is on
|
|
1143
|
+
* @param target - Better target
|
|
1144
|
+
* @returns Outcome
|
|
1145
|
+
*/
|
|
1146
|
+
async doUpgrade(agent, from, target) {
|
|
1147
|
+
const sessionName = agent.sessionName;
|
|
1148
|
+
// Last look right before: anything that started since means "not now".
|
|
1149
|
+
if (await this.deps.isBusy(sessionName).catch(() => true))
|
|
1150
|
+
return 'skipped';
|
|
1151
|
+
const handover = await this.deps
|
|
1152
|
+
.writeHandover({
|
|
1153
|
+
sessionName,
|
|
1154
|
+
from,
|
|
1155
|
+
to: target,
|
|
1156
|
+
direction: 'upgrade',
|
|
1157
|
+
conversationId: this.deps.conversation.get(sessionName) ?? null,
|
|
1158
|
+
workItem: await this.deps.getActiveWorkItem(sessionName).catch(() => null),
|
|
1159
|
+
})
|
|
1160
|
+
.catch(() => null);
|
|
1161
|
+
await this.recordSwitch(agent, from, target, handover, 'upgrade');
|
|
1162
|
+
this.logger.info('Moving an idle agent to a better fallback runtime (its own runtime is still out)', { sessionName, from, to: target, primary: agent.primary });
|
|
1163
|
+
const ok = await this.deps.relaunch(agent).catch(() => false);
|
|
1164
|
+
if (!ok) {
|
|
1165
|
+
this.logger.warn('Relaunch on the better fallback runtime failed (the override stays; the next start uses it)', { sessionName, runtime: target });
|
|
1166
|
+
return 'failed';
|
|
1167
|
+
}
|
|
1168
|
+
return 'switched';
|
|
1169
|
+
}
|
|
918
1170
|
/**
|
|
919
1171
|
* Clear the override of an agent that is not running.
|
|
920
1172
|
*
|
|
921
1173
|
* @param sessionName - Session
|
|
922
1174
|
* @param override - Its override
|
|
923
1175
|
*/
|
|
924
|
-
finishRevertOffline(sessionName, override) {
|
|
1176
|
+
async finishRevertOffline(sessionName, override) {
|
|
925
1177
|
delete this.state.overrides[sessionName];
|
|
926
|
-
|
|
1178
|
+
const currentId = this.deps.conversation.get(sessionName);
|
|
1179
|
+
// The conversation that went on on the fallback account comes back with
|
|
1180
|
+
// the agent when both sides are Claude Code (crewly#1344); otherwise the
|
|
1181
|
+
// primary's own conversation from before the switch is resumed.
|
|
1182
|
+
const carried = currentId ? await this.carryConversation(sessionName, override.runtime, override.primary, currentId) : false;
|
|
1183
|
+
if (carried)
|
|
1184
|
+
this.deps.conversation.set(sessionName, currentId);
|
|
1185
|
+
else if (override.primarySessionId)
|
|
927
1186
|
this.deps.conversation.set(sessionName, override.primarySessionId);
|
|
928
1187
|
else
|
|
929
1188
|
this.deps.conversation.clear(sessionName);
|
|
930
1189
|
this.save();
|
|
931
|
-
this.logger.info('Fallback ended for a stopped agent (its next start uses its own runtime)', { sessionName, runtime: override.primary });
|
|
1190
|
+
this.logger.info('Fallback ended for a stopped agent (its next start uses its own runtime)', { sessionName, runtime: override.primary, carried });
|
|
932
1191
|
}
|
|
933
1192
|
/**
|
|
934
1193
|
* Move an idle agent back to its configured runtime.
|
|
@@ -973,12 +1232,18 @@ export class RuntimeFallbackService {
|
|
|
973
1232
|
})
|
|
974
1233
|
.catch(() => null);
|
|
975
1234
|
delete this.state.overrides[sessionName];
|
|
976
|
-
|
|
1235
|
+
const currentId = this.deps.conversation.get(sessionName);
|
|
1236
|
+
// Both sides Claude Code: the conversation that went on while on the
|
|
1237
|
+
// fallback account comes back with the agent (crewly#1344).
|
|
1238
|
+
const carried = currentId ? await this.carryConversation(sessionName, override.runtime, override.primary, currentId) : false;
|
|
1239
|
+
if (carried)
|
|
1240
|
+
this.deps.conversation.set(sessionName, currentId);
|
|
1241
|
+
else if (override.primarySessionId)
|
|
977
1242
|
this.deps.conversation.set(sessionName, override.primarySessionId);
|
|
978
1243
|
else
|
|
979
1244
|
this.deps.conversation.clear(sessionName);
|
|
980
1245
|
this.save();
|
|
981
|
-
this.kickoffNotes.set(sessionName, this.revertNote(override, handover, workItem));
|
|
1246
|
+
this.kickoffNotes.set(sessionName, this.revertNote(override, handover, workItem, carried));
|
|
982
1247
|
this.logger.info('Switching agent back to its own runtime at an idle boundary', { sessionName, from: override.runtime, to: override.primary });
|
|
983
1248
|
const ok = await this.deps.relaunch(agent).catch(() => false);
|
|
984
1249
|
if (!ok) {
|
|
@@ -1137,7 +1402,15 @@ export class RuntimeFallbackService {
|
|
|
1137
1402
|
...(tz ? { timeZone: tz } : {}),
|
|
1138
1403
|
}).format(new Date(epochMs));
|
|
1139
1404
|
}
|
|
1140
|
-
|
|
1405
|
+
/** The second sentence of a kickoff note: whether the conversation came along. */
|
|
1406
|
+
continuity(handover, carried) {
|
|
1407
|
+
if (carried)
|
|
1408
|
+
return 'Your conversation came with you — carry on where you were; nothing was lost.';
|
|
1409
|
+
return handover
|
|
1410
|
+
? `This is a fresh conversation: after registering, read ${handover} once — it holds the end of your previous conversation.`
|
|
1411
|
+
: 'This is a fresh conversation: your tasks, teams and wiki are all still in Crewly.';
|
|
1412
|
+
}
|
|
1413
|
+
switchNote(from, to, until, handover, workItem, carried = false) {
|
|
1141
1414
|
const reset = until ? ` (it resets ~${this.formatTime(Date.parse(until))})` : '';
|
|
1142
1415
|
const kind = this.state.exhausted[from]?.kind;
|
|
1143
1416
|
const parts = [
|
|
@@ -1148,20 +1421,29 @@ export class RuntimeFallbackService {
|
|
|
1148
1421
|
: kind === 'login'
|
|
1149
1422
|
? `Crewly moved you from ${this.label(from)} to ${this.label(to)} because the ${this.label(from)} login expired.`
|
|
1150
1423
|
: `Crewly moved you from ${this.label(from)} to ${this.label(to)} because ${this.label(from)} hit its usage limit${reset}; you will be moved back when it resets.`,
|
|
1151
|
-
handover
|
|
1152
|
-
|
|
1153
|
-
|
|
1424
|
+
this.continuity(handover, carried),
|
|
1425
|
+
];
|
|
1426
|
+
if (workItem)
|
|
1427
|
+
parts.push(`Then continue WorkItem ${workItem.id} ("${workItem.title}") where you left off.`);
|
|
1428
|
+
return parts.join(' ');
|
|
1429
|
+
}
|
|
1430
|
+
upgradeNote(primary, from, to, handover, workItem, carried = false) {
|
|
1431
|
+
const parts = [
|
|
1432
|
+
`${this.label(to)} has usage again, so Crewly moved you there from ${this.label(from)}; ${this.label(primary)} is still unavailable and you will be moved back to it once it is.`,
|
|
1433
|
+
this.continuity(handover, carried),
|
|
1154
1434
|
];
|
|
1155
1435
|
if (workItem)
|
|
1156
1436
|
parts.push(`Then continue WorkItem ${workItem.id} ("${workItem.title}") where you left off.`);
|
|
1157
1437
|
return parts.join(' ');
|
|
1158
1438
|
}
|
|
1159
|
-
revertNote(override, handover, workItem) {
|
|
1439
|
+
revertNote(override, handover, workItem, carried = false) {
|
|
1160
1440
|
const parts = [
|
|
1161
1441
|
`${this.label(override.primary)} is available again, so Crewly moved you back from ${this.label(override.runtime)}.`,
|
|
1162
|
-
|
|
1163
|
-
?
|
|
1164
|
-
:
|
|
1442
|
+
carried
|
|
1443
|
+
? 'Your conversation came back with you — carry on where you were.'
|
|
1444
|
+
: handover
|
|
1445
|
+
? `Work went on while you were away: read ${handover} once for what happened since.`
|
|
1446
|
+
: 'Work went on while you were away: check your WorkItems and wiki for what happened since.',
|
|
1165
1447
|
];
|
|
1166
1448
|
if (workItem)
|
|
1167
1449
|
parts.push(`Then continue WorkItem ${workItem.id} ("${workItem.title}").`);
|