crewly 1.20.295 → 1.20.296

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 (83) hide show
  1. package/config/skills/_common/lib.sh +6 -0
  2. package/config/skills/agent/core/complete-task/SKILL.md +4 -2
  3. package/config/skills/agent/core/complete-task/execute.sh +7 -0
  4. package/config/skills/agent/core/complete-task/explicit-id.test.sh +56 -0
  5. package/config/skills/agent/core/poll-tasks/execute.sh +13 -1
  6. package/config/skills/agent/core/poll-tasks/execute.test.sh +37 -0
  7. package/config/skills/team-leader/delegate-task/execute.sh +13 -2
  8. package/config/skills/team-leader/verify-output/SKILL.md +9 -0
  9. package/dist/backend/backend/src/constants.d.ts +12 -0
  10. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  11. package/dist/backend/backend/src/constants.js +12 -0
  12. package/dist/backend/backend/src/constants.js.map +1 -1
  13. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  14. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +28 -8
  15. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  16. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  17. package/dist/backend/backend/src/controllers/slack/slack.controller.js +28 -1
  18. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  19. package/dist/backend/backend/src/index.d.ts.map +1 -1
  20. package/dist/backend/backend/src/index.js +30 -5
  21. package/dist/backend/backend/src/index.js.map +1 -1
  22. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +18 -4
  23. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  24. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +36 -8
  25. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  26. package/dist/backend/backend/src/services/orc/reply-destination-resolver.d.ts +6 -0
  27. package/dist/backend/backend/src/services/orc/reply-destination-resolver.d.ts.map +1 -1
  28. package/dist/backend/backend/src/services/orc/reply-destination-resolver.js +18 -0
  29. package/dist/backend/backend/src/services/orc/reply-destination-resolver.js.map +1 -1
  30. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts +2 -0
  31. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
  32. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +81 -8
  33. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
  34. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +8 -0
  35. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
  36. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +22 -0
  37. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
  38. package/dist/backend/backend/src/services/session/session-command-helper.d.ts +17 -0
  39. package/dist/backend/backend/src/services/session/session-command-helper.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/session/session-command-helper.js +32 -0
  41. package/dist/backend/backend/src/services/session/session-command-helper.js.map +1 -1
  42. package/dist/backend/backend/src/services/slack/orc-owner-dm-target.d.ts +27 -0
  43. package/dist/backend/backend/src/services/slack/orc-owner-dm-target.d.ts.map +1 -0
  44. package/dist/backend/backend/src/services/slack/orc-owner-dm-target.js +48 -0
  45. package/dist/backend/backend/src/services/slack/orc-owner-dm-target.js.map +1 -0
  46. package/dist/backend/backend/src/services/task-pool/pool-archive-migration.d.ts +18 -0
  47. package/dist/backend/backend/src/services/task-pool/pool-archive-migration.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/task-pool/pool-archive-migration.js +9 -3
  49. package/dist/backend/backend/src/services/task-pool/pool-archive-migration.js.map +1 -1
  50. package/dist/backend/backend/src/services/task-pool/pool-prune.d.ts +76 -0
  51. package/dist/backend/backend/src/services/task-pool/pool-prune.d.ts.map +1 -0
  52. package/dist/backend/backend/src/services/task-pool/pool-prune.js +129 -0
  53. package/dist/backend/backend/src/services/task-pool/pool-prune.js.map +1 -0
  54. package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts +9 -1
  55. package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
  56. package/dist/backend/backend/src/services/task-pool/pool-storage.js +34 -3
  57. package/dist/backend/backend/src/services/task-pool/pool-storage.js.map +1 -1
  58. package/dist/backend/backend/src/utils/screen-excerpt.d.ts +34 -0
  59. package/dist/backend/backend/src/utils/screen-excerpt.d.ts.map +1 -0
  60. package/dist/backend/backend/src/utils/screen-excerpt.js +56 -0
  61. package/dist/backend/backend/src/utils/screen-excerpt.js.map +1 -0
  62. package/dist/backend/build-info.json +2 -2
  63. package/dist/cli/backend/src/constants.d.ts +12 -0
  64. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  65. package/dist/cli/backend/src/constants.js +12 -0
  66. package/dist/cli/backend/src/constants.js.map +1 -1
  67. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +18 -4
  68. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  69. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +36 -8
  70. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  71. package/dist/cli/backend/src/services/session/session-command-helper.d.ts +17 -0
  72. package/dist/cli/backend/src/services/session/session-command-helper.d.ts.map +1 -1
  73. package/dist/cli/backend/src/services/session/session-command-helper.js +32 -0
  74. package/dist/cli/backend/src/services/session/session-command-helper.js.map +1 -1
  75. package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts +9 -1
  76. package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
  77. package/dist/cli/backend/src/services/task-pool/pool-storage.js +34 -3
  78. package/dist/cli/backend/src/services/task-pool/pool-storage.js.map +1 -1
  79. package/dist/cli/backend/src/utils/screen-excerpt.d.ts +34 -0
  80. package/dist/cli/backend/src/utils/screen-excerpt.d.ts.map +1 -0
  81. package/dist/cli/backend/src/utils/screen-excerpt.js +56 -0
  82. package/dist/cli/backend/src/utils/screen-excerpt.js.map +1 -0
  83. package/package.json +1 -1
