@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import { and, asc, desc, eq, inArray, isNotNull, isNull, lte, not, or, sql } from "drizzle-orm";
|
|
3
|
-
import { agents, companySecretBindings, companySecretVersions, companySecrets, documentRevisions, documents, executionWorkspaces, goals, heartbeatRuns, issueInboxArchives, issueReadStates, issues, pluginManagedResources, plugins, projects, routineRevisions, routineRuns, routineDocuments, routines, routineTriggers, } from "@penclipai/db";
|
|
2
|
+
import { and, asc, desc, eq, gt, inArray, isNotNull, isNull, lte, not, or, sql } from "drizzle-orm";
|
|
3
|
+
import { agents, activityLog, companies, companyMemberships, companySecretBindings, companySecretVersions, companySecrets, documentRevisions, documents, executionWorkspaces, goals, heartbeatRuns, issueInboxArchives, issueReadStates, issues, pluginManagedResources, plugins, projects, routineRevisions, routineRuns, routineDocuments, routines, routineTriggers, } from "@penclipai/db";
|
|
4
4
|
import { WORKSPACE_BRANCH_ROUTINE_VARIABLE, getBuiltinRoutineVariableValues, extractRoutineVariableNames, interpolateRoutineTemplate, isValidRoutineDateString, pluginOperationIssueOriginKind, stringifyRoutineVariableValue, syncRoutineVariablesWithTemplate, } from "@penclipai/shared";
|
|
5
5
|
import { trackRoutineRun } from "@penclipai/shared/telemetry";
|
|
6
6
|
import { conflict, forbidden, notFound, unauthorized, unprocessable } from "../errors.js";
|
|
@@ -9,11 +9,13 @@ import { getTelemetryClient } from "../telemetry.js";
|
|
|
9
9
|
import { getConfiguredSecretProvider } from "../secrets/configured-provider.js";
|
|
10
10
|
import { issueService } from "./issues.js";
|
|
11
11
|
import { assertAssignableAgent } from "./agent-assignability.js";
|
|
12
|
+
import { visibleIssueCondition } from "./issue-visibility.js";
|
|
12
13
|
import { secretService } from "./secrets.js";
|
|
13
14
|
import { getSecretProvider } from "../secrets/provider-registry.js";
|
|
14
15
|
import { parseCron, validateCron } from "./cron.js";
|
|
15
16
|
import { isUniqueViolation } from "./db-errors.js";
|
|
16
17
|
import { heartbeatService } from "./heartbeat.js";
|
|
18
|
+
import { instanceSettingsService, isTruthyRuntimeEnvValue, resolveWorktreeRunExecutionActivationState, } from "./instance-settings.js";
|
|
17
19
|
import { queueIssueAssignmentWakeup } from "./issue-assignment-wakeup.js";
|
|
18
20
|
import { logActivity } from "./activity-log.js";
|
|
19
21
|
const OPEN_ISSUE_STATUSES = ["backlog", "todo", "in_progress", "in_review", "blocked"];
|
|
@@ -21,6 +23,12 @@ const LIVE_HEARTBEAT_RUN_STATUSES = ["queued", "running", "scheduled_retry"];
|
|
|
21
23
|
const TERMINAL_ISSUE_STATUSES = new Set(["done", "cancelled"]);
|
|
22
24
|
const MAX_CATCH_UP_RUNS = 25;
|
|
23
25
|
const MAX_ROUTINE_REVISIONS = 100;
|
|
26
|
+
const ACTIVITY_GATE_IGNORED_ACTIONS = [
|
|
27
|
+
"issue.read_marked",
|
|
28
|
+
"issue.read_unmarked",
|
|
29
|
+
"issue.inbox_archived",
|
|
30
|
+
"issue.inbox_unarchived",
|
|
31
|
+
];
|
|
24
32
|
const WEEKDAY_INDEX = {
|
|
25
33
|
Sun: 0,
|
|
26
34
|
Mon: 1,
|
|
@@ -30,6 +38,39 @@ const WEEKDAY_INDEX = {
|
|
|
30
38
|
Fri: 5,
|
|
31
39
|
Sat: 6,
|
|
32
40
|
};
|
|
41
|
+
async function resolveCompanyDefaultResponsibleUserId(db, companyId) {
|
|
42
|
+
const company = await db
|
|
43
|
+
.select({ defaultResponsibleUserId: companies.defaultResponsibleUserId })
|
|
44
|
+
.from(companies)
|
|
45
|
+
.where(eq(companies.id, companyId))
|
|
46
|
+
.then((rows) => rows[0] ?? null);
|
|
47
|
+
if (company?.defaultResponsibleUserId)
|
|
48
|
+
return company.defaultResponsibleUserId;
|
|
49
|
+
const owner = await db
|
|
50
|
+
.select({ userId: companyMemberships.principalId })
|
|
51
|
+
.from(companyMemberships)
|
|
52
|
+
.where(and(eq(companyMemberships.companyId, companyId), eq(companyMemberships.principalType, "user"), eq(companyMemberships.status, "active"), eq(companyMemberships.membershipRole, "owner")))
|
|
53
|
+
.orderBy(asc(companyMemberships.createdAt), asc(companyMemberships.id))
|
|
54
|
+
.limit(1)
|
|
55
|
+
.then((rows) => rows[0] ?? null);
|
|
56
|
+
return owner?.userId ?? null;
|
|
57
|
+
}
|
|
58
|
+
async function resolveRoutineResponsibleUserId(db, companyId, actorUserId, parentIssueId) {
|
|
59
|
+
if (actorUserId)
|
|
60
|
+
return actorUserId;
|
|
61
|
+
if (parentIssueId) {
|
|
62
|
+
const parent = await db
|
|
63
|
+
.select({ responsibleUserId: issues.responsibleUserId, createdByUserId: issues.createdByUserId })
|
|
64
|
+
.from(issues)
|
|
65
|
+
.where(and(eq(issues.companyId, companyId), eq(issues.id, parentIssueId)))
|
|
66
|
+
.then((rows) => rows[0] ?? null);
|
|
67
|
+
if (parent?.responsibleUserId)
|
|
68
|
+
return parent.responsibleUserId;
|
|
69
|
+
if (parent?.createdByUserId)
|
|
70
|
+
return parent.createdByUserId;
|
|
71
|
+
}
|
|
72
|
+
return resolveCompanyDefaultResponsibleUserId(db, companyId);
|
|
73
|
+
}
|
|
33
74
|
const ROUTINE_DESCRIPTION_DOCUMENT_KEY = "description";
|
|
34
75
|
function routineWebhookSecretConfigPath(secretId) {
|
|
35
76
|
return `webhookSecret:${secretId}`;
|
|
@@ -349,6 +390,7 @@ function routineRevisionSnapshotRoutine(routine) {
|
|
|
349
390
|
catchUpPolicy: routine.catchUpPolicy,
|
|
350
391
|
variables: routine.variables ?? [],
|
|
351
392
|
env: routine.env ?? null,
|
|
393
|
+
responsibleUserId: routine.responsibleUserId ?? null,
|
|
352
394
|
};
|
|
353
395
|
}
|
|
354
396
|
function routineRevisionSnapshotTrigger(trigger) {
|
|
@@ -413,6 +455,8 @@ function mapRoutineDescriptionDocument(row) {
|
|
|
413
455
|
export function routineService(db, deps = {}) {
|
|
414
456
|
const issueSvc = issueService(db);
|
|
415
457
|
const secretsSvc = secretService(db);
|
|
458
|
+
const instanceSettings = instanceSettingsService(db);
|
|
459
|
+
const runtimeEnv = deps.runtimeEnv ?? process.env;
|
|
416
460
|
const heartbeat = deps.heartbeat ?? heartbeatService(db, {
|
|
417
461
|
pluginWorkerManager: deps.pluginWorkerManager,
|
|
418
462
|
});
|
|
@@ -636,6 +680,7 @@ export function routineService(db, deps = {}) {
|
|
|
636
680
|
createdByAgentId: actor.agentId ?? null,
|
|
637
681
|
createdByUserId: actor.userId ?? null,
|
|
638
682
|
createdByRunId: actor.runId ?? null,
|
|
683
|
+
responsibleUserId: snapshot.routine.responsibleUserId ?? null,
|
|
639
684
|
createdAt: now,
|
|
640
685
|
})
|
|
641
686
|
.returning();
|
|
@@ -818,7 +863,7 @@ export function routineService(db, deps = {}) {
|
|
|
818
863
|
})
|
|
819
864
|
.from(issues)
|
|
820
865
|
.innerJoin(heartbeatRuns, and(eq(heartbeatRuns.id, issues.executionRunId), inArray(heartbeatRuns.status, LIVE_HEARTBEAT_RUN_STATUSES)))
|
|
821
|
-
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, "routine_execution"), inArray(issues.originId, routineIds), inArray(issues.status, OPEN_ISSUE_STATUSES),
|
|
866
|
+
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, "routine_execution"), inArray(issues.originId, routineIds), inArray(issues.status, OPEN_ISSUE_STATUSES), visibleIssueCondition()))
|
|
822
867
|
.orderBy(issues.originId, desc(issues.updatedAt), desc(issues.createdAt));
|
|
823
868
|
const rowsByOriginId = new Map();
|
|
824
869
|
for (const row of executionBoundRows) {
|
|
@@ -840,7 +885,7 @@ export function routineService(db, deps = {}) {
|
|
|
840
885
|
})
|
|
841
886
|
.from(issues)
|
|
842
887
|
.innerJoin(heartbeatRuns, and(eq(heartbeatRuns.companyId, issues.companyId), inArray(heartbeatRuns.status, LIVE_HEARTBEAT_RUN_STATUSES), sql `${heartbeatRuns.contextSnapshot} ->> 'issueId' = cast(${issues.id} as text)`))
|
|
843
|
-
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, "routine_execution"), inArray(issues.originId, missingRoutineIds), inArray(issues.status, OPEN_ISSUE_STATUSES),
|
|
888
|
+
.where(and(eq(issues.companyId, companyId), eq(issues.originKind, "routine_execution"), inArray(issues.originId, missingRoutineIds), inArray(issues.status, OPEN_ISSUE_STATUSES), visibleIssueCondition()))
|
|
844
889
|
.orderBy(issues.originId, desc(issues.updatedAt), desc(issues.createdAt));
|
|
845
890
|
for (const row of legacyRows) {
|
|
846
891
|
if (!row.originId)
|
|
@@ -884,10 +929,113 @@ export function routineService(db, deps = {}) {
|
|
|
884
929
|
.where(eq(routineTriggers.id, input.triggerId));
|
|
885
930
|
}
|
|
886
931
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
932
|
+
async function getAutomaticRoutineDispatchEligibility(routine, activation) {
|
|
933
|
+
if (!isTruthyRuntimeEnvValue(runtimeEnv.PAPERCLIP_IN_WORKTREE))
|
|
934
|
+
return { eligible: true };
|
|
935
|
+
const resolvedActivation = activation ?? await resolveWorktreeRunExecutionActivationState({
|
|
936
|
+
getExperimental: instanceSettings.getExperimental,
|
|
937
|
+
runtimeEnv,
|
|
938
|
+
});
|
|
939
|
+
if (!resolvedActivation.armed)
|
|
940
|
+
return { eligible: false };
|
|
941
|
+
const cutoff = new Date(resolvedActivation.cutoff);
|
|
942
|
+
if (Number.isNaN(cutoff.getTime()) || routine.createdAt < cutoff)
|
|
943
|
+
return { eligible: false };
|
|
944
|
+
return { eligible: true };
|
|
945
|
+
}
|
|
946
|
+
async function evaluateActivityGate(routine, now) {
|
|
947
|
+
const lastDispatchedRun = await db
|
|
948
|
+
.select({ triggeredAt: routineRuns.triggeredAt })
|
|
949
|
+
.from(routineRuns)
|
|
950
|
+
.where(and(eq(routineRuns.companyId, routine.companyId), eq(routineRuns.routineId, routine.id), sql `${routineRuns.status} not in ('skipped', 'coalesced')`))
|
|
951
|
+
.orderBy(desc(routineRuns.triggeredAt), desc(routineRuns.id))
|
|
952
|
+
.limit(1)
|
|
953
|
+
.then((rows) => rows[0] ?? null);
|
|
954
|
+
if (!lastDispatchedRun) {
|
|
955
|
+
return { fire: true, windowStart: null, matchedActivity: null };
|
|
956
|
+
}
|
|
957
|
+
const projectScopeCondition = routine.activityGateScope === "project"
|
|
958
|
+
? routine.projectId
|
|
959
|
+
? sql `(
|
|
960
|
+
(${activityLog.entityType} = 'project' and ${activityLog.entityId} = ${routine.projectId})
|
|
961
|
+
or (${activityLog.details} ->> 'projectId') = ${routine.projectId}
|
|
962
|
+
or exists (
|
|
963
|
+
select 1
|
|
964
|
+
from ${issues} activity_issue
|
|
965
|
+
where activity_issue.company_id = ${routine.companyId}
|
|
966
|
+
and activity_issue.project_id = ${routine.projectId}
|
|
967
|
+
and activity_issue.id::text = ${activityLog.entityId}
|
|
968
|
+
and ${activityLog.entityType} = 'issue'
|
|
969
|
+
)
|
|
970
|
+
or exists (
|
|
971
|
+
select 1
|
|
972
|
+
from ${heartbeatRuns} activity_run
|
|
973
|
+
inner join ${issues} run_issue
|
|
974
|
+
on run_issue.company_id = ${routine.companyId}
|
|
975
|
+
and run_issue.id::text = activity_run.context_snapshot ->> 'issueId'
|
|
976
|
+
where activity_run.company_id = ${routine.companyId}
|
|
977
|
+
and activity_run.id = ${activityLog.runId}
|
|
978
|
+
and run_issue.project_id = ${routine.projectId}
|
|
979
|
+
)
|
|
980
|
+
or exists (
|
|
981
|
+
select 1
|
|
982
|
+
from ${routines} activity_routine
|
|
983
|
+
where activity_routine.company_id = ${routine.companyId}
|
|
984
|
+
and activity_routine.project_id = ${routine.projectId}
|
|
985
|
+
and activity_routine.id::text = ${activityLog.entityId}
|
|
986
|
+
and ${activityLog.entityType} = 'routine'
|
|
987
|
+
)
|
|
988
|
+
or exists (
|
|
989
|
+
select 1
|
|
990
|
+
from ${routineRuns} activity_routine_run
|
|
991
|
+
inner join ${routines} activity_routine
|
|
992
|
+
on activity_routine.company_id = ${routine.companyId}
|
|
993
|
+
and activity_routine.id = activity_routine_run.routine_id
|
|
994
|
+
where activity_routine_run.company_id = ${routine.companyId}
|
|
995
|
+
and activity_routine_run.id::text = ${activityLog.entityId}
|
|
996
|
+
and activity_routine.project_id = ${routine.projectId}
|
|
997
|
+
and ${activityLog.entityType} = 'routine_run'
|
|
998
|
+
)
|
|
999
|
+
)`
|
|
1000
|
+
: sql `false`
|
|
1001
|
+
: undefined;
|
|
1002
|
+
const matchedActivity = await db
|
|
1003
|
+
.select({
|
|
1004
|
+
id: activityLog.id,
|
|
1005
|
+
action: activityLog.action,
|
|
1006
|
+
createdAt: activityLog.createdAt,
|
|
1007
|
+
})
|
|
1008
|
+
.from(activityLog)
|
|
1009
|
+
.where(and(eq(activityLog.companyId, routine.companyId), gt(activityLog.createdAt, lastDispatchedRun.triggeredAt), lte(activityLog.createdAt, now), sql `${activityLog.action} not in (${sql.join(ACTIVITY_GATE_IGNORED_ACTIONS.map((action) => sql `${action}`), sql `, `)})`, sql `not (
|
|
1010
|
+
${activityLog.actorId} = 'routine-scheduler'
|
|
1011
|
+
and (
|
|
1012
|
+
(${activityLog.details} ->> 'routineId') = ${routine.id}
|
|
1013
|
+
or (${activityLog.entityType} = 'routine' and ${activityLog.entityId} = ${routine.id})
|
|
1014
|
+
)
|
|
1015
|
+
)`, sql `not exists (
|
|
1016
|
+
select 1
|
|
1017
|
+
from ${heartbeatRuns} own_run
|
|
1018
|
+
inner join ${issues} own_issue
|
|
1019
|
+
on own_issue.company_id = ${routine.companyId}
|
|
1020
|
+
and own_issue.id::text = own_run.context_snapshot ->> 'issueId'
|
|
1021
|
+
where own_run.company_id = ${routine.companyId}
|
|
1022
|
+
and own_run.id = ${activityLog.runId}
|
|
1023
|
+
and own_issue.origin_kind = 'routine_execution'
|
|
1024
|
+
and own_issue.origin_id = ${routine.id}
|
|
1025
|
+
)`, projectScopeCondition))
|
|
1026
|
+
.orderBy(asc(activityLog.createdAt), asc(activityLog.id))
|
|
1027
|
+
.limit(1)
|
|
1028
|
+
.then((rows) => rows[0] ?? null);
|
|
1029
|
+
return {
|
|
1030
|
+
fire: matchedActivity !== null,
|
|
1031
|
+
windowStart: lastDispatchedRun.triggeredAt,
|
|
1032
|
+
matchedActivity,
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
// Records an automatic firing that was claimed but intentionally not dispatched. The
|
|
1036
|
+
// scheduler advances its tick before calling this helper, so suppressed work is never
|
|
1037
|
+
// replayed after a setting or project state changes.
|
|
1038
|
+
async function recordSuppressedAutomaticRun(input) {
|
|
891
1039
|
const triggeredAt = new Date();
|
|
892
1040
|
const run = await db.transaction(async (tx) => {
|
|
893
1041
|
const txDb = tx;
|
|
@@ -897,20 +1045,26 @@ export function routineService(db, deps = {}) {
|
|
|
897
1045
|
companyId: input.routine.companyId,
|
|
898
1046
|
routineId: input.routine.id,
|
|
899
1047
|
triggerId: input.trigger.id,
|
|
900
|
-
source:
|
|
1048
|
+
source: input.source,
|
|
901
1049
|
status: "skipped",
|
|
902
1050
|
triggeredAt,
|
|
903
1051
|
failureReason: input.reason,
|
|
904
1052
|
completedAt: triggeredAt,
|
|
905
1053
|
linkedIssueId: null,
|
|
906
1054
|
routineRevisionId: input.routine.latestRevisionId,
|
|
1055
|
+
responsibleUserId: input.routine.responsibleUserId ?? null,
|
|
1056
|
+
triggerPayload: input.details ?? null,
|
|
907
1057
|
})
|
|
908
1058
|
.returning();
|
|
909
1059
|
await updateRoutineTouchedState({
|
|
910
1060
|
routineId: input.routine.id,
|
|
911
1061
|
triggerId: input.trigger.id,
|
|
912
1062
|
triggeredAt,
|
|
913
|
-
status: "
|
|
1063
|
+
status: input.reason === "paused"
|
|
1064
|
+
? "skipped_paused"
|
|
1065
|
+
: input.reason === "no_external_activity"
|
|
1066
|
+
? "skipped_no_activity"
|
|
1067
|
+
: "skipped_worktree_execution_cutoff",
|
|
914
1068
|
nextRunAt: input.nextRunAt,
|
|
915
1069
|
}, txDb);
|
|
916
1070
|
return createdRun;
|
|
@@ -919,16 +1073,17 @@ export function routineService(db, deps = {}) {
|
|
|
919
1073
|
await logActivity(db, {
|
|
920
1074
|
companyId: input.routine.companyId,
|
|
921
1075
|
actorType: "system",
|
|
922
|
-
actorId: "routine-scheduler",
|
|
1076
|
+
actorId: input.source === "schedule" ? "routine-scheduler" : "routine-webhook",
|
|
923
1077
|
action: "routine.run_skipped",
|
|
924
1078
|
entityType: "routine_run",
|
|
925
1079
|
entityId: run.id,
|
|
926
1080
|
details: {
|
|
927
1081
|
routineId: input.routine.id,
|
|
928
1082
|
triggerId: input.trigger.id,
|
|
929
|
-
source:
|
|
1083
|
+
source: input.source,
|
|
930
1084
|
status: "skipped",
|
|
931
1085
|
reason: input.reason,
|
|
1086
|
+
...(input.details ?? {}),
|
|
932
1087
|
},
|
|
933
1088
|
});
|
|
934
1089
|
}
|
|
@@ -952,7 +1107,7 @@ export function routineService(db, deps = {}) {
|
|
|
952
1107
|
.select()
|
|
953
1108
|
.from(issues)
|
|
954
1109
|
.innerJoin(heartbeatRuns, and(eq(heartbeatRuns.id, issues.executionRunId), inArray(heartbeatRuns.status, LIVE_HEARTBEAT_RUN_STATUSES)))
|
|
955
|
-
.where(and(eq(issues.companyId, routine.companyId), eq(issues.originKind, originKind), eq(issues.originId, originId), inArray(issues.status, OPEN_ISSUE_STATUSES),
|
|
1110
|
+
.where(and(eq(issues.companyId, routine.companyId), eq(issues.originKind, originKind), eq(issues.originId, originId), inArray(issues.status, OPEN_ISSUE_STATUSES), visibleIssueCondition(), ...(fingerprintCondition ? [fingerprintCondition] : [])))
|
|
956
1111
|
.orderBy(desc(issues.updatedAt), desc(issues.createdAt))
|
|
957
1112
|
.limit(1)
|
|
958
1113
|
.then((rows) => rows[0]?.issues ?? null);
|
|
@@ -962,7 +1117,7 @@ export function routineService(db, deps = {}) {
|
|
|
962
1117
|
.select()
|
|
963
1118
|
.from(issues)
|
|
964
1119
|
.innerJoin(heartbeatRuns, and(eq(heartbeatRuns.companyId, issues.companyId), inArray(heartbeatRuns.status, LIVE_HEARTBEAT_RUN_STATUSES), sql `${heartbeatRuns.contextSnapshot} ->> 'issueId' = cast(${issues.id} as text)`))
|
|
965
|
-
.where(and(eq(issues.companyId, routine.companyId), eq(issues.originKind, originKind), eq(issues.originId, originId), inArray(issues.status, OPEN_ISSUE_STATUSES),
|
|
1120
|
+
.where(and(eq(issues.companyId, routine.companyId), eq(issues.originKind, originKind), eq(issues.originId, originId), inArray(issues.status, OPEN_ISSUE_STATUSES), visibleIssueCondition(), ...(fingerprintCondition ? [fingerprintCondition] : [])))
|
|
966
1121
|
.orderBy(desc(issues.updatedAt), desc(issues.createdAt))
|
|
967
1122
|
.limit(1)
|
|
968
1123
|
.then((rows) => rows[0]?.issues ?? null);
|
|
@@ -1153,6 +1308,21 @@ export function routineService(db, deps = {}) {
|
|
|
1153
1308
|
}
|
|
1154
1309
|
const triggeredAt = new Date();
|
|
1155
1310
|
const manualRunnerUserId = input.source === "manual" ? input.actor?.userId ?? null : null;
|
|
1311
|
+
const latestRevisionResponsibleUserId = input.routine.latestRevisionId
|
|
1312
|
+
? await txDb
|
|
1313
|
+
.select({
|
|
1314
|
+
responsibleUserId: routineRevisions.responsibleUserId,
|
|
1315
|
+
snapshot: routineRevisions.snapshot,
|
|
1316
|
+
})
|
|
1317
|
+
.from(routineRevisions)
|
|
1318
|
+
.where(and(eq(routineRevisions.companyId, input.routine.companyId), eq(routineRevisions.routineId, input.routine.id), eq(routineRevisions.id, input.routine.latestRevisionId)))
|
|
1319
|
+
.then((rows) => {
|
|
1320
|
+
const row = rows[0] ?? null;
|
|
1321
|
+
const snapshot = row?.snapshot;
|
|
1322
|
+
return row?.responsibleUserId ?? snapshot?.routine.responsibleUserId ?? null;
|
|
1323
|
+
})
|
|
1324
|
+
: null;
|
|
1325
|
+
const responsibleUserId = manualRunnerUserId ?? latestRevisionResponsibleUserId ?? input.routine.responsibleUserId ?? null;
|
|
1156
1326
|
const [createdRun] = await txDb
|
|
1157
1327
|
.insert(routineRuns)
|
|
1158
1328
|
.values({
|
|
@@ -1166,6 +1336,7 @@ export function routineService(db, deps = {}) {
|
|
|
1166
1336
|
triggerPayload,
|
|
1167
1337
|
dispatchFingerprint,
|
|
1168
1338
|
routineRevisionId: input.routine.latestRevisionId,
|
|
1339
|
+
responsibleUserId,
|
|
1169
1340
|
})
|
|
1170
1341
|
.returning();
|
|
1171
1342
|
const nextRunAt = input.trigger?.kind === "schedule" && input.trigger.cronExpression && input.trigger.timezone
|
|
@@ -1216,6 +1387,8 @@ export function routineService(db, deps = {}) {
|
|
|
1216
1387
|
assigneeAgentId,
|
|
1217
1388
|
createdByAgentId: input.source === "manual" ? input.actor?.agentId ?? null : null,
|
|
1218
1389
|
createdByUserId: manualRunnerUserId,
|
|
1390
|
+
responsibleUserId,
|
|
1391
|
+
trustExplicitResponsibleUserId: true,
|
|
1219
1392
|
originKind: issueOriginKind,
|
|
1220
1393
|
originId: issueOriginId,
|
|
1221
1394
|
originRunId: createdRun.id,
|
|
@@ -1339,6 +1512,7 @@ export function routineService(db, deps = {}) {
|
|
|
1339
1512
|
return run;
|
|
1340
1513
|
}
|
|
1341
1514
|
return {
|
|
1515
|
+
evaluateActivityGate,
|
|
1342
1516
|
get: getRoutineById,
|
|
1343
1517
|
getTrigger: getTriggerById,
|
|
1344
1518
|
list: async (companyId, filters) => {
|
|
@@ -1490,6 +1664,10 @@ export function routineService(db, deps = {}) {
|
|
|
1490
1664
|
const variables = syncRoutineVariablesWithTemplate([input.title, input.description], sanitizeRoutineVariableInputs(input.variables));
|
|
1491
1665
|
assertRoutineVariableDefinitions(variables);
|
|
1492
1666
|
const status = normalizeDraftRoutineStatus(input.status, input.assigneeAgentId);
|
|
1667
|
+
const responsibleUserId = await resolveRoutineResponsibleUserId(db, companyId, actor.userId, input.parentIssueId ?? null);
|
|
1668
|
+
if (!responsibleUserId) {
|
|
1669
|
+
throw unprocessable("Routine requires a responsible user");
|
|
1670
|
+
}
|
|
1493
1671
|
const createdRoutine = await db.transaction(async (tx) => {
|
|
1494
1672
|
const txDb = tx;
|
|
1495
1673
|
const [created] = await txDb
|
|
@@ -1508,6 +1686,7 @@ export function routineService(db, deps = {}) {
|
|
|
1508
1686
|
catchUpPolicy: input.catchUpPolicy,
|
|
1509
1687
|
variables,
|
|
1510
1688
|
env,
|
|
1689
|
+
responsibleUserId,
|
|
1511
1690
|
createdByAgentId: actor.agentId ?? null,
|
|
1512
1691
|
createdByUserId: actor.userId ?? null,
|
|
1513
1692
|
updatedByAgentId: actor.agentId ?? null,
|
|
@@ -1567,6 +1746,10 @@ export function routineService(db, deps = {}) {
|
|
|
1567
1746
|
if (enabledScheduleTriggers) {
|
|
1568
1747
|
assertScheduleCompatibleVariables(nextVariables);
|
|
1569
1748
|
}
|
|
1749
|
+
const responsibleUserId = await resolveRoutineResponsibleUserId(db, existing.companyId, actor.userId, patch.parentIssueId === undefined ? existing.parentIssueId : patch.parentIssueId);
|
|
1750
|
+
if (!responsibleUserId) {
|
|
1751
|
+
throw unprocessable("Routine requires a responsible user");
|
|
1752
|
+
}
|
|
1570
1753
|
const updatedRoutine = await db.transaction(async (tx) => {
|
|
1571
1754
|
const txDb = tx;
|
|
1572
1755
|
await tx.execute(sql `select id from ${routines} where ${routines.id} = ${id} for update`);
|
|
@@ -1596,6 +1779,7 @@ export function routineService(db, deps = {}) {
|
|
|
1596
1779
|
catchUpPolicy: patch.catchUpPolicy ?? locked.catchUpPolicy,
|
|
1597
1780
|
variables: nextVariables,
|
|
1598
1781
|
env: nextEnv,
|
|
1782
|
+
responsibleUserId: locked.responsibleUserId ?? responsibleUserId,
|
|
1599
1783
|
updatedByAgentId: actor.agentId ?? null,
|
|
1600
1784
|
updatedByUserId: actor.userId ?? null,
|
|
1601
1785
|
};
|
|
@@ -1631,6 +1815,7 @@ export function routineService(db, deps = {}) {
|
|
|
1631
1815
|
catchUpPolicy: candidate.catchUpPolicy,
|
|
1632
1816
|
variables: candidate.variables,
|
|
1633
1817
|
env: candidate.env,
|
|
1818
|
+
responsibleUserId: candidate.responsibleUserId,
|
|
1634
1819
|
updatedByAgentId: actor.agentId ?? null,
|
|
1635
1820
|
updatedByUserId: actor.userId ?? null,
|
|
1636
1821
|
updatedAt: new Date(),
|
|
@@ -2135,6 +2320,15 @@ export function routineService(db, deps = {}) {
|
|
|
2135
2320
|
if (!valid)
|
|
2136
2321
|
throw unauthorized();
|
|
2137
2322
|
}
|
|
2323
|
+
const eligibility = await getAutomaticRoutineDispatchEligibility(routine);
|
|
2324
|
+
if (!eligibility.eligible) {
|
|
2325
|
+
return recordSuppressedAutomaticRun({
|
|
2326
|
+
routine,
|
|
2327
|
+
trigger,
|
|
2328
|
+
source: "webhook",
|
|
2329
|
+
reason: "worktree_execution_cutoff",
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2138
2332
|
return dispatchRoutineRun({
|
|
2139
2333
|
routine,
|
|
2140
2334
|
trigger,
|
|
@@ -2219,6 +2413,12 @@ export function routineService(db, deps = {}) {
|
|
|
2219
2413
|
}));
|
|
2220
2414
|
},
|
|
2221
2415
|
tickScheduledTriggers: async (now = new Date()) => {
|
|
2416
|
+
const worktreeActivation = isTruthyRuntimeEnvValue(runtimeEnv.PAPERCLIP_IN_WORKTREE)
|
|
2417
|
+
? await resolveWorktreeRunExecutionActivationState({
|
|
2418
|
+
getExperimental: instanceSettings.getExperimental,
|
|
2419
|
+
runtimeEnv,
|
|
2420
|
+
})
|
|
2421
|
+
: undefined;
|
|
2222
2422
|
const due = await db
|
|
2223
2423
|
.select({
|
|
2224
2424
|
trigger: routineTriggers,
|
|
@@ -2239,9 +2439,11 @@ export function routineService(db, deps = {}) {
|
|
|
2239
2439
|
// at the next cron boundary instead of replaying missed firings. Routines with no
|
|
2240
2440
|
// project are never suppressed here.
|
|
2241
2441
|
const projectPaused = !!(row.routine.projectId && row.projectPausedAt);
|
|
2442
|
+
const automaticEligibility = await getAutomaticRoutineDispatchEligibility(row.routine, worktreeActivation);
|
|
2443
|
+
const worktreeSuppressed = !automaticEligibility.eligible;
|
|
2242
2444
|
let runCount = 1;
|
|
2243
2445
|
let claimedNextRunAt = nextCronTickInTimeZone(row.trigger.cronExpression, row.trigger.timezone, now);
|
|
2244
|
-
if (!projectPaused && row.routine.catchUpPolicy === "enqueue_missed_with_cap") {
|
|
2446
|
+
if (!projectPaused && !worktreeSuppressed && row.routine.catchUpPolicy === "enqueue_missed_with_cap") {
|
|
2245
2447
|
let cursor = row.trigger.nextRunAt;
|
|
2246
2448
|
runCount = 0;
|
|
2247
2449
|
while (cursor && cursor <= now && runCount < MAX_CATCH_UP_RUNS) {
|
|
@@ -2261,15 +2463,36 @@ export function routineService(db, deps = {}) {
|
|
|
2261
2463
|
.then((rows) => rows[0] ?? null);
|
|
2262
2464
|
if (!claimed)
|
|
2263
2465
|
continue;
|
|
2264
|
-
if (projectPaused) {
|
|
2265
|
-
await
|
|
2466
|
+
if (projectPaused || worktreeSuppressed) {
|
|
2467
|
+
await recordSuppressedAutomaticRun({
|
|
2266
2468
|
routine: row.routine,
|
|
2267
2469
|
trigger: row.trigger,
|
|
2268
|
-
|
|
2470
|
+
source: "schedule",
|
|
2471
|
+
reason: worktreeSuppressed ? "worktree_execution_cutoff" : "paused",
|
|
2269
2472
|
nextRunAt: claimedNextRunAt,
|
|
2270
2473
|
});
|
|
2271
2474
|
continue;
|
|
2272
2475
|
}
|
|
2476
|
+
const activityGate = row.routine.activityGatePolicy === "require_external_activity"
|
|
2477
|
+
? await evaluateActivityGate(row.routine, now)
|
|
2478
|
+
: null;
|
|
2479
|
+
if (activityGate && !activityGate.fire) {
|
|
2480
|
+
await recordSuppressedAutomaticRun({
|
|
2481
|
+
routine: row.routine,
|
|
2482
|
+
trigger: row.trigger,
|
|
2483
|
+
source: "schedule",
|
|
2484
|
+
reason: "no_external_activity",
|
|
2485
|
+
nextRunAt: claimedNextRunAt,
|
|
2486
|
+
details: {
|
|
2487
|
+
activityGate: {
|
|
2488
|
+
verdict: "quiet",
|
|
2489
|
+
windowStart: activityGate.windowStart?.toISOString() ?? null,
|
|
2490
|
+
matchedActivityId: null,
|
|
2491
|
+
},
|
|
2492
|
+
},
|
|
2493
|
+
});
|
|
2494
|
+
continue;
|
|
2495
|
+
}
|
|
2273
2496
|
for (let i = 0; i < runCount; i += 1) {
|
|
2274
2497
|
await dispatchRoutineRun({
|
|
2275
2498
|
routine: row.routine,
|