crewly 1.20.192 → 1.20.194
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/constants.ts +11 -0
- package/config/hooks/subagent-guard/subagent.sh +113 -0
- package/config/roles/architect/prompt.md +1 -1
- package/config/roles/auditor/prompt.md +1 -1
- package/config/roles/backend-developer/prompt.md +1 -1
- package/config/roles/content-strategist/prompt.md +2 -2
- package/config/roles/designer/prompt.md +1 -1
- package/config/roles/developer/prompt.md +2 -2
- package/config/roles/frontend-developer/prompt.md +1 -1
- package/config/roles/fullstack-dev/prompt.md +1 -1
- package/config/roles/generalist/prompt.md +1 -1
- package/config/roles/ops/prompt.md +1 -1
- package/config/roles/orchestrator/prompt.md +2 -2
- package/config/roles/product-manager/prompt.md +1 -1
- package/config/roles/qa/prompt.md +1 -1
- package/config/roles/qa-engineer/prompt.md +1 -1
- package/config/roles/researcher/prompt.md +1 -1
- package/config/roles/sales/prompt.md +1 -1
- package/config/roles/support/prompt.md +1 -1
- package/config/roles/team-leader/prompt.md +1 -1
- package/config/roles/tpm/prompt.md +1 -1
- package/config/roles/ux-designer/prompt.md +1 -1
- package/config/skills/_common/complete-body-shape.test.sh +17 -0
- package/config/skills/agent/core/complete-task/SKILL.md +27 -4
- package/config/skills/agent/core/complete-task/execute.sh +23 -3
- package/config/skills/agent/core/complete-task/execute.test.sh +34 -0
- package/config/skills/agent/core/experiment-card/SKILL.md +96 -0
- package/config/skills/agent/core/experiment-card/execute.sh +147 -0
- package/config/skills/agent/core/experiment-card/execute.test.sh +91 -0
- package/config/skills/agent/core/handoff-task/execute.sh +1 -1
- package/config/skills/agent/core/report-status/SKILL.md +27 -4
- package/config/skills/agent/core/report-status/execute.sh +104 -4
- package/config/skills/agent/core/todo-add/SKILL.md +16 -2
- package/config/skills/agent/core/todo-add/execute.sh +21 -5
- package/config/skills/agent/core/todo-add/execute.test.sh +14 -0
- package/config/skills/agent/core/todo-tasks/SKILL.md +4 -3
- package/config/skills/agent/core/todo-update/SKILL.md +13 -2
- package/config/skills/agent/core/todo-update/execute.sh +41 -3
- package/config/skills/agent/core/todo-update/execute.test.sh +7 -0
- package/config/skills/marketplace-registry.ts +4 -4
- package/config/skills/orchestrator/complete-task/SKILL.md +13 -6
- package/config/skills/orchestrator/complete-task/execute.sh +22 -3
- package/config/skills/orchestrator/delegate-task/execute.sh +2 -2
- package/config/skills/orchestrator/harness-login/SKILL.md +9 -1
- package/config/skills/orchestrator/harness-login/execute.sh +12 -4
- package/config/skills/orchestrator/harness-login/execute.test.sh +7 -0
- package/config/skills/registry.json +6 -5
- package/config/skills/team-leader/delegate-task/execute.sh +1 -1
- package/config/skills/team-leader/verify-output/SKILL.md +18 -1
- package/config/skills/team-leader/verify-output/execute.sh +28 -0
- package/config/skills/team-leader/verify-output/execute.test.sh +27 -0
- package/dist/backend/backend/src/constants.d.ts +192 -2
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +196 -1
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/canva/canva.controller.d.ts +6 -0
- package/dist/backend/backend/src/controllers/canva/canva.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/canva/canva.controller.js +13 -2
- package/dist/backend/backend/src/controllers/canva/canva.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/canva/canva.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/canva/canva.routes.js +3 -1
- package/dist/backend/backend/src/controllers/canva/canva.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +4 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/connector/connector.controller.d.ts +4 -0
- package/dist/backend/backend/src/controllers/connector/connector.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/connector/connector.controller.js +32 -3
- package/dist/backend/backend/src/controllers/connector/connector.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/connector/grant-sharing.handler.d.ts +41 -0
- package/dist/backend/backend/src/controllers/connector/grant-sharing.handler.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/connector/grant-sharing.handler.js +75 -0
- package/dist/backend/backend/src/controllers/connector/grant-sharing.handler.js.map +1 -0
- package/dist/backend/backend/src/controllers/experiments/experiments.routes.d.ts +27 -0
- package/dist/backend/backend/src/controllers/experiments/experiments.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/experiments/experiments.routes.js +96 -0
- package/dist/backend/backend/src/controllers/experiments/experiments.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts +6 -0
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.controller.js +19 -0
- package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.routes.js +3 -1
- package/dist/backend/backend/src/controllers/google/google.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/harness/owner-login.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/harness/owner-login.controller.js +22 -3
- package/dist/backend/backend/src/controllers/harness/owner-login.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.d.ts +19 -2
- package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.js +37 -4
- package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.js +3 -1
- package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +9 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +26 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/people/people.routes.d.ts +25 -0
- package/dist/backend/backend/src/controllers/people/people.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/people/people.routes.js +90 -0
- package/dist/backend/backend/src/controllers/people/people.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/request-types.d.ts +2 -0
- package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.d.ts +22 -1
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js +143 -3
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +25 -3
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +125 -19
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +14 -0
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +82 -3
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +6 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +13 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +28 -3
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js +3 -0
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/control-plane-guard.service.d.ts +3 -2
- package/dist/backend/backend/src/services/agent/control-plane-guard.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/control-plane-guard.service.js +14 -3
- package/dist/backend/backend/src/services/agent/control-plane-guard.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts +28 -1
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js +48 -4
- package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/idle-detection.service.js +1 -1
- package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +2 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +17 -4
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +14 -0
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +38 -0
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts +34 -0
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.js +49 -5
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +8 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/canva/canva-token.service.d.ts +17 -4
- package/dist/backend/backend/src/services/canva/canva-token.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/canva/canva-token.service.js +54 -17
- package/dist/backend/backend/src/services/canva/canva-token.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +35 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +77 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.service.d.ts +17 -2
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.service.js +30 -6
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.utils.d.ts +38 -2
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.utils.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.utils.js +63 -1
- package/dist/backend/backend/src/services/cloud/cloud-disconnect-notice.utils.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts +74 -4
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.js +204 -56
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +19 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +3 -0
- package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -1
- package/dist/backend/backend/src/services/experiments/experiment-verdict.d.ts +88 -0
- package/dist/backend/backend/src/services/experiments/experiment-verdict.d.ts.map +1 -0
- package/dist/backend/backend/src/services/experiments/experiment-verdict.js +226 -0
- package/dist/backend/backend/src/services/experiments/experiment-verdict.js.map +1 -0
- package/dist/backend/backend/src/services/experiments/experiment.service.d.ts +301 -0
- package/dist/backend/backend/src/services/experiments/experiment.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/experiments/experiment.service.js +754 -0
- package/dist/backend/backend/src/services/experiments/experiment.service.js.map +1 -0
- package/dist/backend/backend/src/services/experiments/experiment.wiring.d.ts +73 -0
- package/dist/backend/backend/src/services/experiments/experiment.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/experiments/experiment.wiring.js +142 -0
- package/dist/backend/backend/src/services/experiments/experiment.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.d.ts +60 -0
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.d.ts.map +1 -0
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.js +113 -0
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.js.map +1 -0
- package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts +25 -2
- package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js +53 -7
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/claude-accounts.d.ts +207 -0
- package/dist/backend/backend/src/services/harness/claude-accounts.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/claude-accounts.js +306 -0
- package/dist/backend/backend/src/services/harness/claude-accounts.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts +35 -0
- package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-credentials.store.js +48 -0
- package/dist/backend/backend/src/services/harness/harness-credentials.store.js.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts +70 -1
- package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-relogin.service.js +156 -19
- package/dist/backend/backend/src/services/harness/harness-relogin.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/harness.types.d.ts +2 -0
- package/dist/backend/backend/src/services/harness/harness.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/harness.types.js.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +19 -4
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.js +46 -7
- package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/owner-login-request.d.ts +18 -2
- package/dist/backend/backend/src/services/harness/owner-login-request.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/owner-login-request.js +31 -7
- package/dist/backend/backend/src/services/harness/owner-login-request.js.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts +21 -0
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js +39 -1
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts +19 -0
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js +46 -0
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +5 -0
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +13 -0
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
- package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.d.ts +87 -5
- package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.js +151 -12
- package/dist/backend/backend/src/services/microsoft/microsoft-todo.service.js.map +1 -1
- package/dist/backend/backend/src/services/microsoft/microsoft-token.service.d.ts +17 -4
- package/dist/backend/backend/src/services/microsoft/microsoft-token.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/microsoft/microsoft-token.service.js +50 -17
- package/dist/backend/backend/src/services/microsoft/microsoft-token.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/claude-session-tokens.service.d.ts +53 -7
- package/dist/backend/backend/src/services/monitoring/claude-session-tokens.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/claude-session-tokens.service.js +77 -14
- package/dist/backend/backend/src/services/monitoring/claude-session-tokens.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.d.ts +53 -1
- package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.js +130 -29
- package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-status-router.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-status-router.service.js +3 -2
- package/dist/backend/backend/src/services/orc/orc-status-router.service.js.map +1 -1
- package/dist/backend/backend/src/services/people/acting-for.service.d.ts +188 -0
- package/dist/backend/backend/src/services/people/acting-for.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/people/acting-for.service.js +299 -0
- package/dist/backend/backend/src/services/people/acting-for.service.js.map +1 -0
- package/dist/backend/backend/src/services/people/dedicated-agent.d.ts +89 -0
- package/dist/backend/backend/src/services/people/dedicated-agent.d.ts.map +1 -0
- package/dist/backend/backend/src/services/people/dedicated-agent.js +113 -0
- package/dist/backend/backend/src/services/people/dedicated-agent.js.map +1 -0
- package/dist/backend/backend/src/services/people/grant-sharing.d.ts +80 -0
- package/dist/backend/backend/src/services/people/grant-sharing.d.ts.map +1 -0
- package/dist/backend/backend/src/services/people/grant-sharing.js +143 -0
- package/dist/backend/backend/src/services/people/grant-sharing.js.map +1 -0
- package/dist/backend/backend/src/services/people/people-directory.service.d.ts +239 -0
- package/dist/backend/backend/src/services/people/people-directory.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/people/people-directory.service.js +454 -0
- package/dist/backend/backend/src/services/people/people-directory.service.js.map +1 -0
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts +29 -1
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js +40 -0
- package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.d.ts +8 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.js +16 -2
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts +60 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js +140 -8
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.store.js +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.store.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts +20 -7
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.js +24 -7
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js +12 -2
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.d.ts +7 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.js +18 -3
- package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +3 -0
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-bot-ids.d.ts +33 -0
- package/dist/backend/backend/src/services/slack/slack-bot-ids.d.ts.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-bot-ids.js +56 -0
- package/dist/backend/backend/src/services/slack/slack-bot-ids.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +22 -0
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +70 -0
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +46 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +6 -0
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +8 -0
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/completion-evidence.service.d.ts +105 -0
- package/dist/backend/backend/src/services/task-pool/completion-evidence.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/task-pool/completion-evidence.service.js +238 -0
- package/dist/backend/backend/src/services/task-pool/completion-evidence.service.js.map +1 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +4 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/usage/usage-stats.service.d.ts +39 -12
- package/dist/backend/backend/src/services/usage/usage-stats.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/usage/usage-stats.service.js +61 -20
- package/dist/backend/backend/src/services/usage/usage-stats.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts +2 -0
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +9 -0
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +10 -0
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +45 -2
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +3 -0
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.js +3 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/experiment.types.d.ts +153 -0
- package/dist/backend/backend/src/types/experiment.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/experiment.types.js +32 -0
- package/dist/backend/backend/src/types/experiment.types.js.map +1 -0
- package/dist/backend/backend/src/types/index.d.ts +12 -1
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/types/messaging.types.d.ts +11 -0
- package/dist/backend/backend/src/types/messaging.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/messaging.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/completion-evidence.types.d.ts +77 -0
- package/dist/backend/backend/src/types/v2/completion-evidence.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/v2/completion-evidence.types.js +119 -0
- package/dist/backend/backend/src/types/v2/completion-evidence.types.js.map +1 -0
- package/dist/backend/backend/src/types/v2/work-item.types.d.ts +13 -0
- package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/backend/config/constants.d.ts +11 -0
- package/dist/backend/config/constants.d.ts.map +1 -1
- package/dist/backend/config/constants.js +11 -0
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +192 -2
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +196 -1
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +13 -0
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js +28 -3
- package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js +3 -0
- package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/control-plane-guard.service.d.ts +3 -2
- package/dist/cli/backend/src/services/agent/control-plane-guard.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/control-plane-guard.service.js +14 -3
- package/dist/cli/backend/src/services/agent/control-plane-guard.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts +28 -1
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js +48 -4
- package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +2 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +17 -4
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts +14 -0
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js +38 -0
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts +34 -0
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.js +49 -5
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js +8 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +35 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +77 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.d.ts +74 -4
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.js +204 -56
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +19 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/cli/backend/src/services/harness/claude-accounts.d.ts +207 -0
- package/dist/cli/backend/src/services/harness/claude-accounts.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/claude-accounts.js +306 -0
- package/dist/cli/backend/src/services/harness/claude-accounts.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts +35 -0
- package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-credentials.store.js +48 -0
- package/dist/cli/backend/src/services/harness/harness-credentials.store.js.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts +70 -1
- package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-relogin.service.js +156 -19
- package/dist/cli/backend/src/services/harness/harness-relogin.service.js.map +1 -1
- package/dist/cli/backend/src/services/harness/harness.types.d.ts +2 -0
- package/dist/cli/backend/src/services/harness/harness.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/harness.types.js.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +19 -4
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.js +46 -7
- package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/cli/backend/src/services/harness/owner-login-request.d.ts +18 -2
- package/dist/cli/backend/src/services/harness/owner-login-request.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/owner-login-request.js +31 -7
- package/dist/cli/backend/src/services/harness/owner-login-request.js.map +1 -1
- package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.d.ts +21 -0
- package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.js +39 -1
- package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts +19 -0
- package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js +46 -0
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +5 -0
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +13 -0
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/claude-session-tokens.service.d.ts +197 -0
- package/dist/cli/backend/src/services/monitoring/claude-session-tokens.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/monitoring/claude-session-tokens.service.js +455 -0
- package/dist/cli/backend/src/services/monitoring/claude-session-tokens.service.js.map +1 -0
- package/dist/cli/backend/src/services/people/acting-for.service.d.ts +188 -0
- package/dist/cli/backend/src/services/people/acting-for.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/people/acting-for.service.js +299 -0
- package/dist/cli/backend/src/services/people/acting-for.service.js.map +1 -0
- package/dist/cli/backend/src/services/people/dedicated-agent.d.ts +89 -0
- package/dist/cli/backend/src/services/people/dedicated-agent.d.ts.map +1 -0
- package/dist/cli/backend/src/services/people/dedicated-agent.js +113 -0
- package/dist/cli/backend/src/services/people/dedicated-agent.js.map +1 -0
- package/dist/cli/backend/src/services/people/people-directory.service.d.ts +239 -0
- package/dist/cli/backend/src/services/people/people-directory.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/people/people-directory.service.js +454 -0
- package/dist/cli/backend/src/services/people/people-directory.service.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts +29 -1
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js +40 -0
- package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts +20 -7
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.js +24 -7
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +3 -0
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +22 -0
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +70 -0
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +46 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts +6 -0
- package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.js +8 -0
- package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +4 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
- package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +12 -1
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/backend/src/types/messaging.types.d.ts +11 -0
- package/dist/cli/backend/src/types/messaging.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/messaging.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.d.ts +13 -0
- package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
- package/dist/cli/cli/src/utils/marketplace.d.ts +21 -0
- package/dist/cli/cli/src/utils/marketplace.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/marketplace.js +35 -1
- package/dist/cli/cli/src/utils/marketplace.js.map +1 -1
- package/dist/cli/config/constants.d.ts +11 -0
- package/dist/cli/config/constants.d.ts.map +1 -1
- package/dist/cli/config/constants.js +11 -0
- package/dist/cli/config/constants.js.map +1 -1
- package/dist/cli/config/skills/marketplace-registry.d.ts +4 -4
- package/dist/cli/config/skills/marketplace-registry.js +4 -4
- package/frontend/dist/assets/{index-fc715ec3.css → index-5e967795.css} +1 -1
- package/frontend/dist/assets/{index-5b7af029.js → index-800118ca.js} +296 -296
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/packages/crewly-agent/src/runtime/tool-registry.test.ts +45 -0
- package/packages/crewly-agent/src/runtime/tool-registry.ts +40 -5
- package/packages/crewly-agent/src/test/isolated-home.test.ts +24 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* People directory — the humans who use this Crewly instance, keyed by their
|
|
3
|
+
* Slack user id, with a role (issue #968).
|
|
4
|
+
*
|
|
5
|
+
* - **owner**: the instance owner. Their person id is always `owner` —
|
|
6
|
+
* what this backend stores and sends Cloud. Any Slack id known to be the
|
|
7
|
+
* owner maps to it: the Slack installer (Cloud's workspace config, i.e. the
|
|
8
|
+
* Cloud account's Slack identity), `SLACK_OWNER_USER_ID` (installs whose
|
|
9
|
+
* Slack credentials come from env), and Slack ids the owner marked as their
|
|
10
|
+
* own in Settings › People. Always shown, never removable.
|
|
11
|
+
* - **member**: a person in the workspace. A Slack user who messages an agent
|
|
12
|
+
* is added as a member automatically.
|
|
13
|
+
* - **guest**: someone the owner marked as a guest. Guests are not included
|
|
14
|
+
* when a connector is shared with "all members".
|
|
15
|
+
*
|
|
16
|
+
* Bots (the master bot, agent bots) are never people: they are not added,
|
|
17
|
+
* and rows a bot left in `people.json` are removed when the file is loaded.
|
|
18
|
+
*
|
|
19
|
+
* Stored in `<CREWLY_HOME>/people.json`. Writes are atomic.
|
|
20
|
+
*
|
|
21
|
+
* specs/per-person-access.md
|
|
22
|
+
*
|
|
23
|
+
* @module services/people/people-directory.service
|
|
24
|
+
*/
|
|
25
|
+
/** A person's role on this instance. */
|
|
26
|
+
export type PersonRole = 'owner' | 'member' | 'guest';
|
|
27
|
+
/** One person. */
|
|
28
|
+
export interface Person {
|
|
29
|
+
/** Slack user id (`U0123…`), or `owner` for the instance owner */
|
|
30
|
+
id: string;
|
|
31
|
+
/** The owner's known Slack user ids (owner row only, for display) */
|
|
32
|
+
slackUserIds?: string[];
|
|
33
|
+
/** Display name */
|
|
34
|
+
name?: string;
|
|
35
|
+
role: PersonRole;
|
|
36
|
+
/** `auto`: added when they first messaged an agent; `owner`: added or edited by the owner */
|
|
37
|
+
source: 'auto' | 'owner';
|
|
38
|
+
createdAt: string;
|
|
39
|
+
updatedAt: string;
|
|
40
|
+
}
|
|
41
|
+
/** An invalid edit. */
|
|
42
|
+
export declare class PeopleDirectoryError extends Error {
|
|
43
|
+
}
|
|
44
|
+
/** Injectable dependencies. */
|
|
45
|
+
export interface PeopleDirectoryDeps {
|
|
46
|
+
/** Store file (default `<CREWLY_HOME>/people.json`) */
|
|
47
|
+
filePath?: string;
|
|
48
|
+
/** The instance owner's Slack user id, when known (the Slack installer) */
|
|
49
|
+
getOwnerSlackUserId?: () => string | null | undefined;
|
|
50
|
+
/** Whether a Slack user id is a bot (the master bot or an agent's bot) */
|
|
51
|
+
isBot?: (slackUserId: string) => boolean;
|
|
52
|
+
/** Environment (default `process.env`), for `SLACK_OWNER_USER_ID` */
|
|
53
|
+
env?: NodeJS.ProcessEnv;
|
|
54
|
+
now?: () => number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether a value is a valid role.
|
|
58
|
+
*
|
|
59
|
+
* @param value - Candidate
|
|
60
|
+
* @returns True for owner / member / guest
|
|
61
|
+
*/
|
|
62
|
+
export declare function isPersonRole(value: unknown): value is PersonRole;
|
|
63
|
+
/**
|
|
64
|
+
* Whether a value is a person id this directory accepts: a Slack user id, or
|
|
65
|
+
* the owner placeholder.
|
|
66
|
+
*
|
|
67
|
+
* @param value - Candidate
|
|
68
|
+
* @returns True when valid
|
|
69
|
+
*/
|
|
70
|
+
export declare function isPersonId(value: unknown): value is string;
|
|
71
|
+
/** The people directory. */
|
|
72
|
+
export declare class PeopleDirectoryService {
|
|
73
|
+
private readonly filePathOverride?;
|
|
74
|
+
private readonly installerSlackUserId;
|
|
75
|
+
private readonly botCheck;
|
|
76
|
+
private readonly env;
|
|
77
|
+
private readonly now;
|
|
78
|
+
/**
|
|
79
|
+
* @param deps - Store path, owner and bot lookups, environment, clock
|
|
80
|
+
*/
|
|
81
|
+
constructor(deps?: PeopleDirectoryDeps);
|
|
82
|
+
/** @returns Store path (resolved per call so CREWLY_HOME changes apply) */
|
|
83
|
+
private filePath;
|
|
84
|
+
/**
|
|
85
|
+
* The owner's person id. Always `owner` — what is stored and sent Cloud.
|
|
86
|
+
*
|
|
87
|
+
* @returns `owner`
|
|
88
|
+
*/
|
|
89
|
+
ownerId(): string;
|
|
90
|
+
/**
|
|
91
|
+
* Every Slack id known to be the owner: the Slack installer,
|
|
92
|
+
* `SLACK_OWNER_USER_ID`, and ids the owner marked as their own.
|
|
93
|
+
*
|
|
94
|
+
* @returns Slack user ids (deduplicated, maybe empty)
|
|
95
|
+
*/
|
|
96
|
+
ownerSlackUserIds(): string[];
|
|
97
|
+
/**
|
|
98
|
+
* Whether a person id is the instance owner.
|
|
99
|
+
*
|
|
100
|
+
* @param id - Person id
|
|
101
|
+
* @returns True for `owner` or any Slack id known to be the owner
|
|
102
|
+
*/
|
|
103
|
+
isOwner(id: string | null | undefined): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The id to store and send for a person: `owner` for the owner (by either
|
|
106
|
+
* spelling), else the id as given.
|
|
107
|
+
*
|
|
108
|
+
* @param id - Person id
|
|
109
|
+
* @returns Canonical person id
|
|
110
|
+
*/
|
|
111
|
+
canonicalId(id: string): string;
|
|
112
|
+
/**
|
|
113
|
+
* Whether a Slack user id is a bot (never a person).
|
|
114
|
+
*
|
|
115
|
+
* @param id - Slack user id
|
|
116
|
+
* @returns True for the master bot or an agent's bot
|
|
117
|
+
*/
|
|
118
|
+
isBot(id: string | null | undefined): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Everyone, owner first, then by name.
|
|
121
|
+
*
|
|
122
|
+
* @returns People (copies)
|
|
123
|
+
*/
|
|
124
|
+
list(): Person[];
|
|
125
|
+
/**
|
|
126
|
+
* One person.
|
|
127
|
+
*
|
|
128
|
+
* @param id - Person id
|
|
129
|
+
* @returns The person, or null when unknown
|
|
130
|
+
*/
|
|
131
|
+
get(id: string): Person | null;
|
|
132
|
+
/**
|
|
133
|
+
* A person's role. Unknown people are members (the default for a Slack
|
|
134
|
+
* user in the workspace).
|
|
135
|
+
*
|
|
136
|
+
* @param id - Person id
|
|
137
|
+
* @returns Role
|
|
138
|
+
*/
|
|
139
|
+
roleOf(id: string): PersonRole;
|
|
140
|
+
/**
|
|
141
|
+
* How to name a person to others.
|
|
142
|
+
*
|
|
143
|
+
* @param id - Person id
|
|
144
|
+
* @returns Their name, "the owner" for an owner without one, else the id
|
|
145
|
+
*/
|
|
146
|
+
displayName(id: string): string;
|
|
147
|
+
/**
|
|
148
|
+
* Record a Slack user who messaged an agent (added as a member the first
|
|
149
|
+
* time; a missing name is filled in). Never changes a role.
|
|
150
|
+
*
|
|
151
|
+
* @param id - Slack user id
|
|
152
|
+
* @param name - Their display name, when known
|
|
153
|
+
*/
|
|
154
|
+
noteSeen(id: string, name?: string): void;
|
|
155
|
+
/**
|
|
156
|
+
* Add or edit a person (owner action). Giving a Slack id the `owner` role
|
|
157
|
+
* marks it as the owner's own Slack account (for installs that cannot
|
|
158
|
+
* tell, e.g. Slack credentials from env): it then maps to `owner`.
|
|
159
|
+
*
|
|
160
|
+
* @param id - Slack user id
|
|
161
|
+
* @param patch - Name and/or role
|
|
162
|
+
* @returns The person
|
|
163
|
+
* @throws PeopleDirectoryError on an invalid id or role, a bot, or when changing the owner's role
|
|
164
|
+
*/
|
|
165
|
+
upsert(id: string, patch: {
|
|
166
|
+
name?: unknown;
|
|
167
|
+
role?: unknown;
|
|
168
|
+
}): Person;
|
|
169
|
+
/**
|
|
170
|
+
* Remove a person (they come back as a member if they message an agent again).
|
|
171
|
+
*
|
|
172
|
+
* @param id - Person id
|
|
173
|
+
* @returns True when removed
|
|
174
|
+
* @throws PeopleDirectoryError for the owner
|
|
175
|
+
*/
|
|
176
|
+
remove(id: string): boolean;
|
|
177
|
+
/**
|
|
178
|
+
* Record a Slack id as the owner's own and drop any member row it had.
|
|
179
|
+
*
|
|
180
|
+
* @param id - Slack user id
|
|
181
|
+
*/
|
|
182
|
+
private markOwnerSlackId;
|
|
183
|
+
/**
|
|
184
|
+
* The stored file, without bots. Bot rows found on disk (written by an
|
|
185
|
+
* earlier version that recorded agent posts as people) are removed from
|
|
186
|
+
* the file here (best effort).
|
|
187
|
+
*
|
|
188
|
+
* @returns The stored file (empty when missing or unreadable)
|
|
189
|
+
*/
|
|
190
|
+
private read;
|
|
191
|
+
/** @returns The stored file as on disk (valid rows only; empty when missing or unreadable) */
|
|
192
|
+
private readRaw;
|
|
193
|
+
/**
|
|
194
|
+
* Write atomically.
|
|
195
|
+
*
|
|
196
|
+
* @param file - Contents
|
|
197
|
+
*/
|
|
198
|
+
private write;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Trim and bound a display name.
|
|
202
|
+
*
|
|
203
|
+
* @param name - Raw name
|
|
204
|
+
* @returns Clean name, or undefined when empty
|
|
205
|
+
*/
|
|
206
|
+
export declare function cleanPersonName(name: string | null | undefined): string | undefined;
|
|
207
|
+
/**
|
|
208
|
+
* Record a Slack user who messaged an agent, with their name (best effort,
|
|
209
|
+
* never throws).
|
|
210
|
+
*
|
|
211
|
+
* @param slackUserId - Slack user id
|
|
212
|
+
* @param name - Display name, when known
|
|
213
|
+
*/
|
|
214
|
+
export declare function notePerson(slackUserId: string, name?: string | null): void;
|
|
215
|
+
/**
|
|
216
|
+
* Tell the directory how to find the owner's Slack id (wired once Slack is up).
|
|
217
|
+
*
|
|
218
|
+
* @param lookup - Lookup, or null
|
|
219
|
+
*/
|
|
220
|
+
export declare function setPeopleOwnerLookup(lookup: (() => string | null | undefined) | null): void;
|
|
221
|
+
/**
|
|
222
|
+
* Tell the directory how to recognise Crewly's bots (wired once Slack is up).
|
|
223
|
+
*
|
|
224
|
+
* @param lookup - Whether a Slack user id is a bot, or null
|
|
225
|
+
*/
|
|
226
|
+
export declare function setPeopleBotLookup(lookup: ((slackUserId: string) => boolean) | null): void;
|
|
227
|
+
/**
|
|
228
|
+
* The backend's people directory.
|
|
229
|
+
*
|
|
230
|
+
* @returns Singleton
|
|
231
|
+
*/
|
|
232
|
+
export declare function getPeopleDirectory(): PeopleDirectoryService;
|
|
233
|
+
/**
|
|
234
|
+
* Replace the singleton (tests).
|
|
235
|
+
*
|
|
236
|
+
* @param service - Instance, or null to reset
|
|
237
|
+
*/
|
|
238
|
+
export declare function setPeopleDirectoryForTesting(service: PeopleDirectoryService | null): void;
|
|
239
|
+
//# sourceMappingURL=people-directory.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"people-directory.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/people/people-directory.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAOH,wCAAwC;AACxC,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD,kBAAkB;AAClB,MAAM,WAAW,MAAM;IACtB,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,6FAA6F;IAC7F,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAUD,uBAAuB;AACvB,qBAAa,oBAAqB,SAAQ,KAAK;CAAG;AAElD,+BAA+B;AAC/B,MAAM,WAAW,mBAAmB;IACnC,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,0EAA0E;IAC1E,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE1D;AAED,4BAA4B;AAC5B,qBAAa,sBAAsB;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA0B;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IAEnC;;OAEG;gBACS,IAAI,GAAE,mBAAwB;IAqB1C,2EAA2E;IAC3E,OAAO,CAAC,QAAQ;IAIhB;;;;OAIG;IACH,OAAO,IAAI,MAAM;IAIjB;;;;;OAKG;IACH,iBAAiB,IAAI,MAAM,EAAE;IAY7B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO;IAK/C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAI/B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO;IAI7C;;;;OAIG;IACH,IAAI,IAAI,MAAM,EAAE;IAuBhB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK9B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU;IAO9B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAM/B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAiCzC;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM;IA+BrE;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAU3B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;;;;;OAMG;IACH,OAAO,CAAC,IAAI;IAaZ,8FAA8F;IAC9F,OAAO,CAAC,OAAO;IAkBf;;;;OAIG;IACH,OAAO,CAAC,KAAK;CAOb;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAInF;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAM1E;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,IAAI,CAE3F;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,CAE1F;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,sBAAsB,CAM3D;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,IAAI,CAEzF"}
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* People directory — the humans who use this Crewly instance, keyed by their
|
|
3
|
+
* Slack user id, with a role (issue #968).
|
|
4
|
+
*
|
|
5
|
+
* - **owner**: the instance owner. Their person id is always `owner` —
|
|
6
|
+
* what this backend stores and sends Cloud. Any Slack id known to be the
|
|
7
|
+
* owner maps to it: the Slack installer (Cloud's workspace config, i.e. the
|
|
8
|
+
* Cloud account's Slack identity), `SLACK_OWNER_USER_ID` (installs whose
|
|
9
|
+
* Slack credentials come from env), and Slack ids the owner marked as their
|
|
10
|
+
* own in Settings › People. Always shown, never removable.
|
|
11
|
+
* - **member**: a person in the workspace. A Slack user who messages an agent
|
|
12
|
+
* is added as a member automatically.
|
|
13
|
+
* - **guest**: someone the owner marked as a guest. Guests are not included
|
|
14
|
+
* when a connector is shared with "all members".
|
|
15
|
+
*
|
|
16
|
+
* Bots (the master bot, agent bots) are never people: they are not added,
|
|
17
|
+
* and rows a bot left in `people.json` are removed when the file is loaded.
|
|
18
|
+
*
|
|
19
|
+
* Stored in `<CREWLY_HOME>/people.json`. Writes are atomic.
|
|
20
|
+
*
|
|
21
|
+
* specs/per-person-access.md
|
|
22
|
+
*
|
|
23
|
+
* @module services/people/people-directory.service
|
|
24
|
+
*/
|
|
25
|
+
import * as fs from 'fs';
|
|
26
|
+
import * as path from 'path';
|
|
27
|
+
import { PEOPLE_CONSTANTS } from '../../constants.js';
|
|
28
|
+
import { getCrewlyHomePath } from '../core/crewly-home.utils.js';
|
|
29
|
+
/** An invalid edit. */
|
|
30
|
+
export class PeopleDirectoryError extends Error {
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Whether a value is a valid role.
|
|
34
|
+
*
|
|
35
|
+
* @param value - Candidate
|
|
36
|
+
* @returns True for owner / member / guest
|
|
37
|
+
*/
|
|
38
|
+
export function isPersonRole(value) {
|
|
39
|
+
return typeof value === 'string' && PEOPLE_CONSTANTS.ROLES.includes(value);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Whether a value is a person id this directory accepts: a Slack user id, or
|
|
43
|
+
* the owner placeholder.
|
|
44
|
+
*
|
|
45
|
+
* @param value - Candidate
|
|
46
|
+
* @returns True when valid
|
|
47
|
+
*/
|
|
48
|
+
export function isPersonId(value) {
|
|
49
|
+
return typeof value === 'string' && (value === PEOPLE_CONSTANTS.OWNER_ID || PEOPLE_CONSTANTS.SLACK_USER_ID_PATTERN.test(value));
|
|
50
|
+
}
|
|
51
|
+
/** The people directory. */
|
|
52
|
+
export class PeopleDirectoryService {
|
|
53
|
+
filePathOverride;
|
|
54
|
+
installerSlackUserId;
|
|
55
|
+
botCheck;
|
|
56
|
+
env;
|
|
57
|
+
now;
|
|
58
|
+
/**
|
|
59
|
+
* @param deps - Store path, owner and bot lookups, environment, clock
|
|
60
|
+
*/
|
|
61
|
+
constructor(deps = {}) {
|
|
62
|
+
this.filePathOverride = deps.filePath;
|
|
63
|
+
this.installerSlackUserId = () => {
|
|
64
|
+
try {
|
|
65
|
+
const id = deps.getOwnerSlackUserId?.();
|
|
66
|
+
return typeof id === 'string' && id.trim() ? id.trim() : null;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
this.botCheck = (id) => {
|
|
73
|
+
try {
|
|
74
|
+
return !!deps.isBot?.(id);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
this.env = () => deps.env ?? process.env;
|
|
81
|
+
this.now = deps.now ?? (() => Date.now());
|
|
82
|
+
}
|
|
83
|
+
/** @returns Store path (resolved per call so CREWLY_HOME changes apply) */
|
|
84
|
+
filePath() {
|
|
85
|
+
return this.filePathOverride ?? path.join(getCrewlyHomePath(), PEOPLE_CONSTANTS.STORE_FILE);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The owner's person id. Always `owner` — what is stored and sent Cloud.
|
|
89
|
+
*
|
|
90
|
+
* @returns `owner`
|
|
91
|
+
*/
|
|
92
|
+
ownerId() {
|
|
93
|
+
return PEOPLE_CONSTANTS.OWNER_ID;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Every Slack id known to be the owner: the Slack installer,
|
|
97
|
+
* `SLACK_OWNER_USER_ID`, and ids the owner marked as their own.
|
|
98
|
+
*
|
|
99
|
+
* @returns Slack user ids (deduplicated, maybe empty)
|
|
100
|
+
*/
|
|
101
|
+
ownerSlackUserIds() {
|
|
102
|
+
const ids = [];
|
|
103
|
+
const add = (id) => {
|
|
104
|
+
const v = typeof id === 'string' ? id.trim() : '';
|
|
105
|
+
if (PEOPLE_CONSTANTS.SLACK_USER_ID_PATTERN.test(v) && !ids.includes(v))
|
|
106
|
+
ids.push(v);
|
|
107
|
+
};
|
|
108
|
+
add(this.installerSlackUserId());
|
|
109
|
+
for (const id of (this.env()[PEOPLE_CONSTANTS.OWNER_SLACK_USER_ID_ENV] ?? '').split(','))
|
|
110
|
+
add(id);
|
|
111
|
+
for (const id of this.readRaw().ownerSlackUserIds ?? [])
|
|
112
|
+
add(id);
|
|
113
|
+
return ids;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Whether a person id is the instance owner.
|
|
117
|
+
*
|
|
118
|
+
* @param id - Person id
|
|
119
|
+
* @returns True for `owner` or any Slack id known to be the owner
|
|
120
|
+
*/
|
|
121
|
+
isOwner(id) {
|
|
122
|
+
if (!id)
|
|
123
|
+
return false;
|
|
124
|
+
return id === PEOPLE_CONSTANTS.OWNER_ID || this.ownerSlackUserIds().includes(id);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The id to store and send for a person: `owner` for the owner (by either
|
|
128
|
+
* spelling), else the id as given.
|
|
129
|
+
*
|
|
130
|
+
* @param id - Person id
|
|
131
|
+
* @returns Canonical person id
|
|
132
|
+
*/
|
|
133
|
+
canonicalId(id) {
|
|
134
|
+
return this.isOwner(id) ? PEOPLE_CONSTANTS.OWNER_ID : id;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Whether a Slack user id is a bot (never a person).
|
|
138
|
+
*
|
|
139
|
+
* @param id - Slack user id
|
|
140
|
+
* @returns True for the master bot or an agent's bot
|
|
141
|
+
*/
|
|
142
|
+
isBot(id) {
|
|
143
|
+
return !!id && id !== PEOPLE_CONSTANTS.OWNER_ID && this.botCheck(id);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Everyone, owner first, then by name.
|
|
147
|
+
*
|
|
148
|
+
* @returns People (copies)
|
|
149
|
+
*/
|
|
150
|
+
list() {
|
|
151
|
+
const stored = this.read().people;
|
|
152
|
+
const slackIds = this.ownerSlackUserIds();
|
|
153
|
+
const iso = new Date(this.now()).toISOString();
|
|
154
|
+
// The owner's row: the `owner` entry, else a row from before the owner
|
|
155
|
+
// was always `owner` (keyed by one of their Slack ids), for the name.
|
|
156
|
+
const ownerRow = stored.find((p) => p.id === PEOPLE_CONSTANTS.OWNER_ID);
|
|
157
|
+
const legacyRow = stored.find((p) => slackIds.includes(p.id) && p.name);
|
|
158
|
+
const name = ownerRow?.name ?? legacyRow?.name;
|
|
159
|
+
const owner = {
|
|
160
|
+
...(ownerRow ?? { source: 'owner', createdAt: iso, updatedAt: iso }),
|
|
161
|
+
...(name ? { name } : {}),
|
|
162
|
+
id: PEOPLE_CONSTANTS.OWNER_ID,
|
|
163
|
+
role: 'owner',
|
|
164
|
+
...(slackIds.length > 0 ? { slackUserIds: slackIds } : {}),
|
|
165
|
+
};
|
|
166
|
+
const others = stored
|
|
167
|
+
.filter((p) => p.id !== PEOPLE_CONSTANTS.OWNER_ID && !slackIds.includes(p.id))
|
|
168
|
+
.map((p) => ({ ...p, role: p.role === 'owner' ? 'member' : p.role }))
|
|
169
|
+
.sort((a, b) => (a.name ?? a.id).localeCompare(b.name ?? b.id));
|
|
170
|
+
return [owner, ...others];
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* One person.
|
|
174
|
+
*
|
|
175
|
+
* @param id - Person id
|
|
176
|
+
* @returns The person, or null when unknown
|
|
177
|
+
*/
|
|
178
|
+
get(id) {
|
|
179
|
+
const key = this.canonicalId(id);
|
|
180
|
+
return this.list().find((p) => p.id === key) ?? null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* A person's role. Unknown people are members (the default for a Slack
|
|
184
|
+
* user in the workspace).
|
|
185
|
+
*
|
|
186
|
+
* @param id - Person id
|
|
187
|
+
* @returns Role
|
|
188
|
+
*/
|
|
189
|
+
roleOf(id) {
|
|
190
|
+
if (this.isOwner(id))
|
|
191
|
+
return 'owner';
|
|
192
|
+
const found = this.read().people.find((p) => p.id === id);
|
|
193
|
+
if (!found)
|
|
194
|
+
return PEOPLE_CONSTANTS.DEFAULT_ROLE;
|
|
195
|
+
return found.role === 'owner' ? 'member' : found.role;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* How to name a person to others.
|
|
199
|
+
*
|
|
200
|
+
* @param id - Person id
|
|
201
|
+
* @returns Their name, "the owner" for an owner without one, else the id
|
|
202
|
+
*/
|
|
203
|
+
displayName(id) {
|
|
204
|
+
const person = this.get(id);
|
|
205
|
+
if (person?.name)
|
|
206
|
+
return person.name;
|
|
207
|
+
return this.isOwner(id) ? 'the owner' : id;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Record a Slack user who messaged an agent (added as a member the first
|
|
211
|
+
* time; a missing name is filled in). Never changes a role.
|
|
212
|
+
*
|
|
213
|
+
* @param id - Slack user id
|
|
214
|
+
* @param name - Their display name, when known
|
|
215
|
+
*/
|
|
216
|
+
noteSeen(id, name) {
|
|
217
|
+
if (!PEOPLE_CONSTANTS.SLACK_USER_ID_PATTERN.test(id))
|
|
218
|
+
return;
|
|
219
|
+
// A bot is never a person.
|
|
220
|
+
if (this.isBot(id))
|
|
221
|
+
return;
|
|
222
|
+
// The owner is the `owner` row, never a member row of their own.
|
|
223
|
+
if (this.isOwner(id)) {
|
|
224
|
+
const cleanOwnerName = cleanPersonName(name);
|
|
225
|
+
if (cleanOwnerName && !this.get(PEOPLE_CONSTANTS.OWNER_ID)?.name)
|
|
226
|
+
this.upsert(PEOPLE_CONSTANTS.OWNER_ID, { name: cleanOwnerName });
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const file = this.read();
|
|
230
|
+
const existing = file.people.find((p) => p.id === id);
|
|
231
|
+
const cleanName = cleanPersonName(name);
|
|
232
|
+
if (existing) {
|
|
233
|
+
if (cleanName && !existing.name) {
|
|
234
|
+
existing.name = cleanName;
|
|
235
|
+
existing.updatedAt = new Date(this.now()).toISOString();
|
|
236
|
+
this.write(file);
|
|
237
|
+
}
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const iso = new Date(this.now()).toISOString();
|
|
241
|
+
file.people.push({
|
|
242
|
+
id,
|
|
243
|
+
...(cleanName ? { name: cleanName } : {}),
|
|
244
|
+
role: PEOPLE_CONSTANTS.DEFAULT_ROLE,
|
|
245
|
+
source: 'auto',
|
|
246
|
+
createdAt: iso,
|
|
247
|
+
updatedAt: iso,
|
|
248
|
+
});
|
|
249
|
+
this.write(file);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Add or edit a person (owner action). Giving a Slack id the `owner` role
|
|
253
|
+
* marks it as the owner's own Slack account (for installs that cannot
|
|
254
|
+
* tell, e.g. Slack credentials from env): it then maps to `owner`.
|
|
255
|
+
*
|
|
256
|
+
* @param id - Slack user id
|
|
257
|
+
* @param patch - Name and/or role
|
|
258
|
+
* @returns The person
|
|
259
|
+
* @throws PeopleDirectoryError on an invalid id or role, a bot, or when changing the owner's role
|
|
260
|
+
*/
|
|
261
|
+
upsert(id, patch) {
|
|
262
|
+
if (!isPersonId(id))
|
|
263
|
+
throw new PeopleDirectoryError('A person is a Slack user id like U0123ABCD');
|
|
264
|
+
if (patch.role !== undefined && !isPersonRole(patch.role))
|
|
265
|
+
throw new PeopleDirectoryError('role must be owner, member or guest');
|
|
266
|
+
if (this.isBot(id))
|
|
267
|
+
throw new PeopleDirectoryError("That Slack id is one of Crewly's bots, not a person");
|
|
268
|
+
const owner = this.isOwner(id);
|
|
269
|
+
if (owner && patch.role !== undefined && patch.role !== 'owner')
|
|
270
|
+
throw new PeopleDirectoryError("The instance owner's role can't be changed");
|
|
271
|
+
if (patch.name !== undefined && patch.name !== null && typeof patch.name !== 'string')
|
|
272
|
+
throw new PeopleDirectoryError('name must be text');
|
|
273
|
+
if (!owner && patch.role === 'owner') {
|
|
274
|
+
this.markOwnerSlackId(id);
|
|
275
|
+
return patch.name !== undefined ? this.upsert(PEOPLE_CONSTANTS.OWNER_ID, { name: patch.name }) : this.get(PEOPLE_CONSTANTS.OWNER_ID);
|
|
276
|
+
}
|
|
277
|
+
const file = this.read();
|
|
278
|
+
const key = owner ? PEOPLE_CONSTANTS.OWNER_ID : id;
|
|
279
|
+
const iso = new Date(this.now()).toISOString();
|
|
280
|
+
let person = file.people.find((p) => p.id === key);
|
|
281
|
+
if (!person) {
|
|
282
|
+
person = { id: key, role: owner ? 'owner' : PEOPLE_CONSTANTS.DEFAULT_ROLE, source: 'owner', createdAt: iso, updatedAt: iso };
|
|
283
|
+
file.people.push(person);
|
|
284
|
+
}
|
|
285
|
+
if (patch.name !== undefined) {
|
|
286
|
+
const name = cleanPersonName(patch.name);
|
|
287
|
+
if (name)
|
|
288
|
+
person.name = name;
|
|
289
|
+
else
|
|
290
|
+
delete person.name;
|
|
291
|
+
}
|
|
292
|
+
if (patch.role !== undefined)
|
|
293
|
+
person.role = patch.role;
|
|
294
|
+
person.source = 'owner';
|
|
295
|
+
person.updatedAt = iso;
|
|
296
|
+
this.write(file);
|
|
297
|
+
return this.get(key);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Remove a person (they come back as a member if they message an agent again).
|
|
301
|
+
*
|
|
302
|
+
* @param id - Person id
|
|
303
|
+
* @returns True when removed
|
|
304
|
+
* @throws PeopleDirectoryError for the owner
|
|
305
|
+
*/
|
|
306
|
+
remove(id) {
|
|
307
|
+
if (this.isOwner(id))
|
|
308
|
+
throw new PeopleDirectoryError("The instance owner can't be removed");
|
|
309
|
+
const file = this.read();
|
|
310
|
+
const before = file.people.length;
|
|
311
|
+
file.people = file.people.filter((p) => p.id !== id);
|
|
312
|
+
if (file.people.length === before)
|
|
313
|
+
return false;
|
|
314
|
+
this.write(file);
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Record a Slack id as the owner's own and drop any member row it had.
|
|
319
|
+
*
|
|
320
|
+
* @param id - Slack user id
|
|
321
|
+
*/
|
|
322
|
+
markOwnerSlackId(id) {
|
|
323
|
+
const file = this.readRaw();
|
|
324
|
+
const ids = new Set(file.ownerSlackUserIds ?? []);
|
|
325
|
+
ids.add(id);
|
|
326
|
+
const name = file.people.find((p) => p.id === id)?.name;
|
|
327
|
+
file.people = file.people.filter((p) => p.id !== id);
|
|
328
|
+
file.ownerSlackUserIds = [...ids];
|
|
329
|
+
if (name && !file.people.some((p) => p.id === PEOPLE_CONSTANTS.OWNER_ID)) {
|
|
330
|
+
const iso = new Date(this.now()).toISOString();
|
|
331
|
+
file.people.push({ id: PEOPLE_CONSTANTS.OWNER_ID, name, role: 'owner', source: 'owner', createdAt: iso, updatedAt: iso });
|
|
332
|
+
}
|
|
333
|
+
this.write(file);
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* The stored file, without bots. Bot rows found on disk (written by an
|
|
337
|
+
* earlier version that recorded agent posts as people) are removed from
|
|
338
|
+
* the file here (best effort).
|
|
339
|
+
*
|
|
340
|
+
* @returns The stored file (empty when missing or unreadable)
|
|
341
|
+
*/
|
|
342
|
+
read() {
|
|
343
|
+
const file = this.readRaw();
|
|
344
|
+
const people = file.people.filter((p) => !this.isBot(p.id));
|
|
345
|
+
if (people.length === file.people.length)
|
|
346
|
+
return file;
|
|
347
|
+
const cleaned = { ...file, people };
|
|
348
|
+
try {
|
|
349
|
+
this.write(cleaned);
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// cleaned in memory; retried on the next read
|
|
353
|
+
}
|
|
354
|
+
return cleaned;
|
|
355
|
+
}
|
|
356
|
+
/** @returns The stored file as on disk (valid rows only; empty when missing or unreadable) */
|
|
357
|
+
readRaw() {
|
|
358
|
+
try {
|
|
359
|
+
const raw = JSON.parse(fs.readFileSync(this.filePath(), 'utf-8'));
|
|
360
|
+
const obj = raw && typeof raw === 'object' ? raw : {};
|
|
361
|
+
const people = Array.isArray(obj.people) ? obj.people : [];
|
|
362
|
+
const ownerIds = Array.isArray(obj.ownerSlackUserIds)
|
|
363
|
+
? obj.ownerSlackUserIds.filter((id) => typeof id === 'string' && PEOPLE_CONSTANTS.SLACK_USER_ID_PATTERN.test(id))
|
|
364
|
+
: [];
|
|
365
|
+
return {
|
|
366
|
+
version: 1,
|
|
367
|
+
people: people.filter((p) => !!p && isPersonId(p.id) && isPersonRole(p.role)),
|
|
368
|
+
...(ownerIds.length > 0 ? { ownerSlackUserIds: ownerIds } : {}),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
return { version: 1, people: [] };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Write atomically.
|
|
377
|
+
*
|
|
378
|
+
* @param file - Contents
|
|
379
|
+
*/
|
|
380
|
+
write(file) {
|
|
381
|
+
const target = this.filePath();
|
|
382
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
383
|
+
const tmp = `${target}.${process.pid}.tmp`;
|
|
384
|
+
fs.writeFileSync(tmp, `${JSON.stringify(file, null, 2)}\n`, 'utf-8');
|
|
385
|
+
fs.renameSync(tmp, target);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Trim and bound a display name.
|
|
390
|
+
*
|
|
391
|
+
* @param name - Raw name
|
|
392
|
+
* @returns Clean name, or undefined when empty
|
|
393
|
+
*/
|
|
394
|
+
export function cleanPersonName(name) {
|
|
395
|
+
if (typeof name !== 'string')
|
|
396
|
+
return undefined;
|
|
397
|
+
const trimmed = name.replace(/\s+/g, ' ').trim().slice(0, PEOPLE_CONSTANTS.MAX_NAME_LENGTH);
|
|
398
|
+
return trimmed || undefined;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Record a Slack user who messaged an agent, with their name (best effort,
|
|
402
|
+
* never throws).
|
|
403
|
+
*
|
|
404
|
+
* @param slackUserId - Slack user id
|
|
405
|
+
* @param name - Display name, when known
|
|
406
|
+
*/
|
|
407
|
+
export function notePerson(slackUserId, name) {
|
|
408
|
+
try {
|
|
409
|
+
getPeopleDirectory().noteSeen(slackUserId, name ?? undefined);
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
// the directory is a convenience here
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
let instance = null;
|
|
416
|
+
let ownerLookup = null;
|
|
417
|
+
let botLookup = null;
|
|
418
|
+
/**
|
|
419
|
+
* Tell the directory how to find the owner's Slack id (wired once Slack is up).
|
|
420
|
+
*
|
|
421
|
+
* @param lookup - Lookup, or null
|
|
422
|
+
*/
|
|
423
|
+
export function setPeopleOwnerLookup(lookup) {
|
|
424
|
+
ownerLookup = lookup;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Tell the directory how to recognise Crewly's bots (wired once Slack is up).
|
|
428
|
+
*
|
|
429
|
+
* @param lookup - Whether a Slack user id is a bot, or null
|
|
430
|
+
*/
|
|
431
|
+
export function setPeopleBotLookup(lookup) {
|
|
432
|
+
botLookup = lookup;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* The backend's people directory.
|
|
436
|
+
*
|
|
437
|
+
* @returns Singleton
|
|
438
|
+
*/
|
|
439
|
+
export function getPeopleDirectory() {
|
|
440
|
+
instance ??= new PeopleDirectoryService({
|
|
441
|
+
getOwnerSlackUserId: () => ownerLookup?.() ?? null,
|
|
442
|
+
isBot: (id) => botLookup?.(id) ?? false,
|
|
443
|
+
});
|
|
444
|
+
return instance;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Replace the singleton (tests).
|
|
448
|
+
*
|
|
449
|
+
* @param service - Instance, or null to reset
|
|
450
|
+
*/
|
|
451
|
+
export function setPeopleDirectoryForTesting(service) {
|
|
452
|
+
instance = service;
|
|
453
|
+
}
|
|
454
|
+
//# sourceMappingURL=people-directory.service.js.map
|