@penclipai/server 2026.704.0 → 2026.714.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/process/execute.d.ts.map +1 -1
- package/dist/adapters/process/execute.js +1 -0
- package/dist/adapters/process/execute.js.map +1 -1
- package/dist/adapters/registry.d.ts.map +1 -1
- package/dist/adapters/registry.js +79 -51
- package/dist/adapters/registry.js.map +1 -1
- package/dist/adapters/utils.d.ts +5 -0
- package/dist/adapters/utils.d.ts.map +1 -1
- package/dist/adapters/utils.js.map +1 -1
- package/dist/agent-auth-jwt.d.ts +5 -1
- package/dist/agent-auth-jwt.d.ts.map +1 -1
- package/dist/agent-auth-jwt.js +72 -20
- package/dist/agent-auth-jwt.js.map +1 -1
- package/dist/app.d.ts +2 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +10 -0
- package/dist/app.js.map +1 -1
- package/dist/built-ins/agents/reflection-coach/AGENTS.md +47 -0
- package/dist/built-ins/agents/reflection-coach/routines/recent-agent-reflection.md +77 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +208 -116
- package/dist/index.js.map +1 -1
- package/dist/middleware/api-compression.d.ts +8 -0
- package/dist/middleware/api-compression.d.ts.map +1 -0
- package/dist/middleware/api-compression.js +207 -0
- package/dist/middleware/api-compression.js.map +1 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +130 -3
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/error-handler.d.ts.map +1 -1
- package/dist/middleware/error-handler.js +27 -0
- package/dist/middleware/error-handler.js.map +1 -1
- package/dist/onboarding-assets/default/AGENTS.md +1 -0
- package/dist/redaction.d.ts.map +1 -1
- package/dist/redaction.js +11 -0
- package/dist/redaction.js.map +1 -1
- package/dist/routes/access.d.ts.map +1 -1
- package/dist/routes/access.js +4 -3
- package/dist/routes/access.js.map +1 -1
- package/dist/routes/adapters.d.ts.map +1 -1
- package/dist/routes/adapters.js +2 -0
- package/dist/routes/adapters.js.map +1 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +222 -87
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/attention.d.ts +3 -0
- package/dist/routes/attention.d.ts.map +1 -0
- package/dist/routes/attention.js +24 -0
- package/dist/routes/attention.js.map +1 -0
- package/dist/routes/authz.d.ts.map +1 -1
- package/dist/routes/authz.js +29 -1
- package/dist/routes/authz.js.map +1 -1
- package/dist/routes/board-chat.d.ts.map +1 -1
- package/dist/routes/board-chat.js +4 -1
- package/dist/routes/board-chat.js.map +1 -1
- package/dist/routes/built-in-agents.d.ts +3 -0
- package/dist/routes/built-in-agents.d.ts.map +1 -0
- package/dist/routes/built-in-agents.js +267 -0
- package/dist/routes/built-in-agents.js.map +1 -0
- package/dist/routes/cases.d.ts +46 -0
- package/dist/routes/cases.d.ts.map +1 -0
- package/dist/routes/cases.js +1395 -0
- package/dist/routes/cases.js.map +1 -0
- package/dist/routes/companies.d.ts.map +1 -1
- package/dist/routes/companies.js +4 -1
- package/dist/routes/companies.js.map +1 -1
- package/dist/routes/company-skills.d.ts.map +1 -1
- package/dist/routes/company-skills.js +453 -33
- package/dist/routes/company-skills.js.map +1 -1
- package/dist/routes/environments.d.ts.map +1 -1
- package/dist/routes/environments.js +71 -8
- package/dist/routes/environments.js.map +1 -1
- package/dist/routes/execution-workspaces.d.ts.map +1 -1
- package/dist/routes/execution-workspaces.js +89 -3
- package/dist/routes/execution-workspaces.js.map +1 -1
- package/dist/routes/health.d.ts +2 -0
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +30 -0
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/inbox-dismissals.d.ts.map +1 -1
- package/dist/routes/inbox-dismissals.js +80 -19
- package/dist/routes/inbox-dismissals.js.map +1 -1
- package/dist/routes/index.d.ts +2 -0
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +2 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/issues.d.ts +25 -0
- package/dist/routes/issues.d.ts.map +1 -1
- package/dist/routes/issues.js +1455 -46
- package/dist/routes/issues.js.map +1 -1
- package/dist/routes/openapi.d.ts.map +1 -1
- package/dist/routes/openapi.js +448 -11
- package/dist/routes/openapi.js.map +1 -1
- package/dist/routes/pipelines.js +2 -2
- package/dist/routes/pipelines.js.map +1 -1
- package/dist/routes/resource-memberships.d.ts.map +1 -1
- package/dist/routes/resource-memberships.js +13 -5
- package/dist/routes/resource-memberships.js.map +1 -1
- package/dist/routes/secrets.d.ts.map +1 -1
- package/dist/routes/secrets.js +261 -1
- package/dist/routes/secrets.js.map +1 -1
- package/dist/routes/sidebar-badges.d.ts.map +1 -1
- package/dist/routes/sidebar-badges.js +18 -2
- package/dist/routes/sidebar-badges.js.map +1 -1
- package/dist/routes/user-profiles.d.ts.map +1 -1
- package/dist/routes/user-profiles.js +5 -4
- package/dist/routes/user-profiles.js.map +1 -1
- package/dist/server-info.d.ts +2 -0
- package/dist/server-info.d.ts.map +1 -1
- package/dist/server-info.js +20 -5
- package/dist/server-info.js.map +1 -1
- package/dist/services/access.d.ts +4 -4
- package/dist/services/access.d.ts.map +1 -1
- package/dist/services/activity.d.ts +3 -3
- package/dist/services/activity.d.ts.map +1 -1
- package/dist/services/activity.js +5 -4
- package/dist/services/activity.js.map +1 -1
- package/dist/services/adapter-registry-bootstrap.reconcile.test.js +1 -0
- package/dist/services/adapter-registry-bootstrap.reconcile.test.js.map +1 -1
- package/dist/services/agent-secret-bindings.d.ts +15 -0
- package/dist/services/agent-secret-bindings.d.ts.map +1 -1
- package/dist/services/agent-secret-bindings.js +43 -0
- package/dist/services/agent-secret-bindings.js.map +1 -1
- package/dist/services/agents.d.ts +194 -133
- package/dist/services/agents.d.ts.map +1 -1
- package/dist/services/agents.js +107 -4
- package/dist/services/agents.js.map +1 -1
- package/dist/services/approvals.d.ts +10 -10
- package/dist/services/approvals.d.ts.map +1 -1
- package/dist/services/approvals.js +9 -1
- package/dist/services/approvals.js.map +1 -1
- package/dist/services/assets.d.ts +5 -5
- package/dist/services/attention.d.ts +11 -0
- package/dist/services/attention.d.ts.map +1 -0
- package/dist/services/attention.js +1024 -0
- package/dist/services/attention.js.map +1 -0
- package/dist/services/authorization.d.ts +15 -2
- package/dist/services/authorization.d.ts.map +1 -1
- package/dist/services/authorization.js +324 -8
- package/dist/services/authorization.js.map +1 -1
- package/dist/services/board-auth.d.ts +2 -2
- package/dist/services/budgets.d.ts.map +1 -1
- package/dist/services/budgets.js +8 -7
- package/dist/services/budgets.js.map +1 -1
- package/dist/services/built-in-agent-metadata.d.ts +9 -0
- package/dist/services/built-in-agent-metadata.d.ts.map +1 -0
- package/dist/services/built-in-agent-metadata.js +39 -0
- package/dist/services/built-in-agent-metadata.js.map +1 -0
- package/dist/services/built-in-agents.d.ts +394 -0
- package/dist/services/built-in-agents.d.ts.map +1 -0
- package/dist/services/built-in-agents.js +1426 -0
- package/dist/services/built-in-agents.js.map +1 -0
- package/dist/services/change-consent-gate.d.ts +18 -0
- package/dist/services/change-consent-gate.d.ts.map +1 -0
- package/dist/services/change-consent-gate.js +170 -0
- package/dist/services/change-consent-gate.js.map +1 -0
- package/dist/services/companies.d.ts +14 -8
- package/dist/services/companies.d.ts.map +1 -1
- package/dist/services/companies.js +6 -1
- package/dist/services/companies.js.map +1 -1
- package/dist/services/company-artifacts.d.ts +4 -1
- package/dist/services/company-artifacts.d.ts.map +1 -1
- package/dist/services/company-artifacts.js +9 -1
- package/dist/services/company-artifacts.js.map +1 -1
- package/dist/services/company-member-roles.d.ts.map +1 -1
- package/dist/services/company-member-roles.js +2 -0
- package/dist/services/company-member-roles.js.map +1 -1
- package/dist/services/company-portability.d.ts +1 -1
- package/dist/services/company-portability.d.ts.map +1 -1
- package/dist/services/company-portability.js +113 -8
- package/dist/services/company-portability.js.map +1 -1
- package/dist/services/company-search.d.ts.map +1 -1
- package/dist/services/company-search.js +843 -294
- package/dist/services/company-search.js.map +1 -1
- package/dist/services/company-skills.d.ts +64 -3
- package/dist/services/company-skills.d.ts.map +1 -1
- package/dist/services/company-skills.js +1205 -20
- package/dist/services/company-skills.js.map +1 -1
- package/dist/services/costs.d.ts +9 -8
- package/dist/services/costs.d.ts.map +1 -1
- package/dist/services/costs.js +9 -2
- package/dist/services/costs.js.map +1 -1
- package/dist/services/dashboard.d.ts +2 -0
- package/dist/services/dashboard.d.ts.map +1 -1
- package/dist/services/dashboard.js +60 -17
- package/dist/services/dashboard.js.map +1 -1
- package/dist/services/database-backup-health.d.ts +34 -0
- package/dist/services/database-backup-health.d.ts.map +1 -0
- package/dist/services/database-backup-health.js +104 -0
- package/dist/services/database-backup-health.js.map +1 -0
- package/dist/services/document-annotations.d.ts +169 -1
- package/dist/services/document-annotations.d.ts.map +1 -1
- package/dist/services/document-annotations.js +272 -1
- package/dist/services/document-annotations.js.map +1 -1
- package/dist/services/documents.d.ts +368 -0
- package/dist/services/documents.d.ts.map +1 -1
- package/dist/services/documents.js +2 -2
- package/dist/services/documents.js.map +1 -1
- package/dist/services/environment-config.d.ts.map +1 -1
- package/dist/services/environment-config.js +6 -0
- package/dist/services/environment-config.js.map +1 -1
- package/dist/services/environment-custom-image-runtime.d.ts +28 -0
- package/dist/services/environment-custom-image-runtime.d.ts.map +1 -1
- package/dist/services/environment-custom-image-runtime.js +106 -7
- package/dist/services/environment-custom-image-runtime.js.map +1 -1
- package/dist/services/environment-custom-images.d.ts +31 -1
- package/dist/services/environment-custom-images.d.ts.map +1 -1
- package/dist/services/environment-custom-images.js +110 -4
- package/dist/services/environment-custom-images.js.map +1 -1
- package/dist/services/environment-execution-target.d.ts.map +1 -1
- package/dist/services/environment-execution-target.js +1 -3
- package/dist/services/environment-execution-target.js.map +1 -1
- package/dist/services/environment-probe.d.ts +1 -0
- package/dist/services/environment-probe.d.ts.map +1 -1
- package/dist/services/environment-probe.js +99 -5
- package/dist/services/environment-probe.js.map +1 -1
- package/dist/services/environments.d.ts +3 -1
- package/dist/services/environments.d.ts.map +1 -1
- package/dist/services/environments.js +98 -3
- package/dist/services/environments.js.map +1 -1
- package/dist/services/execution-workspace-policy.d.ts +29 -3
- package/dist/services/execution-workspace-policy.d.ts.map +1 -1
- package/dist/services/execution-workspace-policy.js +44 -1
- package/dist/services/execution-workspace-policy.js.map +1 -1
- package/dist/services/execution-workspaces.d.ts +64 -1
- package/dist/services/execution-workspaces.d.ts.map +1 -1
- package/dist/services/execution-workspaces.js +634 -3
- package/dist/services/execution-workspaces.js.map +1 -1
- package/dist/services/external-objects.d.ts +26 -26
- package/dist/services/feedback.d.ts +2 -2
- package/dist/services/finance.d.ts +5 -5
- package/dist/services/goals.d.ts +8 -8
- package/dist/services/heartbeat-stop-metadata.d.ts +2 -2
- package/dist/services/heartbeat-stop-metadata.d.ts.map +1 -1
- package/dist/services/heartbeat-stop-metadata.js +4 -0
- package/dist/services/heartbeat-stop-metadata.js.map +1 -1
- package/dist/services/heartbeat-stop-metadata.test.js +9 -0
- package/dist/services/heartbeat-stop-metadata.test.js.map +1 -1
- package/dist/services/heartbeat.d.ts +133 -28
- package/dist/services/heartbeat.d.ts.map +1 -1
- package/dist/services/heartbeat.js +1963 -239
- package/dist/services/heartbeat.js.map +1 -1
- package/dist/services/inbox-dismissals.d.ts +26 -0
- package/dist/services/inbox-dismissals.d.ts.map +1 -1
- package/dist/services/inbox-dismissals.js +33 -18
- package/dist/services/inbox-dismissals.js.map +1 -1
- package/dist/services/index.d.ts +3 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/instance-settings.d.ts +25 -1
- package/dist/services/instance-settings.d.ts.map +1 -1
- package/dist/services/instance-settings.js +103 -5
- package/dist/services/instance-settings.js.map +1 -1
- package/dist/services/issue-continuation-summary.js +1 -1
- package/dist/services/issue-continuation-summary.js.map +1 -1
- package/dist/services/issue-recovery-actions.d.ts +3 -0
- package/dist/services/issue-recovery-actions.d.ts.map +1 -1
- package/dist/services/issue-recovery-actions.js +9 -0
- package/dist/services/issue-recovery-actions.js.map +1 -1
- package/dist/services/issue-rewake-throttle.d.ts +92 -0
- package/dist/services/issue-rewake-throttle.d.ts.map +1 -0
- package/dist/services/issue-rewake-throttle.js +139 -0
- package/dist/services/issue-rewake-throttle.js.map +1 -0
- package/dist/services/issue-thread-interactions.d.ts +8 -1
- package/dist/services/issue-thread-interactions.d.ts.map +1 -1
- package/dist/services/issue-thread-interactions.js +231 -16
- package/dist/services/issue-thread-interactions.js.map +1 -1
- package/dist/services/issue-visibility.d.ts +4 -0
- package/dist/services/issue-visibility.d.ts.map +1 -0
- package/dist/services/issue-visibility.js +9 -0
- package/dist/services/issue-visibility.js.map +1 -0
- package/dist/services/issues.d.ts +225 -105
- package/dist/services/issues.d.ts.map +1 -1
- package/dist/services/issues.js +540 -18
- package/dist/services/issues.js.map +1 -1
- package/dist/services/local-service-supervisor.d.ts +3 -0
- package/dist/services/local-service-supervisor.d.ts.map +1 -1
- package/dist/services/local-service-supervisor.js +51 -0
- package/dist/services/local-service-supervisor.js.map +1 -1
- package/dist/services/pipeline-case-outputs.d.ts.map +1 -1
- package/dist/services/pipeline-case-outputs.js +2 -1
- package/dist/services/pipeline-case-outputs.js.map +1 -1
- package/dist/services/pipelines-aggregation.d.ts.map +1 -1
- package/dist/services/pipelines-aggregation.js +3 -2
- package/dist/services/pipelines-aggregation.js.map +1 -1
- package/dist/services/pipelines.d.ts +165 -165
- package/dist/services/pipelines.d.ts.map +1 -1
- package/dist/services/pipelines.js +6 -4
- package/dist/services/pipelines.js.map +1 -1
- package/dist/services/plugin-database.d.ts +2 -2
- package/dist/services/plugin-environment-driver.d.ts +1 -1
- package/dist/services/plugin-host-services.d.ts.map +1 -1
- package/dist/services/plugin-host-services.js +3 -1
- package/dist/services/plugin-host-services.js.map +1 -1
- package/dist/services/plugin-managed-routines.d.ts +1 -0
- package/dist/services/plugin-managed-routines.d.ts.map +1 -1
- package/dist/services/plugin-registry.d.ts +21 -21
- package/dist/services/productivity-review.d.ts +1 -0
- package/dist/services/productivity-review.d.ts.map +1 -1
- package/dist/services/productivity-review.js +6 -5
- package/dist/services/productivity-review.js.map +1 -1
- package/dist/services/projects.d.ts +9 -9
- package/dist/services/recovery/service.d.ts +82 -54
- package/dist/services/recovery/service.d.ts.map +1 -1
- package/dist/services/recovery/service.js +200 -35
- package/dist/services/recovery/service.js.map +1 -1
- package/dist/services/recovery/successful-run-handoff.d.ts +1 -0
- package/dist/services/recovery/successful-run-handoff.d.ts.map +1 -1
- package/dist/services/recovery/successful-run-handoff.js +2 -0
- package/dist/services/recovery/successful-run-handoff.js.map +1 -1
- package/dist/services/recovery/successful-run-handoff.test.js +20 -0
- package/dist/services/recovery/successful-run-handoff.test.js.map +1 -1
- package/dist/services/resource-memberships.d.ts +13 -10
- package/dist/services/resource-memberships.d.ts.map +1 -1
- package/dist/services/resource-memberships.js +89 -20
- package/dist/services/resource-memberships.js.map +1 -1
- package/dist/services/responsible-user-denial-run-outcomes.d.ts +60 -0
- package/dist/services/responsible-user-denial-run-outcomes.d.ts.map +1 -0
- package/dist/services/responsible-user-denial-run-outcomes.js +56 -0
- package/dist/services/responsible-user-denial-run-outcomes.js.map +1 -0
- package/dist/services/responsible-user-denial-run-outcomes.test.d.ts +2 -0
- package/dist/services/responsible-user-denial-run-outcomes.test.d.ts.map +1 -0
- package/dist/services/responsible-user-denial-run-outcomes.test.js +75 -0
- package/dist/services/responsible-user-denial-run-outcomes.test.js.map +1 -0
- package/dist/services/routines.d.ts +30 -8
- package/dist/services/routines.d.ts.map +1 -1
- package/dist/services/routines.js +241 -18
- package/dist/services/routines.js.map +1 -1
- package/dist/services/run-liveness.d.ts.map +1 -1
- package/dist/services/run-liveness.js +21 -0
- package/dist/services/run-liveness.js.map +1 -1
- package/dist/services/run-log-store.d.ts +1 -0
- package/dist/services/run-log-store.d.ts.map +1 -1
- package/dist/services/run-log-store.js +4 -0
- package/dist/services/run-log-store.js.map +1 -1
- package/dist/services/run-scratch.d.ts +42 -0
- package/dist/services/run-scratch.d.ts.map +1 -0
- package/dist/services/run-scratch.js +111 -0
- package/dist/services/run-scratch.js.map +1 -0
- package/dist/services/run-scratch.test.d.ts +2 -0
- package/dist/services/run-scratch.test.d.ts.map +1 -0
- package/dist/services/run-scratch.test.js +98 -0
- package/dist/services/run-scratch.test.js.map +1 -0
- package/dist/services/secrets.d.ts +1261 -64
- package/dist/services/secrets.d.ts.map +1 -1
- package/dist/services/secrets.js +1089 -96
- package/dist/services/secrets.js.map +1 -1
- package/dist/services/task-watchdogs.d.ts +1 -0
- package/dist/services/task-watchdogs.d.ts.map +1 -1
- package/dist/services/task-watchdogs.js +78 -9
- package/dist/services/task-watchdogs.js.map +1 -1
- package/dist/services/work-timeline.d.ts.map +1 -1
- package/dist/services/work-timeline.js +34 -2
- package/dist/services/work-timeline.js.map +1 -1
- package/dist/services/workspace-runtime-read-model.d.ts +30 -29
- package/dist/services/workspace-runtime-read-model.d.ts.map +1 -1
- package/dist/services/workspace-runtime-read-model.js.map +1 -1
- package/dist/services/workspace-runtime.d.ts +59 -13
- package/dist/services/workspace-runtime.d.ts.map +1 -1
- package/dist/services/workspace-runtime.js +1121 -102
- package/dist/services/workspace-runtime.js.map +1 -1
- package/dist/skills-catalog/catalog/bundled/paperclip-operations/reflection-coach/SKILL.md +202 -0
- package/dist/skills-catalog/catalog/bundled/product/paperclip-capsules/SKILL.md +1 -1
- package/dist/skills-catalog/catalog/bundled/product/wireframe/SKILL.md +1 -1
- package/dist/skills-catalog/catalog/optional/content/release-announcement/SKILL.md +90 -0
- package/dist/skills-catalog/catalog/optional/finance/ramp/SKILL.md +98 -0
- package/dist/skills-catalog/generated/catalog.json +84 -12
- package/dist/ui-branding.d.ts +7 -0
- package/dist/ui-branding.d.ts.map +1 -1
- package/dist/ui-branding.js +8 -2
- package/dist/ui-branding.js.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +114 -3
- package/dist/version.js.map +1 -1
- package/package.json +19 -20
- package/skills/paperclip/SKILL.md +45 -10
- package/skills/paperclip/references/api-reference.md +246 -1
- package/skills/paperclip/references/cases.md +295 -0
- package/skills/paperclip/references/company-skills.md +1 -1
- package/skills/paperclip-board/SKILL.md +3 -4
- package/skills/paperclip-converting-plans-to-tasks/SKILL.md +3 -7
- package/skills/para-memory-files/SKILL.md +3 -7
- package/ui-dist/assets/{abnfDiagram-VRR7QNED-BsFz2IiG.js → abnfDiagram-VRR7QNED-Dtgfy1PK.js} +1 -1
- package/ui-dist/assets/{arc-HZhAwbOs.js → arc-BGdvNvs8.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-BteMjuOn.js → architectureDiagram-ZJ3FMSHR-CK19SQDx.js} +1 -1
- package/ui-dist/assets/{blockDiagram-677ZJIJ3-Iq66uZjf.js → blockDiagram-677ZJIJ3-Kh4N3XG4.js} +1 -1
- package/ui-dist/assets/{browser-ponyfill-BBsuyZJt.js → browser-ponyfill-B3hXtEFW.js} +1 -1
- package/ui-dist/assets/{c4Diagram-LMCZKHZV-_nlglj7I.js → c4Diagram-LMCZKHZV-CBHpGrgU.js} +1 -1
- package/ui-dist/assets/channel-4fjB8e8N.js +1 -0
- package/ui-dist/assets/{chunk-2Q5K7J3B-Cvz7WwSQ.js → chunk-2Q5K7J3B-BdHbqi7k.js} +1 -1
- package/ui-dist/assets/{chunk-32BRIVSS-LLubniCS.js → chunk-32BRIVSS-DxtzZzpt.js} +1 -1
- package/ui-dist/assets/{chunk-5VM5RSS4-BOst5hcr.js → chunk-5VM5RSS4-DMKxBbgu.js} +1 -1
- package/ui-dist/assets/{chunk-EX3LRPZG-D5WNShVm.js → chunk-EX3LRPZG-BaIOPi4v.js} +1 -1
- package/ui-dist/assets/{chunk-JWPE2WC7-CA07x4av.js → chunk-JWPE2WC7-DGo3MPmr.js} +1 -1
- package/ui-dist/assets/{chunk-MOJQB5TN-Clfi83rK.js → chunk-MOJQB5TN-BEhQg0uD.js} +1 -1
- package/ui-dist/assets/{chunk-RYQCIY6F-BhZ6p7YJ.js → chunk-RYQCIY6F-HPJ6zRpJ.js} +1 -1
- package/ui-dist/assets/{chunk-V7JOEXUC-CdexJGoV.js → chunk-V7JOEXUC-Bl_6cAJD.js} +1 -1
- package/ui-dist/assets/{chunk-VR4S4FIN-8vjmBhr1.js → chunk-VR4S4FIN-KMjgGCsw.js} +1 -1
- package/ui-dist/assets/{chunk-XXDRQBXY-CqmCaplj.js → chunk-XXDRQBXY-oWGAIKjr.js} +1 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-CTXxO5l9.js +1 -0
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CTXxO5l9.js +1 -0
- package/ui-dist/assets/{cose-bilkent-JH36ORCC-CY-zAygY.js → cose-bilkent-JH36ORCC-Ckqse1pH.js} +1 -1
- package/ui-dist/assets/{cynefin-VYW2F7L2-BQSQ1HKr.js → cynefin-VYW2F7L2-DfZ8Hzqi.js} +1 -1
- package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-NJCuFrZL.js → cynefinDiagram-TSTJHNR4-BkDQo9oi.js} +1 -1
- package/ui-dist/assets/{dagre-VKFMJZFB-DAUPIc8g.js → dagre-VKFMJZFB-ClghXQ6E.js} +1 -1
- package/ui-dist/assets/{diagram-FQU43EPY-DvMwJlCi.js → diagram-FQU43EPY-D5a0CwpV.js} +1 -1
- package/ui-dist/assets/{diagram-G47NLZAW-DPY0Jz_y.js → diagram-G47NLZAW-hVjYR_xl.js} +1 -1
- package/ui-dist/assets/{diagram-NH7WQ7WH-BpopeEhp.js → diagram-NH7WQ7WH-BlDPgD5Z.js} +1 -1
- package/ui-dist/assets/{diagram-OA4YK3LP-Qpu05z9X.js → diagram-OA4YK3LP-D0iZKIS3.js} +1 -1
- package/ui-dist/assets/{diagram-WEI45ONY-DHnvw9XU.js → diagram-WEI45ONY-m6hrfD0J.js} +1 -1
- package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-D61S54_7.js → ebnfDiagram-CCIWWBDH-D4SQYLod.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q63AITRT-pplAN_x2.js → erDiagram-Q63AITRT-Byzb6-I5.js} +1 -1
- package/ui-dist/assets/{flowDiagram-23GEKE2U-BaBcbyDq.js → flowDiagram-23GEKE2U-CaTUkFO6.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-NO4QXBWP-BOJSII2b.js → ganttDiagram-NO4QXBWP-DmdMQ3ES.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-aYAaO4a2.js → gitGraphDiagram-IHSO6WYX-Bt-1g2CS.js} +1 -1
- package/ui-dist/assets/{index-CZxYajxF.js → index-2Dk9yO0W.js} +1 -1
- package/ui-dist/assets/{index-B8H0SHw1.js → index-8jLpgFNU.js} +1 -1
- package/ui-dist/assets/{index-3EKATXgc.js → index-AP_iimxs.js} +1 -1
- package/ui-dist/assets/{index-C2JgdjPa.js → index-BNJasQY9.js} +1 -1
- package/ui-dist/assets/{index-BaiskB3o.js → index-BO-aNmyX.js} +1 -1
- package/ui-dist/assets/{index-B5YenxAQ.js → index-BPCzCn1Y.js} +1 -1
- package/ui-dist/assets/{index-Da2kqT1M.js → index-BSLnLTb2.js} +1 -1
- package/ui-dist/assets/{index-By0oeEvz.js → index-CCZ2qgHN.js} +1 -1
- package/ui-dist/assets/{index-bUFCSEgv.js → index-CLZXR1k9.js} +1 -1
- package/ui-dist/assets/{index-CJlw4l9L.js → index-CTNfrE1s.js} +1 -1
- package/ui-dist/assets/{index-TmpY6Xh_.js → index-ChNd25s7.js} +1 -1
- package/ui-dist/assets/{index-BRgdHUNR.js → index-CjHiMOEO.js} +1 -1
- package/ui-dist/assets/{index-DrL6pHSJ.js → index-CmeJQpXZ.js} +1 -1
- package/ui-dist/assets/index-CyuYtn7U.css +1 -0
- package/ui-dist/assets/{index-CKKytnOd.js → index-CzZjM8eh.js} +1 -1
- package/ui-dist/assets/{index-Dceamza_.js → index-D-6T0Aft.js} +1 -1
- package/ui-dist/assets/{index-CjDqB1SX.js → index-DG_7V1pG.js} +1 -1
- package/ui-dist/assets/index-DIKcgxCt.js +676 -0
- package/ui-dist/assets/{index-BKVeJ3Jh.js → index-DiUerHmi.js} +1 -1
- package/ui-dist/assets/{index-C-nKjFZh.js → index-NZ7v5Fc2.js} +1 -1
- package/ui-dist/assets/{index-CvPPuNs1.js → index-Py70EvBg.js} +1 -1
- package/ui-dist/assets/{index-LHkZdu0h.js → index-R3aYn0qM.js} +1 -1
- package/ui-dist/assets/{index-BT8b79Bd.js → index-YXpm7gW-.js} +1 -1
- package/ui-dist/assets/{index-CemenVOf.js → index-n4q3gzki.js} +1 -1
- package/ui-dist/assets/{index-D3ODiUup.js → index-vlZ3GoYY.js} +1 -1
- package/ui-dist/assets/{infoDiagram-FWYZ7A6U-C7_90qGq.js → infoDiagram-FWYZ7A6U-jdi5ciVg.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-T-nPPdTt.js → ishikawaDiagram-FXEZZL3T-CMz5VvYp.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-5HDEW3XC-C3hqQN0R.js → journeyDiagram-5HDEW3XC-DK6dk2R-.js} +1 -1
- package/ui-dist/assets/{kanban-definition-HUTT4EX6-CPoD9DUm.js → kanban-definition-HUTT4EX6-DX5cZL-D.js} +1 -1
- package/ui-dist/assets/{linear-D-S8yr3Z.js → linear-CI96ABKp.js} +1 -1
- package/ui-dist/assets/{mermaid.core-DhvH8shK.js → mermaid.core-DnsEVfbd.js} +4 -4
- package/ui-dist/assets/{mindmap-definition-LN4V7U3C-CxCIKrKo.js → mindmap-definition-LN4V7U3C-BdDCY7hf.js} +1 -1
- package/ui-dist/assets/{pegDiagram-2B236MQR-D4G-PC6N.js → pegDiagram-2B236MQR-DuY4TF-f.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ENE6RG2P-N4X8UvqY.js → pieDiagram-ENE6RG2P-bgFw7dm3.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-CZohoDln.js → quadrantDiagram-ABIIQ3AL-BCZVWyWS.js} +1 -1
- package/ui-dist/assets/{railroadDiagram-RFXS5EU6-fMGQVhwF.js → railroadDiagram-RFXS5EU6-D9V5_Cgc.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-TGXJPOKE-CK0IuUmk.js → requirementDiagram-TGXJPOKE-CItsya2r.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-pSfb3CqG.js → sankeyDiagram-HTMAVEWB-Cz9IHsZO.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-CbhkqIeq.js → sequenceDiagram-DBY2YBRQ-hMSqTiwK.js} +1 -1
- package/ui-dist/assets/{sizeCapture-X5ZJPWSS-B6vqqPx-.js → sizeCapture-X5ZJPWSS-0g9M5wMf.js} +1 -1
- package/ui-dist/assets/{stateDiagram-2N3HPSRC-DIJf9h5C.js → stateDiagram-2N3HPSRC-F8_YhgWl.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-fZImUBtq.js +1 -0
- package/ui-dist/assets/{swimlanes-5IMT3BWC-DIX_LV8O.js → swimlanes-5IMT3BWC-CCZqPbpE.js} +2 -2
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-9C1UT51R.js +8 -0
- package/ui-dist/assets/{timeline-definition-FHXFAJF6-CD-Pxb_g.js → timeline-definition-FHXFAJF6-BeUIr18x.js} +1 -1
- package/ui-dist/assets/{vennDiagram-L72KCM5P-BAZsWL0R.js → vennDiagram-L72KCM5P-D3d5h_G4.js} +1 -1
- package/ui-dist/assets/{wardleyDiagram-EHGQE667-CnNyfwX5.js → wardleyDiagram-EHGQE667-Bzt-As9A.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-FW5EYKEG-j9YgsD3Y.js → xychartDiagram-FW5EYKEG-C2mly0xf.js} +1 -1
- package/ui-dist/fonts/InterVariable-Italic.woff2 +0 -0
- package/ui-dist/fonts/InterVariable.woff2 +0 -0
- package/ui-dist/fonts/NOTICE.md +17 -0
- package/ui-dist/index.html +2 -2
- package/ui-dist/locales/en/common.json +1142 -5
- package/ui-dist/locales/zh-CN/common.json +1140 -3
- package/ui-dist/assets/channel-CsiI2LYw.js +0 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-CBn1Jqo8.js +0 -1
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CBn1Jqo8.js +0 -1
- package/ui-dist/assets/index-BsL8K1vL.css +0 -1
- package/ui-dist/assets/index-D__fTsb2.js +0 -643
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-DpwLD7YL.js +0 -1
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-Cklauutg.js +0 -8
|
@@ -3,6 +3,7 @@ import { DEFAULT_ISSUE_GRAPH_LIVENESS_AUTO_RECOVERY_LOOKBACK_HOURS, MAX_ISSUE_GR
|
|
|
3
3
|
import { agents, agentWakeupRequests, approvals, activityLog, companies, heartbeatRunEvents, heartbeatRunWatchdogDecisions, heartbeatRuns, issueAttachments, issueComments, issueApprovals, issueRecoveryActions, issueRelations, issueThreadInteractions, issues, } from "@penclipai/db";
|
|
4
4
|
import { parseObject, asBoolean, asNumber } from "../../adapters/utils.js";
|
|
5
5
|
import { runningProcesses } from "../../adapters/index.js";
|
|
6
|
+
import { visibleIssueCondition } from "../issue-visibility.js";
|
|
6
7
|
import { forbidden, notFound } from "../../errors.js";
|
|
7
8
|
import { logger } from "../../middleware/logger.js";
|
|
8
9
|
import { isPidAlive, isProcessGroupAlive, terminateLocalService } from "../local-service-supervisor.js";
|
|
@@ -25,7 +26,7 @@ import { classifyIssueGraphLiveness, } from "./issue-graph-liveness.js";
|
|
|
25
26
|
import { recoveryAssigneeAdapterOverrides, withRecoveryModelProfileHint, } from "./model-profile-hint.js";
|
|
26
27
|
import { isAutomaticRecoverySuppressedByPauseHold } from "./pause-hold-guard.js";
|
|
27
28
|
const EXECUTION_PATH_HEARTBEAT_RUN_STATUSES = ["queued", "running", "scheduled_retry"];
|
|
28
|
-
const UNSUCCESSFUL_HEARTBEAT_RUN_TERMINAL_STATUSES = ["failed", "cancelled", "timed_out"];
|
|
29
|
+
const UNSUCCESSFUL_HEARTBEAT_RUN_TERMINAL_STATUSES = ["interrupted", "failed", "cancelled", "timed_out"];
|
|
29
30
|
export const ACTIVE_RUN_OUTPUT_SUSPICION_THRESHOLD_MS = 60 * 60 * 1000;
|
|
30
31
|
export const ACTIVE_RUN_OUTPUT_CRITICAL_THRESHOLD_MS = 4 * 60 * 60 * 1000;
|
|
31
32
|
export const ACTIVE_RUN_OUTPUT_CONTINUE_REARM_MS = 30 * 60 * 1000;
|
|
@@ -102,6 +103,7 @@ const TRANSIENT_INFRA_CONTINUATION_ERROR_CODES = new Set([
|
|
|
102
103
|
"adapter_failed",
|
|
103
104
|
"codex_transient_upstream",
|
|
104
105
|
"claude_transient_upstream",
|
|
106
|
+
"provider_quota",
|
|
105
107
|
"timeout",
|
|
106
108
|
]);
|
|
107
109
|
const NON_RETRYABLE_CONTINUATION_ERROR_CODES = new Set([
|
|
@@ -426,6 +428,17 @@ export function recoveryService(db, deps) {
|
|
|
426
428
|
.limit(1)
|
|
427
429
|
.then((rows) => Boolean(rows[0]));
|
|
428
430
|
}
|
|
431
|
+
async function hasPersistedDurableWaitPath(issue) {
|
|
432
|
+
if (issue.monitorNextCheckAt)
|
|
433
|
+
return true;
|
|
434
|
+
return db
|
|
435
|
+
.select({ id: issueRelations.issueId })
|
|
436
|
+
.from(issueRelations)
|
|
437
|
+
.innerJoin(issues, eq(issueRelations.issueId, issues.id))
|
|
438
|
+
.where(and(eq(issueRelations.companyId, issue.companyId), eq(issueRelations.relatedIssueId, issue.id), eq(issueRelations.type, "blocks"), eq(issues.companyId, issue.companyId), notInArray(issues.status, ["done", "cancelled"]), isNull(issues.hiddenAt)))
|
|
439
|
+
.limit(1)
|
|
440
|
+
.then((rows) => Boolean(rows[0]));
|
|
441
|
+
}
|
|
429
442
|
async function hasQueuedIssueWake(companyId, issueId, agentId) {
|
|
430
443
|
return db
|
|
431
444
|
.select({ id: agentWakeupRequests.id })
|
|
@@ -434,6 +447,51 @@ export function recoveryService(db, deps) {
|
|
|
434
447
|
.limit(1)
|
|
435
448
|
.then((rows) => Boolean(rows[0]));
|
|
436
449
|
}
|
|
450
|
+
async function getLatestAcceptedContinuationInteraction(companyId, issueId) {
|
|
451
|
+
return db
|
|
452
|
+
.select({
|
|
453
|
+
id: issueThreadInteractions.id,
|
|
454
|
+
kind: issueThreadInteractions.kind,
|
|
455
|
+
status: issueThreadInteractions.status,
|
|
456
|
+
continuationPolicy: issueThreadInteractions.continuationPolicy,
|
|
457
|
+
sourceRunId: issueThreadInteractions.sourceRunId,
|
|
458
|
+
resolvedAt: issueThreadInteractions.resolvedAt,
|
|
459
|
+
updatedAt: issueThreadInteractions.updatedAt,
|
|
460
|
+
})
|
|
461
|
+
.from(issueThreadInteractions)
|
|
462
|
+
.where(and(eq(issueThreadInteractions.companyId, companyId), eq(issueThreadInteractions.issueId, issueId), eq(issueThreadInteractions.status, "accepted"), inArray(issueThreadInteractions.continuationPolicy, ["wake_assignee", "wake_assignee_on_accept"])))
|
|
463
|
+
.orderBy(desc(sql `coalesce(${issueThreadInteractions.resolvedAt}, ${issueThreadInteractions.updatedAt})`), desc(issueThreadInteractions.id))
|
|
464
|
+
.limit(1)
|
|
465
|
+
.then((rows) => rows[0] ?? null);
|
|
466
|
+
}
|
|
467
|
+
async function hasSuccessfulIssueRunSince(companyId, issueId, agentId, since, interactionId) {
|
|
468
|
+
return db
|
|
469
|
+
.select({ id: heartbeatRuns.id })
|
|
470
|
+
.from(heartbeatRuns)
|
|
471
|
+
.where(and(eq(heartbeatRuns.companyId, companyId), eq(heartbeatRuns.agentId, agentId), eq(heartbeatRuns.status, "succeeded"), sql `${heartbeatRuns.contextSnapshot} ->> 'issueId' = ${issueId}`, interactionId
|
|
472
|
+
? sql `${heartbeatRuns.contextSnapshot} ->> 'interactionId' = ${interactionId}`
|
|
473
|
+
: sql `true`, or(gte(heartbeatRuns.createdAt, since), gte(heartbeatRuns.finishedAt, since))))
|
|
474
|
+
.limit(1)
|
|
475
|
+
.then((rows) => Boolean(rows[0]));
|
|
476
|
+
}
|
|
477
|
+
async function getLatestIssueRunSince(companyId, issueId, agentId, since) {
|
|
478
|
+
return db
|
|
479
|
+
.select({
|
|
480
|
+
id: heartbeatRuns.id,
|
|
481
|
+
agentId: heartbeatRuns.agentId,
|
|
482
|
+
status: heartbeatRuns.status,
|
|
483
|
+
error: heartbeatRuns.error,
|
|
484
|
+
errorCode: heartbeatRuns.errorCode,
|
|
485
|
+
contextSnapshot: heartbeatRuns.contextSnapshot,
|
|
486
|
+
livenessState: heartbeatRuns.livenessState,
|
|
487
|
+
resultJson: heartbeatRuns.resultJson,
|
|
488
|
+
})
|
|
489
|
+
.from(heartbeatRuns)
|
|
490
|
+
.where(and(eq(heartbeatRuns.companyId, companyId), eq(heartbeatRuns.agentId, agentId), sql `${heartbeatRuns.contextSnapshot} ->> 'issueId' = ${issueId}`, or(gte(heartbeatRuns.createdAt, since), gte(heartbeatRuns.finishedAt, since))))
|
|
491
|
+
.orderBy(desc(heartbeatRuns.createdAt), desc(heartbeatRuns.id))
|
|
492
|
+
.limit(1)
|
|
493
|
+
.then((rows) => rows[0] ?? null);
|
|
494
|
+
}
|
|
437
495
|
// GGU-809: visible-progress signal for stranded-recovery escalation guard.
|
|
438
496
|
// Returns true if the assignee posted a comment, OR any attachment was added
|
|
439
497
|
// to the issue, within `windowMs`. Used to suppress false-positive recovery
|
|
@@ -656,7 +714,7 @@ export function recoveryService(db, deps) {
|
|
|
656
714
|
updatedAt: issues.updatedAt,
|
|
657
715
|
})
|
|
658
716
|
.from(issues)
|
|
659
|
-
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, STALE_ACTIVE_RUN_EVALUATION_ORIGIN_KIND), eq(issues.originId, runId),
|
|
717
|
+
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, STALE_ACTIVE_RUN_EVALUATION_ORIGIN_KIND), eq(issues.originId, runId), visibleIssueCondition(), notInArray(issues.status, ["done", "cancelled"])))
|
|
660
718
|
.limit(1);
|
|
661
719
|
return row ?? null;
|
|
662
720
|
}
|
|
@@ -673,7 +731,7 @@ export function recoveryService(db, deps) {
|
|
|
673
731
|
const [row] = await db
|
|
674
732
|
.select({ id: issues.id, identifier: issues.identifier, status: issues.status })
|
|
675
733
|
.from(issues)
|
|
676
|
-
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, STALE_ACTIVE_RUN_EVALUATION_ORIGIN_KIND), eq(issues.originId, runId),
|
|
734
|
+
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, STALE_ACTIVE_RUN_EVALUATION_ORIGIN_KIND), eq(issues.originId, runId), visibleIssueCondition(), eq(issues.status, "done")))
|
|
677
735
|
.orderBy(desc(issues.updatedAt))
|
|
678
736
|
.limit(1);
|
|
679
737
|
return row ?? null;
|
|
@@ -750,7 +808,7 @@ export function recoveryService(db, deps) {
|
|
|
750
808
|
const [issue] = await db
|
|
751
809
|
.select()
|
|
752
810
|
.from(issues)
|
|
753
|
-
.where(and(eq(issues.companyId, run.companyId), eq(issues.id, issueId),
|
|
811
|
+
.where(and(eq(issues.companyId, run.companyId), eq(issues.id, issueId), visibleIssueCondition()))
|
|
754
812
|
.limit(1);
|
|
755
813
|
return issue ?? null;
|
|
756
814
|
}
|
|
@@ -1060,7 +1118,7 @@ export function recoveryService(db, deps) {
|
|
|
1060
1118
|
? db
|
|
1061
1119
|
.select({ id: issues.id, identifier: issues.identifier, title: issues.title, status: issues.status })
|
|
1062
1120
|
.from(issues)
|
|
1063
|
-
.where(and(eq(issues.companyId, input.run.companyId), eq(issues.parentId, input.sourceIssue.id),
|
|
1121
|
+
.where(and(eq(issues.companyId, input.run.companyId), eq(issues.parentId, input.sourceIssue.id), visibleIssueCondition()))
|
|
1064
1122
|
.orderBy(desc(issues.updatedAt))
|
|
1065
1123
|
.limit(8)
|
|
1066
1124
|
: Promise.resolve([]),
|
|
@@ -1414,12 +1472,27 @@ export function recoveryService(db, deps) {
|
|
|
1414
1472
|
async function scanSilentActiveRuns(opts) {
|
|
1415
1473
|
const now = opts?.now ?? new Date();
|
|
1416
1474
|
const suspicionBefore = new Date(now.getTime() - ACTIVE_RUN_OUTPUT_SUSPICION_THRESHOLD_MS);
|
|
1417
|
-
|
|
1475
|
+
let candidates = await db
|
|
1418
1476
|
.select()
|
|
1419
1477
|
.from(heartbeatRuns)
|
|
1420
1478
|
.where(and(opts?.companyId ? eq(heartbeatRuns.companyId, opts.companyId) : undefined, eq(heartbeatRuns.status, "running"), sql `coalesce(${heartbeatRuns.lastOutputAt}, ${heartbeatRuns.processStartedAt}, ${heartbeatRuns.startedAt}, ${heartbeatRuns.createdAt}) <= ${suspicionBefore.toISOString()}::timestamptz`))
|
|
1421
1479
|
.orderBy(asc(heartbeatRuns.createdAt))
|
|
1422
1480
|
.limit(100);
|
|
1481
|
+
if (opts?.issueCreatedAtGte) {
|
|
1482
|
+
const issueIds = [...new Set(candidates.flatMap((run) => {
|
|
1483
|
+
const context = parseObject(run.contextSnapshot);
|
|
1484
|
+
const issueId = context.issueId ?? context.taskId;
|
|
1485
|
+
return typeof issueId === "string" && issueId.length > 0 ? [issueId] : [];
|
|
1486
|
+
}))];
|
|
1487
|
+
const eligibleIssueIds = new Set(issueIds.length > 0
|
|
1488
|
+
? (await db.select({ id: issues.id }).from(issues).where(and(inArray(issues.id, issueIds), gte(issues.createdAt, opts.issueCreatedAtGte)))).map((issue) => issue.id)
|
|
1489
|
+
: []);
|
|
1490
|
+
candidates = candidates.filter((run) => {
|
|
1491
|
+
const context = parseObject(run.contextSnapshot);
|
|
1492
|
+
const issueId = context.issueId ?? context.taskId;
|
|
1493
|
+
return typeof issueId === "string" && eligibleIssueIds.has(issueId);
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1423
1496
|
const result = {
|
|
1424
1497
|
scanned: candidates.length,
|
|
1425
1498
|
created: 0,
|
|
@@ -1563,7 +1636,7 @@ export function recoveryService(db, deps) {
|
|
|
1563
1636
|
return db
|
|
1564
1637
|
.select()
|
|
1565
1638
|
.from(issues)
|
|
1566
|
-
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, STRANDED_ISSUE_RECOVERY_ORIGIN_KIND), eq(issues.originId, sourceIssueId),
|
|
1639
|
+
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, STRANDED_ISSUE_RECOVERY_ORIGIN_KIND), eq(issues.originId, sourceIssueId), visibleIssueCondition(), notInArray(issues.status, ["done", "cancelled"])))
|
|
1567
1640
|
.orderBy(desc(issues.createdAt))
|
|
1568
1641
|
.limit(1)
|
|
1569
1642
|
.then((rows) => rows[0] ?? null);
|
|
@@ -2008,7 +2081,7 @@ export function recoveryService(db, deps) {
|
|
|
2008
2081
|
const openChildren = await db
|
|
2009
2082
|
.select({ id: issues.id, identifier: issues.identifier })
|
|
2010
2083
|
.from(issues)
|
|
2011
|
-
.where(and(eq(issues.companyId, issue.companyId), eq(issues.parentId, issue.id),
|
|
2084
|
+
.where(and(eq(issues.companyId, issue.companyId), eq(issues.parentId, issue.id), visibleIssueCondition(), notInArray(issues.status, ["done", "cancelled"])));
|
|
2012
2085
|
const blockedByIssueIds = [...new Set([...existingBlockers.map((row) => row.id), ...openChildren.map((row) => row.id)])];
|
|
2013
2086
|
if (blockedByIssueIds.length === 0)
|
|
2014
2087
|
return null;
|
|
@@ -2189,11 +2262,11 @@ export function recoveryService(db, deps) {
|
|
|
2189
2262
|
}
|
|
2190
2263
|
return updated;
|
|
2191
2264
|
}
|
|
2192
|
-
async function reconcileStrandedAssignedIssues() {
|
|
2265
|
+
async function reconcileStrandedAssignedIssues(opts) {
|
|
2193
2266
|
const candidates = await db
|
|
2194
2267
|
.select()
|
|
2195
2268
|
.from(issues)
|
|
2196
|
-
.where(and(isNull(issues.assigneeUserId), inArray(issues.status, ["todo", "in_progress", "in_review"]), or(sql `${issues.assigneeAgentId} is not null`, eq(issues.status, "in_review"))));
|
|
2269
|
+
.where(and(isNull(issues.assigneeUserId), inArray(issues.status, ["todo", "in_progress", "in_review"]), or(sql `${issues.assigneeAgentId} is not null`, eq(issues.status, "in_review")), opts?.issueCreatedAtGte ? gte(issues.createdAt, opts.issueCreatedAtGte) : undefined));
|
|
2197
2270
|
const result = {
|
|
2198
2271
|
assignmentDispatched: 0,
|
|
2199
2272
|
dispatchRequeued: 0,
|
|
@@ -2246,6 +2319,10 @@ export function recoveryService(db, deps) {
|
|
|
2246
2319
|
continue;
|
|
2247
2320
|
}
|
|
2248
2321
|
const latestRun = await getLatestIssueRun(issue.companyId, issue.id);
|
|
2322
|
+
if (latestRun?.status === "succeeded" && await hasPersistedDurableWaitPath(issue)) {
|
|
2323
|
+
result.skipped += 1;
|
|
2324
|
+
continue;
|
|
2325
|
+
}
|
|
2249
2326
|
if (isStrandedIssueRecoveryIssue(issue) && isUnsuccessfulTerminalIssueRun(latestRun)) {
|
|
2250
2327
|
const updated = await escalateStrandedRecoveryIssueInPlace({
|
|
2251
2328
|
issue,
|
|
@@ -2261,6 +2338,52 @@ export function recoveryService(db, deps) {
|
|
|
2261
2338
|
}
|
|
2262
2339
|
continue;
|
|
2263
2340
|
}
|
|
2341
|
+
const acceptedContinuationInteraction = await getLatestAcceptedContinuationInteraction(issue.companyId, issue.id);
|
|
2342
|
+
const acceptedInteractionResolvedAt = acceptedContinuationInteraction
|
|
2343
|
+
? acceptedContinuationInteraction.resolvedAt ?? acceptedContinuationInteraction.updatedAt
|
|
2344
|
+
: null;
|
|
2345
|
+
if (acceptedContinuationInteraction && acceptedInteractionResolvedAt && !pendingExecutionState) {
|
|
2346
|
+
const successfulRunSinceResolution = await hasSuccessfulIssueRunSince(issue.companyId, issue.id, agentId, acceptedInteractionResolvedAt, acceptedContinuationInteraction.id);
|
|
2347
|
+
if (!successfulRunSinceResolution) {
|
|
2348
|
+
if (!agentInvokable) {
|
|
2349
|
+
result.skipped += 1;
|
|
2350
|
+
continue;
|
|
2351
|
+
}
|
|
2352
|
+
if (await hasQueuedIssueWake(issue.companyId, issue.id, agentId)) {
|
|
2353
|
+
result.skipped += 1;
|
|
2354
|
+
continue;
|
|
2355
|
+
}
|
|
2356
|
+
if (await isInvocationBudgetBlocked(issue, agentId)) {
|
|
2357
|
+
result.skipped += 1;
|
|
2358
|
+
continue;
|
|
2359
|
+
}
|
|
2360
|
+
const latestPostResolutionRun = await getLatestIssueRunSince(issue.companyId, issue.id, agentId, acceptedInteractionResolvedAt);
|
|
2361
|
+
const queued = await enqueueStrandedIssueRecovery({
|
|
2362
|
+
issueId: issue.id,
|
|
2363
|
+
agentId,
|
|
2364
|
+
reason: "issue_continuation_needed",
|
|
2365
|
+
retryReason: "issue_continuation_needed",
|
|
2366
|
+
source: "issue.interaction_continuation_recovery",
|
|
2367
|
+
retryOfRunId: latestPostResolutionRun?.id ?? acceptedContinuationInteraction.sourceRunId ?? latestRun?.id ?? null,
|
|
2368
|
+
extraContext: {
|
|
2369
|
+
mutation: "interaction",
|
|
2370
|
+
interactionId: acceptedContinuationInteraction.id,
|
|
2371
|
+
interactionKind: acceptedContinuationInteraction.kind,
|
|
2372
|
+
interactionStatus: acceptedContinuationInteraction.status,
|
|
2373
|
+
interactionContinuationPolicy: acceptedContinuationInteraction.continuationPolicy,
|
|
2374
|
+
interactionResolvedAt: acceptedInteractionResolvedAt.toISOString(),
|
|
2375
|
+
},
|
|
2376
|
+
});
|
|
2377
|
+
if (queued) {
|
|
2378
|
+
result.continuationRequeued += 1;
|
|
2379
|
+
result.issueIds.push(issue.id);
|
|
2380
|
+
}
|
|
2381
|
+
else {
|
|
2382
|
+
result.skipped += 1;
|
|
2383
|
+
}
|
|
2384
|
+
continue;
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2264
2387
|
if (issue.status === "in_review") {
|
|
2265
2388
|
if (!participantAgentId || !pendingExecutionState) {
|
|
2266
2389
|
result.skipped += 1;
|
|
@@ -2611,7 +2734,7 @@ export function recoveryService(db, deps) {
|
|
|
2611
2734
|
monitorAttemptCount: issues.monitorAttemptCount,
|
|
2612
2735
|
})
|
|
2613
2736
|
.from(issues)
|
|
2614
|
-
.where(and(
|
|
2737
|
+
.where(and(visibleIssueCondition(), notInArray(issues.originKind, [RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation]))));
|
|
2615
2738
|
const [issueRows, relationRows, agentRows, activeRunRows, activeIssueRunRows, wakeRows, interactionRows, approvalRows, recoveryIssueRows, recoveryActionRows,] = await Promise.all([
|
|
2616
2739
|
issueRowsPromise,
|
|
2617
2740
|
db
|
|
@@ -2651,7 +2774,7 @@ export function recoveryService(db, deps) {
|
|
|
2651
2774
|
})
|
|
2652
2775
|
.from(issues)
|
|
2653
2776
|
.innerJoin(heartbeatRuns, eq(issues.executionRunId, heartbeatRuns.id))
|
|
2654
|
-
.where(and(
|
|
2777
|
+
.where(and(visibleIssueCondition(), notInArray(issues.originKind, [RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation]), inArray(heartbeatRuns.status, [...EXECUTION_PATH_HEARTBEAT_RUN_STATUSES]))),
|
|
2655
2778
|
db
|
|
2656
2779
|
.select({
|
|
2657
2780
|
companyId: agentWakeupRequests.companyId,
|
|
@@ -2687,7 +2810,7 @@ export function recoveryService(db, deps) {
|
|
|
2687
2810
|
originId: issues.originId,
|
|
2688
2811
|
})
|
|
2689
2812
|
.from(issues)
|
|
2690
|
-
.where(and(
|
|
2813
|
+
.where(and(visibleIssueCondition(), inArray(issues.originKind, [
|
|
2691
2814
|
STRANDED_ISSUE_RECOVERY_ORIGIN_KIND,
|
|
2692
2815
|
RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation,
|
|
2693
2816
|
]), notInArray(issues.status, ["done", "cancelled"]))),
|
|
@@ -2763,7 +2886,7 @@ export function recoveryService(db, deps) {
|
|
|
2763
2886
|
return db
|
|
2764
2887
|
.select()
|
|
2765
2888
|
.from(issues)
|
|
2766
|
-
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation), eq(issues.originId, incidentKey),
|
|
2889
|
+
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation), eq(issues.originId, incidentKey), visibleIssueCondition(), notInArray(issues.status, ["done", "cancelled"])))
|
|
2767
2890
|
.limit(1)
|
|
2768
2891
|
.then((rows) => rows[0] ?? null);
|
|
2769
2892
|
}
|
|
@@ -2771,7 +2894,7 @@ export function recoveryService(db, deps) {
|
|
|
2771
2894
|
const byFingerprint = await db
|
|
2772
2895
|
.select()
|
|
2773
2896
|
.from(issues)
|
|
2774
|
-
.where(and(eq(issues.companyId, finding.companyId), eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation), eq(issues.originFingerprint, livenessRecoveryLeafFingerprint(finding)),
|
|
2897
|
+
.where(and(eq(issues.companyId, finding.companyId), eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation), eq(issues.originFingerprint, livenessRecoveryLeafFingerprint(finding)), visibleIssueCondition(), notInArray(issues.status, ["done", "cancelled"])))
|
|
2775
2898
|
.limit(1)
|
|
2776
2899
|
.then((rows) => rows[0] ?? null);
|
|
2777
2900
|
if (byFingerprint)
|
|
@@ -2780,7 +2903,7 @@ export function recoveryService(db, deps) {
|
|
|
2780
2903
|
const openRecoveries = await db
|
|
2781
2904
|
.select()
|
|
2782
2905
|
.from(issues)
|
|
2783
|
-
.where(and(eq(issues.companyId, finding.companyId), eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation),
|
|
2906
|
+
.where(and(eq(issues.companyId, finding.companyId), eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation), visibleIssueCondition(), notInArray(issues.status, ["done", "cancelled"])));
|
|
2784
2907
|
return openRecoveries.find((row) => {
|
|
2785
2908
|
const parsed = parseLivenessIncidentKey(row.originId);
|
|
2786
2909
|
return parsed?.state === finding.state && parsed.leafIssueId === leafIssueId;
|
|
@@ -2830,7 +2953,7 @@ export function recoveryService(db, deps) {
|
|
|
2830
2953
|
const openRecoveries = await db
|
|
2831
2954
|
.select()
|
|
2832
2955
|
.from(issues)
|
|
2833
|
-
.where(and(eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation),
|
|
2956
|
+
.where(and(eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation), visibleIssueCondition(), notInArray(issues.status, ["done", "cancelled"])));
|
|
2834
2957
|
const result = {
|
|
2835
2958
|
retired: 0,
|
|
2836
2959
|
activeSkipped: 0,
|
|
@@ -2878,7 +3001,7 @@ export function recoveryService(db, deps) {
|
|
|
2878
3001
|
const closedRecoveries = await db
|
|
2879
3002
|
.select()
|
|
2880
3003
|
.from(issues)
|
|
2881
|
-
.where(and(eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation),
|
|
3004
|
+
.where(and(eq(issues.originKind, RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation), visibleIssueCondition(), inArray(issues.status, ["done", "cancelled"])));
|
|
2882
3005
|
let blockerRelationsRemoved = 0;
|
|
2883
3006
|
for (const recovery of closedRecoveries) {
|
|
2884
3007
|
if (await removeRecoveryBlockerFromSource(recovery)) {
|
|
@@ -3221,14 +3344,40 @@ export function recoveryService(db, deps) {
|
|
|
3221
3344
|
enqueueFailed: 0,
|
|
3222
3345
|
issueIds: [],
|
|
3223
3346
|
};
|
|
3347
|
+
const source = opts?.source ?? "issue_graph_liveness.backstop";
|
|
3348
|
+
const requestedByActorId = source === "workspace.finalize"
|
|
3349
|
+
? "heartbeat_finalize"
|
|
3350
|
+
: "issue_graph_liveness_backstop";
|
|
3351
|
+
const payloadBackstop = source === "workspace.finalize"
|
|
3352
|
+
? "workspace_finalize_reconciliation"
|
|
3353
|
+
: "issue_graph_liveness_reconciliation";
|
|
3354
|
+
const useCursor = !opts?.blockerIssueId;
|
|
3224
3355
|
const queryCandidates = (afterIssueId) => {
|
|
3225
3356
|
const filters = [
|
|
3226
3357
|
eq(issues.status, "blocked"),
|
|
3227
|
-
|
|
3358
|
+
visibleIssueCondition(),
|
|
3228
3359
|
sql `${issues.assigneeAgentId} is not null`,
|
|
3229
3360
|
];
|
|
3361
|
+
if (opts?.companyId)
|
|
3362
|
+
filters.push(eq(issues.companyId, opts.companyId));
|
|
3230
3363
|
if (afterIssueId)
|
|
3231
3364
|
filters.push(gt(issues.id, afterIssueId));
|
|
3365
|
+
if (opts?.blockerIssueId) {
|
|
3366
|
+
filters.push(eq(issueRelations.companyId, issues.companyId), eq(issueRelations.type, "blocks"), eq(issueRelations.issueId, opts.blockerIssueId), eq(issueRelations.relatedIssueId, issues.id));
|
|
3367
|
+
return db
|
|
3368
|
+
.select({
|
|
3369
|
+
id: issues.id,
|
|
3370
|
+
companyId: issues.companyId,
|
|
3371
|
+
identifier: issues.identifier,
|
|
3372
|
+
assigneeAgentId: issues.assigneeAgentId,
|
|
3373
|
+
totalCount: sql `count(*) over()::int`,
|
|
3374
|
+
})
|
|
3375
|
+
.from(issueRelations)
|
|
3376
|
+
.innerJoin(issues, eq(issueRelations.relatedIssueId, issues.id))
|
|
3377
|
+
.where(and(...filters))
|
|
3378
|
+
.orderBy(asc(issues.id))
|
|
3379
|
+
.limit(RESOLVED_DEPENDENCY_WAKE_BACKSTOP_CANDIDATE_LIMIT);
|
|
3380
|
+
}
|
|
3232
3381
|
return db
|
|
3233
3382
|
.select({
|
|
3234
3383
|
id: issues.id,
|
|
@@ -3242,8 +3391,8 @@ export function recoveryService(db, deps) {
|
|
|
3242
3391
|
.orderBy(asc(issues.id))
|
|
3243
3392
|
.limit(RESOLVED_DEPENDENCY_WAKE_BACKSTOP_CANDIDATE_LIMIT);
|
|
3244
3393
|
};
|
|
3245
|
-
let candidateRows = await queryCandidates(resolvedDependencyWakeBackstopCandidateCursor);
|
|
3246
|
-
if (candidateRows.length === 0 && resolvedDependencyWakeBackstopCandidateCursor) {
|
|
3394
|
+
let candidateRows = await queryCandidates(useCursor ? resolvedDependencyWakeBackstopCandidateCursor : null);
|
|
3395
|
+
if (useCursor && candidateRows.length === 0 && resolvedDependencyWakeBackstopCandidateCursor) {
|
|
3247
3396
|
resolvedDependencyWakeBackstopCandidateCursor = null;
|
|
3248
3397
|
candidateRows = await queryCandidates(null);
|
|
3249
3398
|
}
|
|
@@ -3252,14 +3401,18 @@ export function recoveryService(db, deps) {
|
|
|
3252
3401
|
result.checked = candidates.length;
|
|
3253
3402
|
result.candidateLimitSkipped = Math.max(0, totalCandidateCount - candidates.length);
|
|
3254
3403
|
const lastCandidate = candidates[candidates.length - 1] ?? null;
|
|
3255
|
-
|
|
3256
|
-
|
|
3404
|
+
if (useCursor) {
|
|
3405
|
+
resolvedDependencyWakeBackstopCandidateCursor =
|
|
3406
|
+
result.candidateLimitSkipped > 0 && lastCandidate ? lastCandidate.id : null;
|
|
3407
|
+
}
|
|
3257
3408
|
if (result.candidateLimitSkipped > 0) {
|
|
3258
3409
|
logger.warn({
|
|
3259
3410
|
processed: candidates.length,
|
|
3260
3411
|
skipped: result.candidateLimitSkipped,
|
|
3261
3412
|
limit: RESOLVED_DEPENDENCY_WAKE_BACKSTOP_CANDIDATE_LIMIT,
|
|
3262
|
-
nextCursor: resolvedDependencyWakeBackstopCandidateCursor,
|
|
3413
|
+
nextCursor: useCursor ? resolvedDependencyWakeBackstopCandidateCursor : null,
|
|
3414
|
+
source,
|
|
3415
|
+
blockerIssueId: opts?.blockerIssueId ?? null,
|
|
3263
3416
|
}, "issue graph liveness backstop deferred resolved dependency wake candidates past page limit");
|
|
3264
3417
|
}
|
|
3265
3418
|
const candidatesByCompany = new Map();
|
|
@@ -3321,16 +3474,16 @@ export function recoveryService(db, deps) {
|
|
|
3321
3474
|
issueId: candidate.id,
|
|
3322
3475
|
resolvedBlockerIssueId,
|
|
3323
3476
|
blockerIssueIds: readiness.blockerIssueIds,
|
|
3324
|
-
backstop:
|
|
3477
|
+
backstop: payloadBackstop,
|
|
3325
3478
|
},
|
|
3326
3479
|
idempotencyKey,
|
|
3327
3480
|
requestedByActorType: "system",
|
|
3328
|
-
requestedByActorId
|
|
3481
|
+
requestedByActorId,
|
|
3329
3482
|
contextSnapshot: {
|
|
3330
3483
|
issueId: candidate.id,
|
|
3331
3484
|
taskId: candidate.id,
|
|
3332
3485
|
wakeReason: ISSUE_BLOCKERS_RESOLVED_WAKE_REASON,
|
|
3333
|
-
source
|
|
3486
|
+
source,
|
|
3334
3487
|
resolvedBlockerIssueId,
|
|
3335
3488
|
blockerIssueIds: readiness.blockerIssueIds,
|
|
3336
3489
|
},
|
|
@@ -3354,7 +3507,7 @@ export function recoveryService(db, deps) {
|
|
|
3354
3507
|
entityType: "issue",
|
|
3355
3508
|
entityId: candidate.id,
|
|
3356
3509
|
details: {
|
|
3357
|
-
source
|
|
3510
|
+
source,
|
|
3358
3511
|
wakeupRunId: wake.id,
|
|
3359
3512
|
idempotencyKey,
|
|
3360
3513
|
resolvedBlockerIssueId,
|
|
@@ -3365,17 +3518,28 @@ export function recoveryService(db, deps) {
|
|
|
3365
3518
|
catch (err) {
|
|
3366
3519
|
result.deferredOrFailed += 1;
|
|
3367
3520
|
result.enqueueFailed += 1;
|
|
3368
|
-
logger.warn({ err, issueId: candidate.id, agentId, idempotencyKey }, "failed to enqueue dependency wake from issue graph liveness backstop");
|
|
3521
|
+
logger.warn({ err, issueId: candidate.id, agentId, idempotencyKey, source }, "failed to enqueue dependency wake from issue graph liveness backstop");
|
|
3369
3522
|
}
|
|
3370
3523
|
}
|
|
3371
3524
|
}
|
|
3372
3525
|
if (result.healed > 0) {
|
|
3373
|
-
logger.warn({ healed: result.healed, issueIds: result.issueIds }, "issue graph liveness backstop healed resolved blocked dependency wakes");
|
|
3526
|
+
logger.warn({ healed: result.healed, issueIds: result.issueIds, source, blockerIssueId: opts?.blockerIssueId ?? null }, "issue graph liveness backstop healed resolved blocked dependency wakes");
|
|
3374
3527
|
}
|
|
3375
3528
|
return result;
|
|
3376
3529
|
}
|
|
3377
3530
|
async function reconcileIssueGraphLiveness(opts) {
|
|
3378
|
-
|
|
3531
|
+
let findings = await collectIssueGraphLivenessFindings();
|
|
3532
|
+
if (opts?.issueCreatedAtGte) {
|
|
3533
|
+
const findingIssueIds = [...new Set(findings.map((finding) => finding.recoveryIssueId))];
|
|
3534
|
+
const eligibleIssueIds = new Set(findingIssueIds.length === 0
|
|
3535
|
+
? []
|
|
3536
|
+
: (await db
|
|
3537
|
+
.select({ id: issues.id })
|
|
3538
|
+
.from(issues)
|
|
3539
|
+
.where(and(inArray(issues.id, findingIssueIds), gte(issues.createdAt, opts.issueCreatedAtGte))))
|
|
3540
|
+
.map((issue) => issue.id));
|
|
3541
|
+
findings = findings.filter((finding) => eligibleIssueIds.has(finding.recoveryIssueId));
|
|
3542
|
+
}
|
|
3379
3543
|
const experimentalSettings = await instanceSettings.getExperimental();
|
|
3380
3544
|
const autoRecoveryEnabled = asBoolean(experimentalSettings.enableIssueGraphLivenessAutoRecovery, true) || opts?.force === true;
|
|
3381
3545
|
const lookbackHours = normalizeIssueGraphLivenessAutoRecoveryLookbackHours(opts?.lookbackHours ?? experimentalSettings.issueGraphLivenessAutoRecoveryLookbackHours);
|
|
@@ -3413,10 +3577,6 @@ export function recoveryService(db, deps) {
|
|
|
3413
3577
|
escalationIssueIds: [],
|
|
3414
3578
|
retiredRecoveryIssueIds: obsoleteRecoveryCleanup.retiredIssueIds,
|
|
3415
3579
|
};
|
|
3416
|
-
if (!autoRecoveryEnabled) {
|
|
3417
|
-
result.skippedAutoRecoveryDisabled = findings.length;
|
|
3418
|
-
return result;
|
|
3419
|
-
}
|
|
3420
3580
|
const dependencyWakeBackstop = await reconcileResolvedDependencyWakeBackstop({
|
|
3421
3581
|
runId: opts?.runId ?? null,
|
|
3422
3582
|
});
|
|
@@ -3431,6 +3591,10 @@ export function recoveryService(db, deps) {
|
|
|
3431
3591
|
result.dependencyWakeDeferredOrFailed = dependencyWakeBackstop.deferredOrFailed;
|
|
3432
3592
|
result.dependencyWakeEnqueueFailed = dependencyWakeBackstop.enqueueFailed;
|
|
3433
3593
|
result.dependencyWakeIssueIds = dependencyWakeBackstop.issueIds;
|
|
3594
|
+
if (!autoRecoveryEnabled) {
|
|
3595
|
+
result.skippedAutoRecoveryDisabled = findings.length;
|
|
3596
|
+
return result;
|
|
3597
|
+
}
|
|
3434
3598
|
for (const finding of findings) {
|
|
3435
3599
|
if (!isLivenessFindingInsideAutoRecoveryLookback(finding, cutoff, updatedAtByIssueKey)) {
|
|
3436
3600
|
result.skippedOutsideLookback += 1;
|
|
@@ -3557,6 +3721,7 @@ export function recoveryService(db, deps) {
|
|
|
3557
3721
|
reconcileStrandedAssignedIssues,
|
|
3558
3722
|
sweepStaleIssueLocks,
|
|
3559
3723
|
buildIssueGraphLivenessAutoRecoveryPreview,
|
|
3724
|
+
reconcileResolvedDependencyWakeBackstop,
|
|
3560
3725
|
reconcileIssueGraphLiveness,
|
|
3561
3726
|
readRecoveryTimerIntervalMs,
|
|
3562
3727
|
};
|