@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,22 +1,21 @@
|
|
|
1
1
|
import { Router } from "express";
|
|
2
|
-
import { catalogSkillListQuerySchema, companySkillCommentCreateSchema, companySkillCommentUpdateSchema, companySkillCreateSchema, companySkillFileUpdateSchema, companySkillForkSchema, companySkillImportSchema, companySkillInstallCatalogSchema, companySkillInstallUpdateSchema, companySkillListQuerySchema, companySkillProjectScanRequestSchema, companySkillResetSchema, companySkillUpdateSchema, companySkillVersionCreateSchema, } from "@penclipai/shared";
|
|
2
|
+
import { catalogSkillListQuerySchema, companySkillCommentCreateSchema, companySkillCommentUpdateSchema, companySkillCreateSchema, companySkillFileDeleteSchema, companySkillFileUpdateSchema, companySkillForkSchema, companySkillImportSchema, companySkillInstallCatalogSchema, companySkillInstallUpdateSchema, companySkillListQuerySchema, companySkillProjectScanRequestSchema, companySkillResetSchema, companySkillTestInputCreateSchema, companySkillTestInputUpdateSchema, companySkillTestRunTemplateCreateSchema, companySkillTestRunTemplateUpdateSchema, companySkillTestRunCreateSchema, companySkillTestRunListQuerySchema, companySkillUpdateSchema, companySkillVersionCreateSchema, } from "@penclipai/shared";
|
|
3
3
|
import { trackSkillImported } from "@penclipai/shared/telemetry";
|
|
4
4
|
import { validate } from "../middleware/validate.js";
|
|
5
|
-
import { accessService, agentService, companySkillService, logActivity } from "../services/index.js";
|
|
5
|
+
import { accessService, agentService, companySkillService, heartbeatService, issueService, logActivity } from "../services/index.js";
|
|
6
6
|
import { getCatalogSkillOrThrow, listCatalogSkillsOrEmpty, readCatalogSkillFile, } from "../services/skills-catalog.js";
|
|
7
|
-
import { forbidden } from "../errors.js";
|
|
7
|
+
import { forbidden, HttpError } from "../errors.js";
|
|
8
8
|
import { assertAuthenticated, assertCompanyAccess, getActorInfo } from "./authz.js";
|
|
9
9
|
import { getTelemetryClient } from "../telemetry.js";
|
|
10
|
+
import { authorizationDeniedDetails } from "../services/authorization.js";
|
|
11
|
+
import { changeConsentGateService, skillChangeTargetKey, skillImportChangeTargetKey, skillSlugChangeTargetKey, skillsScanProjectsChangeTargetKey, } from "../services/change-consent-gate.js";
|
|
10
12
|
export function companySkillRoutes(db) {
|
|
11
13
|
const router = Router();
|
|
12
14
|
const agents = agentService(db);
|
|
13
15
|
const access = accessService(db);
|
|
14
16
|
const svc = companySkillService(db);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return true;
|
|
18
|
-
return agent.permissions.canCreateSkills !== false;
|
|
19
|
-
}
|
|
17
|
+
const issues = issueService(db);
|
|
18
|
+
const heartbeat = heartbeatService(db);
|
|
20
19
|
function asString(value) {
|
|
21
20
|
if (typeof value !== "string")
|
|
22
21
|
return null;
|
|
@@ -59,14 +58,70 @@ export function companySkillRoutes(db) {
|
|
|
59
58
|
}
|
|
60
59
|
return { type: "system" };
|
|
61
60
|
}
|
|
62
|
-
|
|
61
|
+
function skillMutationTargets(input) {
|
|
62
|
+
const targetKeys = [];
|
|
63
|
+
const skillId = asString(input.skillId);
|
|
64
|
+
const slug = asString(input.slug);
|
|
65
|
+
const source = asString(input.source);
|
|
66
|
+
const catalogSkillId = asString(input.catalogSkillId);
|
|
67
|
+
if (skillId)
|
|
68
|
+
targetKeys.push(skillChangeTargetKey(skillId));
|
|
69
|
+
if (slug)
|
|
70
|
+
targetKeys.push(skillSlugChangeTargetKey(slug));
|
|
71
|
+
if (source)
|
|
72
|
+
targetKeys.push(skillImportChangeTargetKey(source));
|
|
73
|
+
if (catalogSkillId)
|
|
74
|
+
targetKeys.push(skillImportChangeTargetKey(catalogSkillId));
|
|
75
|
+
if (input.scanProjects)
|
|
76
|
+
targetKeys.push(skillsScanProjectsChangeTargetKey());
|
|
77
|
+
return targetKeys;
|
|
78
|
+
}
|
|
79
|
+
async function assertCanMutateCompanySkills(req, companyId, targetKeys = []) {
|
|
80
|
+
assertCompanyAccess(req, companyId);
|
|
81
|
+
const decision = await access.decide({
|
|
82
|
+
actor: req.actor,
|
|
83
|
+
action: "skill_config:update",
|
|
84
|
+
resource: { type: "company", companyId },
|
|
85
|
+
});
|
|
86
|
+
if (decision.allowed) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (decision.reason === "deny_missing_consent" && req.actor.type === "agent" && targetKeys.length > 0) {
|
|
90
|
+
try {
|
|
91
|
+
await changeConsentGateService(db).assertConsented({
|
|
92
|
+
companyId,
|
|
93
|
+
actorAgentId: req.actor.agentId,
|
|
94
|
+
actorRunId: req.actor.runId ?? null,
|
|
95
|
+
targetKeys,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
if (err instanceof HttpError && err.status === 403) {
|
|
100
|
+
throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
const consentedDecision = await access.decide({
|
|
105
|
+
actor: req.actor,
|
|
106
|
+
action: "skill_config:update",
|
|
107
|
+
resource: { type: "company", companyId },
|
|
108
|
+
scope: { consentedChange: true },
|
|
109
|
+
});
|
|
110
|
+
if (consentedDecision.allowed) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
throw forbidden(consentedDecision.explanation, { reason: consentedDecision.reason });
|
|
114
|
+
}
|
|
115
|
+
throw forbidden(decision.explanation, { reason: decision.reason });
|
|
116
|
+
}
|
|
117
|
+
async function assertCanStartSkillTestRuns(req, companyId) {
|
|
63
118
|
assertCompanyAccess(req, companyId);
|
|
64
119
|
if (req.actor.type === "board") {
|
|
65
120
|
if (req.actor.source === "local_implicit" || req.actor.isInstanceAdmin)
|
|
66
121
|
return;
|
|
67
|
-
const allowed = await access.canUser(companyId, req.actor.userId, "
|
|
122
|
+
const allowed = await access.canUser(companyId, req.actor.userId, "tasks:assign");
|
|
68
123
|
if (!allowed) {
|
|
69
|
-
throw forbidden("Missing permission:
|
|
124
|
+
throw forbidden("Missing permission: tasks:assign");
|
|
70
125
|
}
|
|
71
126
|
return;
|
|
72
127
|
}
|
|
@@ -77,14 +132,10 @@ export function companySkillRoutes(db) {
|
|
|
77
132
|
if (!actorAgent || actorAgent.companyId !== companyId) {
|
|
78
133
|
throw forbidden("Agent key cannot access another company");
|
|
79
134
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "skills:create");
|
|
84
|
-
if (allowedByGrant) {
|
|
85
|
-
return;
|
|
135
|
+
const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "tasks:assign");
|
|
136
|
+
if (!allowedByGrant) {
|
|
137
|
+
throw forbidden("Missing permission: tasks:assign");
|
|
86
138
|
}
|
|
87
|
-
throw forbidden("Missing permission: skills:create");
|
|
88
139
|
}
|
|
89
140
|
router.get("/skills/catalog", async (req, res) => {
|
|
90
141
|
assertAuthenticated(req);
|
|
@@ -118,6 +169,10 @@ export function companySkillRoutes(db) {
|
|
|
118
169
|
...queryStringArray(req.query["categories[]"]),
|
|
119
170
|
],
|
|
120
171
|
scope: firstQueryString(req.query.scope),
|
|
172
|
+
include: [
|
|
173
|
+
...queryStringArray(req.query.include),
|
|
174
|
+
...queryStringArray(req.query["include[]"]),
|
|
175
|
+
],
|
|
121
176
|
}));
|
|
122
177
|
res.json(result);
|
|
123
178
|
});
|
|
@@ -137,6 +192,17 @@ export function companySkillRoutes(db) {
|
|
|
137
192
|
}
|
|
138
193
|
res.json(result);
|
|
139
194
|
});
|
|
195
|
+
router.get("/companies/:companyId/skills/:skillId/fork-precheck", async (req, res) => {
|
|
196
|
+
const companyId = req.params.companyId;
|
|
197
|
+
const skillId = req.params.skillId;
|
|
198
|
+
assertCompanyAccess(req, companyId);
|
|
199
|
+
const result = await svc.forkPrecheck(companyId, skillId, skillActor(req));
|
|
200
|
+
if (!result) {
|
|
201
|
+
res.status(404).json({ error: "Skill not found" });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
res.json(result);
|
|
205
|
+
});
|
|
140
206
|
router.get("/companies/:companyId/skills/:skillId/versions", async (req, res) => {
|
|
141
207
|
const companyId = req.params.companyId;
|
|
142
208
|
const skillId = req.params.skillId;
|
|
@@ -155,10 +221,332 @@ export function companySkillRoutes(db) {
|
|
|
155
221
|
}
|
|
156
222
|
res.json(result);
|
|
157
223
|
});
|
|
158
|
-
router.
|
|
224
|
+
router.get("/companies/:companyId/skills/:skillId/test-inputs", async (req, res) => {
|
|
225
|
+
const companyId = req.params.companyId;
|
|
226
|
+
const skillId = req.params.skillId;
|
|
227
|
+
assertCompanyAccess(req, companyId);
|
|
228
|
+
res.json(await svc.listTestInputs(companyId, skillId));
|
|
229
|
+
});
|
|
230
|
+
router.post("/companies/:companyId/skills/:skillId/test-inputs", validate(companySkillTestInputCreateSchema), async (req, res) => {
|
|
231
|
+
const companyId = req.params.companyId;
|
|
232
|
+
const skillId = req.params.skillId;
|
|
233
|
+
await assertCanMutateCompanySkills(req, companyId);
|
|
234
|
+
const result = await svc.createTestInput(companyId, skillId, req.body, skillActor(req));
|
|
235
|
+
const actor = getActorInfo(req);
|
|
236
|
+
await logActivity(db, {
|
|
237
|
+
companyId,
|
|
238
|
+
actorType: actor.actorType,
|
|
239
|
+
actorId: actor.actorId,
|
|
240
|
+
agentId: actor.agentId,
|
|
241
|
+
runId: actor.runId,
|
|
242
|
+
action: "company.skill_test_input_created",
|
|
243
|
+
entityType: "company_skill_test_input",
|
|
244
|
+
entityId: result.id,
|
|
245
|
+
details: { skillId, name: result.name },
|
|
246
|
+
});
|
|
247
|
+
res.status(201).json(result);
|
|
248
|
+
});
|
|
249
|
+
router.patch("/companies/:companyId/skills/:skillId/test-inputs/:inputId", validate(companySkillTestInputUpdateSchema), async (req, res) => {
|
|
159
250
|
const companyId = req.params.companyId;
|
|
160
251
|
const skillId = req.params.skillId;
|
|
252
|
+
const inputId = req.params.inputId;
|
|
161
253
|
await assertCanMutateCompanySkills(req, companyId);
|
|
254
|
+
const result = await svc.updateTestInput(companyId, skillId, inputId, req.body);
|
|
255
|
+
if (!result) {
|
|
256
|
+
res.status(404).json({ error: "Test input not found" });
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const actor = getActorInfo(req);
|
|
260
|
+
await logActivity(db, {
|
|
261
|
+
companyId,
|
|
262
|
+
actorType: actor.actorType,
|
|
263
|
+
actorId: actor.actorId,
|
|
264
|
+
agentId: actor.agentId,
|
|
265
|
+
runId: actor.runId,
|
|
266
|
+
action: "company.skill_test_input_updated",
|
|
267
|
+
entityType: "company_skill_test_input",
|
|
268
|
+
entityId: result.id,
|
|
269
|
+
details: { skillId, changedKeys: Object.keys(req.body).sort() },
|
|
270
|
+
});
|
|
271
|
+
res.json(result);
|
|
272
|
+
});
|
|
273
|
+
router.delete("/companies/:companyId/skills/:skillId/test-inputs/:inputId", async (req, res) => {
|
|
274
|
+
const companyId = req.params.companyId;
|
|
275
|
+
const skillId = req.params.skillId;
|
|
276
|
+
const inputId = req.params.inputId;
|
|
277
|
+
await assertCanMutateCompanySkills(req, companyId);
|
|
278
|
+
const result = await svc.deleteTestInput(companyId, skillId, inputId);
|
|
279
|
+
if (!result) {
|
|
280
|
+
res.status(404).json({ error: "Test input not found" });
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const actor = getActorInfo(req);
|
|
284
|
+
await logActivity(db, {
|
|
285
|
+
companyId,
|
|
286
|
+
actorType: actor.actorType,
|
|
287
|
+
actorId: actor.actorId,
|
|
288
|
+
agentId: actor.agentId,
|
|
289
|
+
runId: actor.runId,
|
|
290
|
+
action: "company.skill_test_input_deleted",
|
|
291
|
+
entityType: "company_skill_test_input",
|
|
292
|
+
entityId: result.id,
|
|
293
|
+
details: { skillId, name: result.name },
|
|
294
|
+
});
|
|
295
|
+
res.json(result);
|
|
296
|
+
});
|
|
297
|
+
router.get("/companies/:companyId/skill-test-run-templates", async (req, res) => {
|
|
298
|
+
const companyId = req.params.companyId;
|
|
299
|
+
assertCompanyAccess(req, companyId);
|
|
300
|
+
res.json(await svc.listTestRunTemplates(companyId));
|
|
301
|
+
});
|
|
302
|
+
router.post("/companies/:companyId/skill-test-run-templates", validate(companySkillTestRunTemplateCreateSchema), async (req, res) => {
|
|
303
|
+
const companyId = req.params.companyId;
|
|
304
|
+
await assertCanMutateCompanySkills(req, companyId);
|
|
305
|
+
const result = await svc.createTestRunTemplate(companyId, req.body, skillActor(req));
|
|
306
|
+
const actor = getActorInfo(req);
|
|
307
|
+
await logActivity(db, {
|
|
308
|
+
companyId,
|
|
309
|
+
actorType: actor.actorType,
|
|
310
|
+
actorId: actor.actorId,
|
|
311
|
+
agentId: actor.agentId,
|
|
312
|
+
runId: actor.runId,
|
|
313
|
+
action: "company.skill_test_run_template_created",
|
|
314
|
+
entityType: "company_skill_test_run_template",
|
|
315
|
+
entityId: result.id,
|
|
316
|
+
details: { name: result.name },
|
|
317
|
+
});
|
|
318
|
+
res.status(201).json(result);
|
|
319
|
+
});
|
|
320
|
+
router.patch("/companies/:companyId/skill-test-run-templates/:templateId", validate(companySkillTestRunTemplateUpdateSchema), async (req, res) => {
|
|
321
|
+
const companyId = req.params.companyId;
|
|
322
|
+
const templateId = req.params.templateId;
|
|
323
|
+
await assertCanMutateCompanySkills(req, companyId);
|
|
324
|
+
const result = await svc.updateTestRunTemplate(companyId, templateId, req.body, skillActor(req));
|
|
325
|
+
if (!result) {
|
|
326
|
+
res.status(404).json({ error: "Test run template not found" });
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const actor = getActorInfo(req);
|
|
330
|
+
await logActivity(db, {
|
|
331
|
+
companyId,
|
|
332
|
+
actorType: actor.actorType,
|
|
333
|
+
actorId: actor.actorId,
|
|
334
|
+
agentId: actor.agentId,
|
|
335
|
+
runId: actor.runId,
|
|
336
|
+
action: "company.skill_test_run_template_updated",
|
|
337
|
+
entityType: "company_skill_test_run_template",
|
|
338
|
+
entityId: result.id,
|
|
339
|
+
details: { changedKeys: Object.keys(req.body).sort() },
|
|
340
|
+
});
|
|
341
|
+
res.json(result);
|
|
342
|
+
});
|
|
343
|
+
router.delete("/companies/:companyId/skill-test-run-templates/:templateId", async (req, res) => {
|
|
344
|
+
const companyId = req.params.companyId;
|
|
345
|
+
const templateId = req.params.templateId;
|
|
346
|
+
await assertCanMutateCompanySkills(req, companyId);
|
|
347
|
+
const result = await svc.deleteTestRunTemplate(companyId, templateId);
|
|
348
|
+
if (!result) {
|
|
349
|
+
res.status(404).json({ error: "Test run template not found" });
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const actor = getActorInfo(req);
|
|
353
|
+
await logActivity(db, {
|
|
354
|
+
companyId,
|
|
355
|
+
actorType: actor.actorType,
|
|
356
|
+
actorId: actor.actorId,
|
|
357
|
+
agentId: actor.agentId,
|
|
358
|
+
runId: actor.runId,
|
|
359
|
+
action: "company.skill_test_run_template_deleted",
|
|
360
|
+
entityType: "company_skill_test_run_template",
|
|
361
|
+
entityId: result.id,
|
|
362
|
+
details: { name: result.name },
|
|
363
|
+
});
|
|
364
|
+
res.json(result);
|
|
365
|
+
});
|
|
366
|
+
router.get("/companies/:companyId/skills/:skillId/test-runs", async (req, res) => {
|
|
367
|
+
const companyId = req.params.companyId;
|
|
368
|
+
const skillId = req.params.skillId;
|
|
369
|
+
assertCompanyAccess(req, companyId);
|
|
370
|
+
const query = companySkillTestRunListQuerySchema.parse({
|
|
371
|
+
inputId: firstQueryString(req.query.inputId),
|
|
372
|
+
});
|
|
373
|
+
res.json(await svc.listTestRuns(companyId, skillId, query));
|
|
374
|
+
});
|
|
375
|
+
router.get("/companies/:companyId/skills/:skillId/test-runs/:runId", async (req, res) => {
|
|
376
|
+
const companyId = req.params.companyId;
|
|
377
|
+
const skillId = req.params.skillId;
|
|
378
|
+
const runId = req.params.runId;
|
|
379
|
+
assertCompanyAccess(req, companyId);
|
|
380
|
+
const result = await svc.getTestRunDetail(companyId, skillId, runId);
|
|
381
|
+
if (!result) {
|
|
382
|
+
res.status(404).json({ error: "Test run not found" });
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
res.json(result);
|
|
386
|
+
});
|
|
387
|
+
router.post("/companies/:companyId/skills/:skillId/test-runs", validate(companySkillTestRunCreateSchema), async (req, res) => {
|
|
388
|
+
const companyId = req.params.companyId;
|
|
389
|
+
const skillId = req.params.skillId;
|
|
390
|
+
await assertCanStartSkillTestRuns(req, companyId);
|
|
391
|
+
const actor = getActorInfo(req);
|
|
392
|
+
const result = await svc.createTestRun(companyId, skillId, req.body, skillActor(req), {
|
|
393
|
+
createHarnessIssue: async (harnessIssue) => {
|
|
394
|
+
const created = await issues.create(companyId, {
|
|
395
|
+
...harnessIssue,
|
|
396
|
+
priority: "medium",
|
|
397
|
+
createdByAgentId: actor.agentId,
|
|
398
|
+
createdByUserId: actor.actorType === "user" ? actor.actorId : null,
|
|
399
|
+
actorRunId: actor.runId,
|
|
400
|
+
});
|
|
401
|
+
await logActivity(db, {
|
|
402
|
+
companyId,
|
|
403
|
+
actorType: actor.actorType,
|
|
404
|
+
actorId: actor.actorId,
|
|
405
|
+
agentId: actor.agentId,
|
|
406
|
+
runId: actor.runId,
|
|
407
|
+
action: "issue.created",
|
|
408
|
+
entityType: "issue",
|
|
409
|
+
entityId: created.id,
|
|
410
|
+
details: {
|
|
411
|
+
title: created.title,
|
|
412
|
+
identifier: created.identifier,
|
|
413
|
+
harnessKind: "skill_test",
|
|
414
|
+
source: "company_skill_test_run",
|
|
415
|
+
skillId,
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
return { id: created.id };
|
|
419
|
+
},
|
|
420
|
+
wakeHarnessIssue: async (issueId, agentId) => heartbeat.wakeup(agentId, {
|
|
421
|
+
source: "assignment",
|
|
422
|
+
triggerDetail: "system",
|
|
423
|
+
reason: "skill_test_run_created",
|
|
424
|
+
payload: { issueId, skillId },
|
|
425
|
+
requestedByActorType: actor.actorType,
|
|
426
|
+
requestedByActorId: actor.actorId,
|
|
427
|
+
contextSnapshot: { issueId, source: "company.skill_test_run" },
|
|
428
|
+
}),
|
|
429
|
+
cleanupHarnessIssue: async (issueId) => {
|
|
430
|
+
const issue = await issues.getById(issueId);
|
|
431
|
+
if (!issue || issue.companyId !== companyId)
|
|
432
|
+
return;
|
|
433
|
+
await issues.update(issueId, {
|
|
434
|
+
status: "cancelled",
|
|
435
|
+
hiddenAt: new Date(),
|
|
436
|
+
actorAgentId: actor.agentId ?? null,
|
|
437
|
+
actorUserId: actor.actorType === "user" ? actor.actorId : null,
|
|
438
|
+
});
|
|
439
|
+
await logActivity(db, {
|
|
440
|
+
companyId,
|
|
441
|
+
actorType: actor.actorType,
|
|
442
|
+
actorId: actor.actorId,
|
|
443
|
+
agentId: actor.agentId,
|
|
444
|
+
runId: actor.runId,
|
|
445
|
+
action: "company.skill_test_harness_issue_cleaned_up",
|
|
446
|
+
entityType: "issue",
|
|
447
|
+
entityId: issueId,
|
|
448
|
+
details: { skillId },
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
await logActivity(db, {
|
|
453
|
+
companyId,
|
|
454
|
+
actorType: actor.actorType,
|
|
455
|
+
actorId: actor.actorId,
|
|
456
|
+
agentId: actor.agentId,
|
|
457
|
+
runId: actor.runId,
|
|
458
|
+
action: "company.skill_test_run_created",
|
|
459
|
+
entityType: "company_skill_test_run",
|
|
460
|
+
entityId: result.id,
|
|
461
|
+
details: {
|
|
462
|
+
skillId,
|
|
463
|
+
inputId: result.inputId,
|
|
464
|
+
skillVersionId: result.skillVersionId,
|
|
465
|
+
agentId: result.agentId,
|
|
466
|
+
issueId: result.issueId,
|
|
467
|
+
},
|
|
468
|
+
});
|
|
469
|
+
res.status(201).json(result);
|
|
470
|
+
});
|
|
471
|
+
router.post("/companies/:companyId/skills/:skillId/test-runs/:runId/cancel", async (req, res) => {
|
|
472
|
+
const companyId = req.params.companyId;
|
|
473
|
+
const skillId = req.params.skillId;
|
|
474
|
+
const runId = req.params.runId;
|
|
475
|
+
await assertCanStartSkillTestRuns(req, companyId);
|
|
476
|
+
const actor = getActorInfo(req);
|
|
477
|
+
const result = await svc.cancelTestRun(companyId, skillId, runId, {
|
|
478
|
+
cancelHarnessIssue: async (issueId) => {
|
|
479
|
+
const issue = await issues.getById(issueId);
|
|
480
|
+
if (!issue || issue.companyId !== companyId)
|
|
481
|
+
return;
|
|
482
|
+
if (issue.executionRunId) {
|
|
483
|
+
await heartbeat.cancelRun(issue.executionRunId, "Cancelled by skill test run request");
|
|
484
|
+
}
|
|
485
|
+
if (issue.status !== "done" && issue.status !== "cancelled") {
|
|
486
|
+
await issues.update(issueId, {
|
|
487
|
+
status: "cancelled",
|
|
488
|
+
actorAgentId: actor.agentId ?? null,
|
|
489
|
+
actorUserId: actor.actorType === "user" ? actor.actorId : null,
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
if (!result) {
|
|
495
|
+
res.status(404).json({ error: "Test run not found" });
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
await logActivity(db, {
|
|
499
|
+
companyId,
|
|
500
|
+
actorType: actor.actorType,
|
|
501
|
+
actorId: actor.actorId,
|
|
502
|
+
agentId: actor.agentId,
|
|
503
|
+
runId: actor.runId,
|
|
504
|
+
action: "company.skill_test_run_cancelled",
|
|
505
|
+
entityType: "company_skill_test_run",
|
|
506
|
+
entityId: result.id,
|
|
507
|
+
details: { skillId, issueId: result.issueId },
|
|
508
|
+
});
|
|
509
|
+
res.json(result);
|
|
510
|
+
});
|
|
511
|
+
router.delete("/companies/:companyId/skills/:skillId/test-runs/:runId", async (req, res) => {
|
|
512
|
+
const companyId = req.params.companyId;
|
|
513
|
+
const skillId = req.params.skillId;
|
|
514
|
+
const runId = req.params.runId;
|
|
515
|
+
await assertCanStartSkillTestRuns(req, companyId);
|
|
516
|
+
const actor = getActorInfo(req);
|
|
517
|
+
const result = await svc.deleteTestRun(companyId, skillId, runId, {
|
|
518
|
+
hideHarnessIssue: async (issueId) => {
|
|
519
|
+
const issue = await issues.getById(issueId);
|
|
520
|
+
if (!issue || issue.companyId !== companyId)
|
|
521
|
+
return;
|
|
522
|
+
await issues.update(issueId, {
|
|
523
|
+
hiddenAt: new Date(),
|
|
524
|
+
actorAgentId: actor.agentId ?? null,
|
|
525
|
+
actorUserId: actor.actorType === "user" ? actor.actorId : null,
|
|
526
|
+
});
|
|
527
|
+
},
|
|
528
|
+
});
|
|
529
|
+
if (!result) {
|
|
530
|
+
res.status(404).json({ error: "Test run not found" });
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
await logActivity(db, {
|
|
534
|
+
companyId,
|
|
535
|
+
actorType: actor.actorType,
|
|
536
|
+
actorId: actor.actorId,
|
|
537
|
+
agentId: actor.agentId,
|
|
538
|
+
runId: actor.runId,
|
|
539
|
+
action: "company.skill_test_run_deleted",
|
|
540
|
+
entityType: "company_skill_test_run",
|
|
541
|
+
entityId: result.id,
|
|
542
|
+
details: { skillId, issueId: result.issueId },
|
|
543
|
+
});
|
|
544
|
+
res.json(result);
|
|
545
|
+
});
|
|
546
|
+
router.post("/companies/:companyId/skills/:skillId/versions", validate(companySkillVersionCreateSchema), async (req, res) => {
|
|
547
|
+
const companyId = req.params.companyId;
|
|
548
|
+
const skillId = req.params.skillId;
|
|
549
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
|
|
162
550
|
const result = await svc.createVersion(companyId, skillId, req.body, skillActor(req));
|
|
163
551
|
const actor = getActorInfo(req);
|
|
164
552
|
await logActivity(db, {
|
|
@@ -219,7 +607,10 @@ export function companySkillRoutes(db) {
|
|
|
219
607
|
router.post("/companies/:companyId/skills/:skillId/fork", validate(companySkillForkSchema), async (req, res) => {
|
|
220
608
|
const companyId = req.params.companyId;
|
|
221
609
|
const skillId = req.params.skillId;
|
|
222
|
-
await assertCanMutateCompanySkills(req, companyId
|
|
610
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({
|
|
611
|
+
skillId,
|
|
612
|
+
slug: req.body.slug,
|
|
613
|
+
}));
|
|
223
614
|
const result = await svc.forkSkill(companyId, skillId, req.body, skillActor(req));
|
|
224
615
|
const actor = getActorInfo(req);
|
|
225
616
|
await logActivity(db, {
|
|
@@ -230,11 +621,12 @@ export function companySkillRoutes(db) {
|
|
|
230
621
|
runId: actor.runId,
|
|
231
622
|
action: "company.skill_forked",
|
|
232
623
|
entityType: "company_skill",
|
|
233
|
-
entityId: result.id,
|
|
624
|
+
entityId: result.skill.id,
|
|
234
625
|
details: {
|
|
235
626
|
sourceSkillId: skillId,
|
|
236
|
-
slug: result.slug,
|
|
237
|
-
name: result.name,
|
|
627
|
+
slug: result.skill.slug,
|
|
628
|
+
name: result.skill.name,
|
|
629
|
+
reassignedAgentIds: result.reassignments.map((entry) => entry.agentId),
|
|
238
630
|
},
|
|
239
631
|
});
|
|
240
632
|
res.status(201).json(result);
|
|
@@ -329,7 +721,9 @@ export function companySkillRoutes(db) {
|
|
|
329
721
|
});
|
|
330
722
|
router.post("/companies/:companyId/skills", validate(companySkillCreateSchema), async (req, res) => {
|
|
331
723
|
const companyId = req.params.companyId;
|
|
332
|
-
await assertCanMutateCompanySkills(req, companyId
|
|
724
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({
|
|
725
|
+
slug: req.body.slug,
|
|
726
|
+
}));
|
|
333
727
|
const result = await svc.createLocalSkill(companyId, req.body, skillActor(req));
|
|
334
728
|
const actor = getActorInfo(req);
|
|
335
729
|
await logActivity(db, {
|
|
@@ -351,7 +745,7 @@ export function companySkillRoutes(db) {
|
|
|
351
745
|
router.patch("/companies/:companyId/skills/:skillId", validate(companySkillUpdateSchema), async (req, res) => {
|
|
352
746
|
const companyId = req.params.companyId;
|
|
353
747
|
const skillId = req.params.skillId;
|
|
354
|
-
await assertCanMutateCompanySkills(req, companyId);
|
|
748
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
|
|
355
749
|
const result = await svc.updateSkill(companyId, skillId, req.body);
|
|
356
750
|
const actor = getActorInfo(req);
|
|
357
751
|
await logActivity(db, {
|
|
@@ -374,7 +768,7 @@ export function companySkillRoutes(db) {
|
|
|
374
768
|
router.patch("/companies/:companyId/skills/:skillId/files", validate(companySkillFileUpdateSchema), async (req, res) => {
|
|
375
769
|
const companyId = req.params.companyId;
|
|
376
770
|
const skillId = req.params.skillId;
|
|
377
|
-
await assertCanMutateCompanySkills(req, companyId);
|
|
771
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
|
|
378
772
|
const result = await svc.updateFile(companyId, skillId, String(req.body.path ?? ""), String(req.body.content ?? ""), skillActor(req));
|
|
379
773
|
const actor = getActorInfo(req);
|
|
380
774
|
await logActivity(db, {
|
|
@@ -393,10 +787,33 @@ export function companySkillRoutes(db) {
|
|
|
393
787
|
});
|
|
394
788
|
res.json(result);
|
|
395
789
|
});
|
|
396
|
-
router.
|
|
790
|
+
router.delete("/companies/:companyId/skills/:skillId/files", validate(companySkillFileDeleteSchema), async (req, res) => {
|
|
397
791
|
const companyId = req.params.companyId;
|
|
792
|
+
const skillId = req.params.skillId;
|
|
398
793
|
await assertCanMutateCompanySkills(req, companyId);
|
|
794
|
+
const result = await svc.deleteFile(companyId, skillId, req.body, skillActor(req));
|
|
795
|
+
const actor = getActorInfo(req);
|
|
796
|
+
await logActivity(db, {
|
|
797
|
+
companyId,
|
|
798
|
+
actorType: actor.actorType,
|
|
799
|
+
actorId: actor.actorId,
|
|
800
|
+
agentId: actor.agentId,
|
|
801
|
+
runId: actor.runId,
|
|
802
|
+
action: "company.skill_file_deleted",
|
|
803
|
+
entityType: "company_skill",
|
|
804
|
+
entityId: skillId,
|
|
805
|
+
details: {
|
|
806
|
+
path: result.path,
|
|
807
|
+
target: result.target,
|
|
808
|
+
deletedPaths: result.deletedPaths,
|
|
809
|
+
},
|
|
810
|
+
});
|
|
811
|
+
res.json(result);
|
|
812
|
+
});
|
|
813
|
+
router.post("/companies/:companyId/skills/import", validate(companySkillImportSchema), async (req, res) => {
|
|
814
|
+
const companyId = req.params.companyId;
|
|
399
815
|
const source = String(req.body.source ?? "");
|
|
816
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ source }));
|
|
400
817
|
const result = await svc.importFromSource(companyId, source);
|
|
401
818
|
const actor = getActorInfo(req);
|
|
402
819
|
await logActivity(db, {
|
|
@@ -428,7 +845,10 @@ export function companySkillRoutes(db) {
|
|
|
428
845
|
});
|
|
429
846
|
router.post("/companies/:companyId/skills/install-catalog", validate(companySkillInstallCatalogSchema), async (req, res) => {
|
|
430
847
|
const companyId = req.params.companyId;
|
|
431
|
-
await assertCanMutateCompanySkills(req, companyId
|
|
848
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({
|
|
849
|
+
catalogSkillId: req.body.catalogSkillId,
|
|
850
|
+
slug: req.body.slug,
|
|
851
|
+
}));
|
|
432
852
|
const result = await svc.installFromCatalog(companyId, req.body);
|
|
433
853
|
const actor = getActorInfo(req);
|
|
434
854
|
await logActivity(db, {
|
|
@@ -453,7 +873,7 @@ export function companySkillRoutes(db) {
|
|
|
453
873
|
});
|
|
454
874
|
router.post("/companies/:companyId/skills/scan-projects", validate(companySkillProjectScanRequestSchema), async (req, res) => {
|
|
455
875
|
const companyId = req.params.companyId;
|
|
456
|
-
await assertCanMutateCompanySkills(req, companyId);
|
|
876
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ scanProjects: true }));
|
|
457
877
|
const result = await svc.scanProjectWorkspaces(companyId, req.body);
|
|
458
878
|
const actor = getActorInfo(req);
|
|
459
879
|
await logActivity(db, {
|
|
@@ -480,7 +900,7 @@ export function companySkillRoutes(db) {
|
|
|
480
900
|
router.delete("/companies/:companyId/skills/:skillId", async (req, res) => {
|
|
481
901
|
const companyId = req.params.companyId;
|
|
482
902
|
const skillId = req.params.skillId;
|
|
483
|
-
await assertCanMutateCompanySkills(req, companyId);
|
|
903
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
|
|
484
904
|
const result = await svc.deleteSkill(companyId, skillId);
|
|
485
905
|
if (!result) {
|
|
486
906
|
res.status(404).json({ error: "Skill not found" });
|
|
@@ -506,7 +926,7 @@ export function companySkillRoutes(db) {
|
|
|
506
926
|
router.post("/companies/:companyId/skills/:skillId/audit", async (req, res) => {
|
|
507
927
|
const companyId = req.params.companyId;
|
|
508
928
|
const skillId = req.params.skillId;
|
|
509
|
-
await assertCanMutateCompanySkills(req, companyId);
|
|
929
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
|
|
510
930
|
const result = await svc.auditSkill(companyId, skillId);
|
|
511
931
|
if (!result) {
|
|
512
932
|
res.status(404).json({ error: "Skill not found" });
|
|
@@ -535,7 +955,7 @@ export function companySkillRoutes(db) {
|
|
|
535
955
|
router.post("/companies/:companyId/skills/:skillId/install-update", validate(companySkillInstallUpdateSchema), async (req, res) => {
|
|
536
956
|
const companyId = req.params.companyId;
|
|
537
957
|
const skillId = req.params.skillId;
|
|
538
|
-
await assertCanMutateCompanySkills(req, companyId);
|
|
958
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
|
|
539
959
|
const before = await svc.getById(companyId, skillId);
|
|
540
960
|
const result = await svc.installUpdate(companyId, skillId, req.body);
|
|
541
961
|
if (!result) {
|
|
@@ -568,7 +988,7 @@ export function companySkillRoutes(db) {
|
|
|
568
988
|
router.post("/companies/:companyId/skills/:skillId/reset", validate(companySkillResetSchema), async (req, res) => {
|
|
569
989
|
const companyId = req.params.companyId;
|
|
570
990
|
const skillId = req.params.skillId;
|
|
571
|
-
await assertCanMutateCompanySkills(req, companyId);
|
|
991
|
+
await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
|
|
572
992
|
const before = await svc.getById(companyId, skillId);
|
|
573
993
|
const result = await svc.resetSkill(companyId, skillId, req.body);
|
|
574
994
|
if (!result) {
|