@@ -77,7 +77,7 @@ import { parseSlackThreadKey } from './services/slack/slack-thread-key.js';
77
77
  import { LIVENESS_MONITOR_CONSTANTS, INPUT_CIRCUIT_CONSTANTS, INPUT_BLOCKED_RETRY_CONSTANTS } from './constants.js';
78
78
  import { InputBlockedRetryService } from './services/messaging/input-blocked-retry.service.js';
79
79
  import { driveCapabilities } from './services/drive/drive-agent.service.js';
80
- import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, AUTO_UPDATE_CONSTANTS, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS, TICKET_CONSTANTS, UNASSIGNED_ROUTE_CONSTANTS, CLOUD_TALK_CONSTANTS, STANDING_ANSWERS_CONSTANTS, TICKET_AUTOPILOT_CONSTANTS, TICKET_HYGIENE_CONSTANTS, EXPERIMENT_CONSTANTS, WORK_ITEM_DESTINATION_CONSTANTS, CODEX_USAGE_SYNC_CONSTANTS, ANTIGRAVITY_USAGE_SYNC_CONSTANTS, OWNER_AUTH_CONSTANTS, CREWLY_APPS_CONSTANTS, SLACK_AGENT_DM_CONSTANTS, BRIEFING_CONSTANTS, DRIVE_CONSTANTS } from './constants.js';
80
+ import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, AUTO_UPDATE_CONSTANTS, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS, TICKET_CONSTANTS, UNASSIGNED_ROUTE_CONSTANTS, CLOUD_TALK_CONSTANTS, STANDING_ANSWERS_CONSTANTS, TICKET_AUTOPILOT_CONSTANTS, TICKET_HYGIENE_CONSTANTS, EXPERIMENT_CONSTANTS, WORK_ITEM_DESTINATION_CONSTANTS, CODEX_USAGE_SYNC_CONSTANTS, ANTIGRAVITY_USAGE_SYNC_CONSTANTS, OWNER_AUTH_CONSTANTS, CREWLY_APPS_CONSTANTS, SLACK_AGENT_DM_CONSTANTS, BRIEFING_CONSTANTS, DRIVE_CONSTANTS, POOL_PRUNE_CONSTANTS } from './constants.js';
81
81
  import { randomUUID } from 'crypto';
82
82
  import { PtyActivityTrackerService } from './services/agent/pty-activity-tracker.service.js';
83
83
  import { InFlightTurnTracker } from './services/restart/in-flight-turn-tracker.service.js';
@@ -88,6 +88,7 @@ import { initialDecider, nextDecider } from './services/task-pool/untargeted-rou
88
88
  import { activeAcceptance, formatTicketMarker, formatTicketNumber } from './types/v2/ticket.types.js';
89
89
  import { createWorkItem, TERMINAL_WORK_ITEM_STATUSES } from './types/v2/work-item.types.js';
90
90
  import { runPoolArchiveMigration } from './services/task-pool/pool-archive-migration.js';
91
+ import { runPoolPrune } from './services/task-pool/pool-prune.js';
91
92
  import { createPtyTurnProbe } from './services/restart/turn-probe.js';
92
93
  import { RestartDrainService, resolveRestartDrainMs, resolveBackgroundDrainMs, } from './services/restart/restart-drain.service.js';
93
94
  import { interruptedTurnsPath, loadInterruptedTurns, saveInterruptedTurns, writeInterruptedTurns, resumeInterruptedTurns, planCommitmentNotes, } from './services/restart/interrupted-turns.js';
@@ -185,6 +186,7 @@ import { TaskHistorySubscriber } from './services/memory/task-history.subscriber
185
186
  import { TeamHealthWatchdogService, LiveTeamHealthDataProvider, loadTeamHealthConfig, setTeamHealthWatchdogSingleton, getTeamHealthWatchdogSingleton, } from './services/team-health/index.js';
186
187
  import { traceHarness, traceTurnActivity } from './services/trace/trace-recorder.js';
187
188
  import { inputCircuitStats, setInputCircuitOpenListener } from './services/session/input-circuit-breaker.js';
189
+ import { looksLikeShellPrompt } from './utils/screen-excerpt.js';
188
190
  import { harnessPastesSinceOutsideInput, shownMarkers } from './services/session/input-ledger.js';
189
191
  // ESM __dirname equivalent using import.meta.url
190
192
  const __filename = fileURLToPath(import.meta.url);
@@ -764,13 +766,25 @@ export class CrewlyServer {
764
766
  // Ticket loop §4: one-time archive of old WorkItems (marker file makes
765
767
  // it run once). Through the pool's own storage cache, so no later
766
768
  // flush can write the archived items back. Never deletes.
769
+ const poolPruneLogger = LoggerService.getInstance().createComponentLogger('PoolPrune');
770
+ const pruneOnce = () => runPoolPrune(TaskPoolService.getInstance().getStorage(), { logger: poolPruneLogger }).catch((pruneErr) => {
771
+ this.logger.warn('Task pool prune failed (pool left as is; retried next interval)', {
772
+ error: pruneErr instanceof Error ? pruneErr.message : String(pruneErr),
773
+ });
774
+ });
767
775
  void runPoolArchiveMigration(TaskPoolService.getInstance().getStorage(), {
768
776
  logger: LoggerService.getInstance().createComponentLogger('PoolArchive'),
769
- }).catch((archiveErr) => {
777
+ })
778
+ .catch((archiveErr) => {
770
779
  this.logger.warn('Task pool one-time archive failed (pool left as is; retried next boot)', {
771
780
  error: archiveErr instanceof Error ? archiveErr.message : String(archiveErr),
772
781
  });
773
- });
782
+ })
783
+ // Then keep it small: finished items and ended claims move to the
784
+ // archive, once now and every few hours (crewly#1108).
785
+ .then(pruneOnce);
786
+ const poolPruneTimer = setInterval(() => void pruneOnce(), POOL_PRUNE_CONSTANTS.INTERVAL_MS);
787
+ poolPruneTimer.unref?.();
774
788
  // Atlas 2026-05-23 fix: wire the agent-liveness gate so claimFromPool /
775
789
  // claimSpecificItem refuse to put a WI into `running` when the requesting
776
790
  // agent's session is dead. delegate-task's "self-heal fix #1" used to
@@ -6383,6 +6397,17 @@ export class CrewlyServer {
6383
6397
  };
6384
6398
  // Every delivery refused for a while: automatic redelivery is slowed
6385
6399
  // to a probe now and then, and the owner told once (crewly#1028).
6400
+ // What the unreadable screen shows (redacted rows), so the owner can
6401
+ // tell a dialog from a bare shell without opening the terminal.
6402
+ const screenNote = (sessionName, state) => {
6403
+ if (state !== 'unknown')
6404
+ return '';
6405
+ const excerpt = SessionCommandHelper.unreadableExcerpt(sessionName);
6406
+ if (!excerpt)
6407
+ return '';
6408
+ const hint = looksLikeShellPrompt(excerpt) ? ' It looks like the runtime exited to a shell prompt.' : '';
6409
+ return `${hint}\nScreen (secrets masked):\n${excerpt.split('\n').map((l) => `> ${l}`).join('\n')}`;
6410
+ };
6386
6411
  setInputCircuitOpenListener((info) => {
6387
6412
  traceHarness('guard.block', {
6388
6413
  session: info.sessionName,
@@ -6435,7 +6460,7 @@ export class CrewlyServer {
6435
6460
  ? 'its input box cannot be read (a dialog or an unfamiliar screen)'
6436
6461
  : `its input box holds ${notice.inputLength} characters that Crewly did not write`;
6437
6462
  const maxMin = Math.round(INPUT_CIRCUIT_CONSTANTS.PROBE_MAX_MS / 60000);
6438
- tell(notice.sessionName, `Needs you: ${notice.sessionName} has not received any message for ${minutes} min: ${what}, so Crewly refused to type over it (${notice.refusals} attempts). Crewly has stopped retrying every few seconds and now tries again only every few minutes (at most every ${maxMin} min). To fix it, open ${notice.sessionName}'s terminal and clear the input box (Ctrl+U), or press Enter if that text is yours. Delivery resumes on its own after that.`, notice.message || undefined);
6463
+ tell(notice.sessionName, `Needs you: ${notice.sessionName} has not received any message for ${minutes} min: ${what}, so Crewly refused to type over it (${notice.refusals} attempts). Crewly has stopped retrying every few seconds and now tries again only every few minutes (at most every ${maxMin} min). To fix it, open ${notice.sessionName}'s terminal and clear the input box (Ctrl+U), or press Enter if that text is yours. Delivery resumes on its own after that.${screenNote(notice.sessionName, notice.blockedState)}`, notice.message || undefined);
6439
6464
  return;
6440
6465
  }
6441
6466
  if (notice.state === 'busy') {
@@ -6445,7 +6470,7 @@ export class CrewlyServer {
6445
6470
  const what = notice.state === 'unknown'
6446
6471
  ? 'its input box cannot be read (a dialog or an unfamiliar screen)'
6447
6472
  : `its input box holds ${notice.inputLength} characters of text not written by Crewly`;
6448
- tell(notice.sessionName, `Needs you: messages to ${notice.sessionName} are waiting because ${what}. Crewly will not type over it. Tried ${notice.refusals} times over ${minutes} min; it keeps retrying. Clear the agent's input (or answer its screen) to let them through.`, notice.message);
6473
+ tell(notice.sessionName, `Needs you: messages to ${notice.sessionName} are waiting because ${what}. Crewly will not type over it. Tried ${notice.refusals} times over ${minutes} min; it keeps retrying. Clear the agent's input (or answer its screen) to let them through.${screenNote(notice.sessionName, notice.state)}`, notice.message);
6449
6474
  },
6450
6475
  });
6451
6476
  // A WorkItem brief held by the restart drain gets its hand-over