crewly 1.20.302 → 1.20.304
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/roles/developer/prompt.md +7 -0
- package/config/roles/fullstack-dev/prompt.md +7 -0
- package/config/roles/product-manager/prompt.md +7 -0
- package/config/skills/orchestrator/move-team/SKILL.md +53 -0
- package/config/skills/orchestrator/move-team/execute.sh +42 -0
- package/config/skills/orchestrator/usage-categories/SKILL.md +59 -0
- package/config/skills/orchestrator/usage-categories/execute.sh +81 -0
- package/config/skills/orchestrator/usage-categories/execute.test.sh +45 -0
- package/config/skills/orchestrator/usage-report/SKILL.md +71 -0
- package/config/skills/orchestrator/usage-report/execute.sh +84 -0
- package/config/skills/orchestrator/usage-report/execute.test.sh +39 -0
- package/config/skills/team-leader/usage-report/SKILL.md +71 -0
- package/config/skills/team-leader/usage-report/execute.sh +84 -0
- package/config/skills/team-leader/usage-report/execute.test.sh +39 -0
- package/dist/backend/backend/src/constants.d.ts +80 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +80 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts +45 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.js +214 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.d.ts +36 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.js +158 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.d.ts +15 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.js +26 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts +10 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +97 -20
- 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/follow-through.wiring.d.ts +32 -0
- package/dist/backend/backend/src/services/agent/follow-through.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/follow-through.wiring.js +42 -1
- package/dist/backend/backend/src/services/agent/follow-through.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts +26 -6
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.js +59 -5
- package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- 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 +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.d.ts +18 -0
- package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.js +16 -0
- package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts +19 -0
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +46 -0
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.d.ts +35 -0
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.js +101 -0
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.d.ts +58 -0
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.d.ts.map +1 -0
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.js +100 -0
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.js.map +1 -0
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js +3 -0
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +7 -0
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +15 -0
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +2 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.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 +25 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +24 -0
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +63 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +19 -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 +41 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts +122 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.js +202 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts +59 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.js +133 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js +217 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.js +348 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts +209 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.js +504 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts +156 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js +462 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts +157 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.js +298 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.d.ts +69 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.js +198 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts +121 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.js +462 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts +110 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.js +198 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts +71 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.js +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts +29 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js +173 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts +50 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js +96 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.d.ts +94 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.js +124 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts +46 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.js +202 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts +269 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.js +44 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts +42 -2
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-context.service.js +66 -5
- package/dist/backend/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-recorder.d.ts.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-recorder.js +11 -0
- package/dist/backend/backend/src/services/trace/trace-recorder.js.map +1 -1
- package/dist/backend/backend/src/services/usage-ledger/categories-param.d.ts +28 -0
- package/dist/backend/backend/src/services/usage-ledger/categories-param.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/categories-param.js +67 -0
- package/dist/backend/backend/src/services/usage-ledger/categories-param.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.d.ts +37 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.js +49 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/index.d.ts +14 -0
- package/dist/backend/backend/src/services/usage-ledger/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/index.js +14 -0
- package/dist/backend/backend/src/services/usage-ledger/index.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.d.ts +44 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.js +52 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.d.ts +100 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.js +189 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.d.ts +41 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.js +71 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.d.ts +47 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.js +106 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.d.ts +101 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.js +263 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.d.ts +96 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.js +166 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.d.ts +90 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.js +294 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.d.ts +102 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.js +314 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.d.ts +62 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.js +106 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.d.ts +52 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.js +95 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.d.ts +127 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.js +19 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.d.ts +124 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.js +372 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +80 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +80 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts +26 -6
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.js +59 -5
- package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- 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 +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.d.ts +18 -0
- package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.js +16 -0
- package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts +19 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js +46 -0
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.d.ts +35 -0
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.d.ts.map +1 -1
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.js +101 -0
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js +3 -0
- package/dist/cli/backend/src/services/monitoring/token-usage.service.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 +25 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +24 -0
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +63 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- 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 +41 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts +42 -2
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-context.service.js +66 -5
- package/dist/cli/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-recorder.d.ts.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-recorder.js +11 -0
- package/dist/cli/backend/src/services/trace/trace-recorder.js.map +1 -1
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.d.ts +44 -0
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.d.ts.map +1 -0
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.js +52 -0
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.js.map +1 -0
- package/dist/cli/cli/src/commands/team-move.d.ts +68 -0
- package/dist/cli/cli/src/commands/team-move.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/team-move.js +155 -0
- package/dist/cli/cli/src/commands/team-move.js.map +1 -0
- package/dist/cli/cli/src/index.js +33 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team move importer (target machine).
|
|
3
|
+
*
|
|
4
|
+
* Takes a downloaded, encrypted package and applies it to this machine in
|
|
5
|
+
* idempotent, journaled steps, so a crash or restart resumes where it stopped:
|
|
6
|
+
*
|
|
7
|
+
* decrypt -> validate -> projects -> repos -> project data -> agents ->
|
|
8
|
+
* records -> team -> start -> report
|
|
9
|
+
*
|
|
10
|
+
* The team is registered (and therefore started) only after every other piece
|
|
11
|
+
* is in place. Project folders are relocated under this machine's projects
|
|
12
|
+
* root; the mapping is recorded and absolute paths inside the moved text files
|
|
13
|
+
* are rewritten to match. Repositories are cloned at the recorded branch and
|
|
14
|
+
* commit with this machine's own git credentials.
|
|
15
|
+
*
|
|
16
|
+
* @module services/team-move/team-move-importer
|
|
17
|
+
*/
|
|
18
|
+
import { createHash } from 'node:crypto';
|
|
19
|
+
import { createReadStream } from 'node:fs';
|
|
20
|
+
import * as fs from 'node:fs/promises';
|
|
21
|
+
import * as os from 'node:os';
|
|
22
|
+
import * as path from 'node:path';
|
|
23
|
+
import { pipeline } from 'node:stream/promises';
|
|
24
|
+
import { extract as tarExtract } from 'tar';
|
|
25
|
+
import { TEAM_MOVE_CONSTANTS } from '../../constants.js';
|
|
26
|
+
import { atomicWriteFile } from '../../utils/file-io.utils.js';
|
|
27
|
+
import { getCrewlyHomePath, resolveProjectDataDir } from '../core/crewly-home.utils.js';
|
|
28
|
+
import { applyTeamChat } from './team-move-chat.js';
|
|
29
|
+
import { createDecryptStream } from './team-move-crypto.js';
|
|
30
|
+
import { hasTextExtension, looksLikeText, pathExists, rewritePathPrefix, sha256File, slugify, walkFiles, writeFileAtomic } from './team-move-fs.js';
|
|
31
|
+
import { restoreRepo } from './team-move-git.js';
|
|
32
|
+
import { MoveJournal } from './team-move-journal.js';
|
|
33
|
+
import { checkTools, hasRoomFor } from './team-move-preflight.js';
|
|
34
|
+
const C = TEAM_MOVE_CONSTANTS;
|
|
35
|
+
/** Where the owner reconnects connectors (Google, Zoho, ...). */
|
|
36
|
+
const CONNECTIONS_URL = 'https://crewlyai.com/connections';
|
|
37
|
+
/** Thrown for a package this machine must not apply. */
|
|
38
|
+
export class TeamMoveImportError extends Error {
|
|
39
|
+
code;
|
|
40
|
+
constructor(message, code = 'invalid_package') {
|
|
41
|
+
super(message);
|
|
42
|
+
this.code = code;
|
|
43
|
+
this.name = 'TeamMoveImportError';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** The projects root of this machine. */
|
|
47
|
+
export function projectsRoot(env = process.env, homeDir = os.homedir()) {
|
|
48
|
+
const fromEnv = env[C.PROJECTS_ROOT_ENV];
|
|
49
|
+
return fromEnv && fromEnv.length > 0 ? path.resolve(fromEnv) : path.join(homeDir, C.DEFAULT_PROJECTS_DIR_NAME);
|
|
50
|
+
}
|
|
51
|
+
/** The importer. */
|
|
52
|
+
export class TeamMoveImporter {
|
|
53
|
+
deps;
|
|
54
|
+
home;
|
|
55
|
+
now;
|
|
56
|
+
restore;
|
|
57
|
+
constructor(deps) {
|
|
58
|
+
this.deps = deps;
|
|
59
|
+
this.home = deps.home ?? getCrewlyHomePath();
|
|
60
|
+
this.now = deps.now ?? (() => new Date().toISOString());
|
|
61
|
+
this.restore = deps.restoreRepo ?? restoreRepo;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Apply a package. Safe to call again for the same move: finished steps are
|
|
65
|
+
* skipped.
|
|
66
|
+
*
|
|
67
|
+
* @param input - Move id, package file and key
|
|
68
|
+
* @param journal - Journal of this move
|
|
69
|
+
* @returns The report for the owner
|
|
70
|
+
* @throws TeamMoveImportError for a package that must not be applied
|
|
71
|
+
*/
|
|
72
|
+
async run(input, journal = new MoveJournal(input.moveId, this.home, this.now)) {
|
|
73
|
+
const staging = path.join(journal.dir, 'staging');
|
|
74
|
+
const step = (name, fn) => journal.run(name, fn);
|
|
75
|
+
await step('download', async () => {
|
|
76
|
+
const stat = await fs.stat(input.packageFile).catch(() => null);
|
|
77
|
+
if (!stat?.isFile())
|
|
78
|
+
throw new TeamMoveImportError('package file is missing', 'invalid_package');
|
|
79
|
+
if (input.expectedSha256) {
|
|
80
|
+
const actual = await sha256File(input.packageFile);
|
|
81
|
+
if (actual !== input.expectedSha256.toLowerCase())
|
|
82
|
+
throw new TeamMoveImportError('package hash does not match what Cloud stored', 'invalid_package');
|
|
83
|
+
}
|
|
84
|
+
return { bytes: stat.size };
|
|
85
|
+
});
|
|
86
|
+
await step('decrypt', async () => {
|
|
87
|
+
await fs.rm(staging, { recursive: true, force: true });
|
|
88
|
+
await fs.mkdir(staging, { recursive: true });
|
|
89
|
+
await pipeline(createReadStream(input.packageFile), createDecryptStream({ privateKey: input.privateKey, moveId: input.moveId }), tarExtract({
|
|
90
|
+
cwd: staging,
|
|
91
|
+
strict: true,
|
|
92
|
+
preservePaths: false,
|
|
93
|
+
// Only plain files and folders: no links, devices or other entries.
|
|
94
|
+
filter: (_p, entry) => {
|
|
95
|
+
const type = entry.type;
|
|
96
|
+
return type === 'File' || type === 'Directory';
|
|
97
|
+
},
|
|
98
|
+
}));
|
|
99
|
+
return { staged: true };
|
|
100
|
+
});
|
|
101
|
+
const manifest = await step('validate', () => this.validate(input, staging));
|
|
102
|
+
const mappings = await step('projects', () => this.registerProjects(manifest, journal));
|
|
103
|
+
const repoOutcome = await step('repos', () => this.cloneRepos(manifest, mappings));
|
|
104
|
+
const dataCounts = await step('data', () => this.importData(staging, manifest, mappings));
|
|
105
|
+
const recordCounts = await step('records', () => this.importRecords(staging, manifest, mappings));
|
|
106
|
+
const teamResult = await step('team', () => this.registerTeam(staging, manifest, mappings));
|
|
107
|
+
const started = await step('start', () => this.startTeam(manifest, teamResult.paused));
|
|
108
|
+
return step('report', async () => {
|
|
109
|
+
const report = await this.buildReport(manifest, mappings, repoOutcome, dataCounts, recordCounts, started);
|
|
110
|
+
await atomicWriteFile(path.join(journal.dir, 'import-report.json'), JSON.stringify(report, null, 2));
|
|
111
|
+
// The decrypted copy and the ciphertext are no longer needed.
|
|
112
|
+
await fs.rm(staging, { recursive: true, force: true });
|
|
113
|
+
await fs.rm(input.packageFile, { force: true });
|
|
114
|
+
return report;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// -------------------------------------------------------------------------
|
|
118
|
+
// validate
|
|
119
|
+
// -------------------------------------------------------------------------
|
|
120
|
+
async validate(input, staging) {
|
|
121
|
+
const raw = await fs.readFile(path.join(staging, 'manifest.json'), 'utf8').catch(() => null);
|
|
122
|
+
if (!raw)
|
|
123
|
+
throw new TeamMoveImportError('the package has no manifest', 'invalid_package');
|
|
124
|
+
let manifest;
|
|
125
|
+
try {
|
|
126
|
+
manifest = JSON.parse(raw);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
throw new TeamMoveImportError('the package manifest is not valid JSON', 'invalid_package');
|
|
130
|
+
}
|
|
131
|
+
if (manifest.kind !== C.PACKAGE_KIND)
|
|
132
|
+
throw new TeamMoveImportError('not a team move package', 'invalid_package');
|
|
133
|
+
if (manifest.schemaVersion !== C.SCHEMA_VERSION) {
|
|
134
|
+
throw new TeamMoveImportError(`package schema ${manifest.schemaVersion} is not supported (this machine reads ${C.SCHEMA_VERSION}); update Crewly here`, 'unsupported');
|
|
135
|
+
}
|
|
136
|
+
if (manifest.moveId !== input.moveId)
|
|
137
|
+
throw new TeamMoveImportError('the package belongs to another move', 'invalid_package');
|
|
138
|
+
if (manifest.noSecrets !== true)
|
|
139
|
+
throw new TeamMoveImportError('the package was not secret-scanned', 'invalid_package');
|
|
140
|
+
if (!manifest.team?.id || !Array.isArray(manifest.files))
|
|
141
|
+
throw new TeamMoveImportError('the package manifest is incomplete', 'invalid_package');
|
|
142
|
+
// Every listed file must be there with the recorded hash, and nothing else.
|
|
143
|
+
const listed = new Map(manifest.files.map((f) => [f.path, f]));
|
|
144
|
+
for (const f of manifest.files) {
|
|
145
|
+
if (f.path.includes('..') || path.isAbsolute(f.path))
|
|
146
|
+
throw new TeamMoveImportError(`unsafe path in package: ${f.path}`, 'invalid_package');
|
|
147
|
+
const abs = path.join(staging, ...f.path.split('/'));
|
|
148
|
+
const actual = await sha256File(abs).catch(() => null);
|
|
149
|
+
if (actual !== f.sha256)
|
|
150
|
+
throw new TeamMoveImportError(`package file is missing or altered: ${f.path}`, 'invalid_package');
|
|
151
|
+
}
|
|
152
|
+
for await (const f of walkFiles(staging)) {
|
|
153
|
+
if (f.rel !== 'manifest.json' && !listed.has(f.rel))
|
|
154
|
+
throw new TeamMoveImportError(`unexpected file in package: ${f.rel}`, 'invalid_package');
|
|
155
|
+
}
|
|
156
|
+
// Conflicts: a live team with this id, or a session name already taken.
|
|
157
|
+
const teams = await this.deps.storage.getTeams();
|
|
158
|
+
const existing = teams.find((t) => t.id === manifest.team.id);
|
|
159
|
+
if (existing && !existing.moveArchive) {
|
|
160
|
+
throw new TeamMoveImportError(`this machine already has a team with the id ${manifest.team.id} ("${existing.name}")`, 'conflict');
|
|
161
|
+
}
|
|
162
|
+
const sessions = new Set(manifest.team.members.map((m) => m.sessionName));
|
|
163
|
+
for (const t of teams) {
|
|
164
|
+
if (t.id === manifest.team.id)
|
|
165
|
+
continue;
|
|
166
|
+
const clash = t.members.find((m) => sessions.has(m.sessionName));
|
|
167
|
+
if (clash)
|
|
168
|
+
throw new TeamMoveImportError(`agent session ${clash.sessionName} already exists in team "${t.name}" on this machine`, 'conflict');
|
|
169
|
+
}
|
|
170
|
+
// The package is unpacked already; the live copies need the same room again.
|
|
171
|
+
const free = await (this.deps.freeDisk ?? (async () => null))(this.home);
|
|
172
|
+
if (free !== null && !hasRoomFor(free, 0, manifest.totalBytes)) {
|
|
173
|
+
throw new TeamMoveImportError('not enough free disk space to import the team', 'no_space');
|
|
174
|
+
}
|
|
175
|
+
return manifest;
|
|
176
|
+
}
|
|
177
|
+
// -------------------------------------------------------------------------
|
|
178
|
+
// projects and repos
|
|
179
|
+
// -------------------------------------------------------------------------
|
|
180
|
+
/**
|
|
181
|
+
* Decide where each project lives here and register it under its own id.
|
|
182
|
+
* A project that already exists here (same id) keeps its folder.
|
|
183
|
+
*/
|
|
184
|
+
async registerProjects(manifest, journal) {
|
|
185
|
+
const root = projectsRoot();
|
|
186
|
+
const known = await this.deps.storage.getProjects();
|
|
187
|
+
const mappings = [];
|
|
188
|
+
const taken = new Set(known.map((p) => path.resolve(p.path)));
|
|
189
|
+
for (const p of manifest.projects) {
|
|
190
|
+
const existing = known.find((k) => k.id === p.id);
|
|
191
|
+
if (existing) {
|
|
192
|
+
mappings.push({ projectId: p.id, name: p.name, from: p.sourcePath, to: existing.path, existing: true });
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
let target = path.join(root, slugify(p.name));
|
|
196
|
+
// A folder already holding something other than Crewly's own data is not ours to reuse.
|
|
197
|
+
if (taken.has(target) || (await this.hasForeignContent(target)))
|
|
198
|
+
target = path.join(root, `${slugify(p.name)}-${p.id.slice(0, 8)}`);
|
|
199
|
+
taken.add(target);
|
|
200
|
+
mappings.push({ projectId: p.id, name: p.name, from: p.sourcePath, to: target, existing: false });
|
|
201
|
+
}
|
|
202
|
+
for (const m of mappings) {
|
|
203
|
+
if (m.existing)
|
|
204
|
+
continue;
|
|
205
|
+
await fs.mkdir(m.to, { recursive: true });
|
|
206
|
+
const at = this.now();
|
|
207
|
+
await this.deps.storage.saveProject({ id: m.projectId, name: m.name, path: m.to, teams: {}, status: 'stopped', createdAt: at, updatedAt: at });
|
|
208
|
+
}
|
|
209
|
+
await journal.ensure();
|
|
210
|
+
await atomicWriteFile(path.join(journal.dir, 'path-mapping.json'), JSON.stringify(mappings, null, 2));
|
|
211
|
+
return mappings;
|
|
212
|
+
}
|
|
213
|
+
async hasForeignContent(dir) {
|
|
214
|
+
const entries = await fs.readdir(dir).catch(() => null);
|
|
215
|
+
if (!entries)
|
|
216
|
+
return false;
|
|
217
|
+
return entries.some((e) => e !== '.crewly' && e !== '.git');
|
|
218
|
+
}
|
|
219
|
+
/** Clone each project's repository at the recorded branch and commit. */
|
|
220
|
+
async cloneRepos(manifest, mappings) {
|
|
221
|
+
const cloned = [];
|
|
222
|
+
const failed = [];
|
|
223
|
+
const warnings = [];
|
|
224
|
+
for (const repo of manifest.repos) {
|
|
225
|
+
const mapping = mappings.find((m) => m.projectId === repo.projectId);
|
|
226
|
+
if (!mapping)
|
|
227
|
+
continue;
|
|
228
|
+
if (mapping.existing) {
|
|
229
|
+
// The project was already here under this id: its checkout is not ours to move.
|
|
230
|
+
warnings.push(`${repo.projectName} already exists on this machine (${mapping.to}); its checkout was left as it is.`);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (!repo.remoteUrl) {
|
|
234
|
+
const plain = repo.note?.startsWith('not a git repository') || repo.note?.startsWith('project folder does not exist');
|
|
235
|
+
if (plain)
|
|
236
|
+
warnings.push(`${repo.projectName}: ${repo.note}.`);
|
|
237
|
+
else
|
|
238
|
+
failed.push({ name: repo.projectName, reason: repo.note ?? 'no git remote on the source; copy the code by hand' });
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
const result = await this.restore(mapping.to, repo);
|
|
242
|
+
for (const w of result.warnings)
|
|
243
|
+
warnings.push(`${repo.projectName}: ${w}`);
|
|
244
|
+
if (result.ok)
|
|
245
|
+
cloned.push({ name: repo.projectName, path: mapping.to, branch: result.branch, headSha: result.headSha });
|
|
246
|
+
else
|
|
247
|
+
failed.push({ name: repo.projectName, reason: result.error ?? 'clone failed' });
|
|
248
|
+
}
|
|
249
|
+
return { repos: { cloned, failed }, warnings };
|
|
250
|
+
}
|
|
251
|
+
// -------------------------------------------------------------------------
|
|
252
|
+
// data
|
|
253
|
+
// -------------------------------------------------------------------------
|
|
254
|
+
/**
|
|
255
|
+
* Copy a package directory into a destination. A file that exists with other
|
|
256
|
+
* content is replaced (the package is the team's state) and the old copy is
|
|
257
|
+
* kept next to it as `<name>.pre-move-<id>`. Text files get this machine's
|
|
258
|
+
* paths. Writes are atomic, so a crash never leaves a half file.
|
|
259
|
+
*/
|
|
260
|
+
async copyTree(srcRoot, destRoot, rewrites, tag, skip = () => false) {
|
|
261
|
+
const counts = { written: 0, unchanged: 0, replaced: 0, rewritten: 0 };
|
|
262
|
+
for await (const f of walkFiles(srcRoot)) {
|
|
263
|
+
if (skip(f.rel))
|
|
264
|
+
continue;
|
|
265
|
+
const dest = path.join(destRoot, ...f.rel.split('/'));
|
|
266
|
+
let content = await fs.readFile(f.abs);
|
|
267
|
+
if (rewrites.length > 0 && f.size <= C.TEXT_FILE_MAX_BYTES && hasTextExtension(f.abs) && looksLikeText(content)) {
|
|
268
|
+
let text = content.toString('utf8');
|
|
269
|
+
let changed = 0;
|
|
270
|
+
for (const [from, to] of rewrites) {
|
|
271
|
+
const r = rewritePathPrefix(text, from, to);
|
|
272
|
+
text = r.text;
|
|
273
|
+
changed += r.count;
|
|
274
|
+
}
|
|
275
|
+
if (changed > 0) {
|
|
276
|
+
content = Buffer.from(text, 'utf8');
|
|
277
|
+
counts.rewritten += 1;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const current = await fs.readFile(dest).catch(() => null);
|
|
281
|
+
if (current) {
|
|
282
|
+
if (createHash('sha256').update(current).digest('hex') === createHash('sha256').update(content).digest('hex')) {
|
|
283
|
+
counts.unchanged += 1;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const backup = `${dest}.pre-move-${tag}`;
|
|
287
|
+
if (!(await pathExists(backup)))
|
|
288
|
+
await fs.writeFile(backup, current);
|
|
289
|
+
counts.replaced += 1;
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
counts.written += 1;
|
|
293
|
+
}
|
|
294
|
+
await writeFileAtomic(dest, content);
|
|
295
|
+
}
|
|
296
|
+
return counts;
|
|
297
|
+
}
|
|
298
|
+
/** Project data, agent memory and handover notes. */
|
|
299
|
+
async importData(staging, manifest, mappings) {
|
|
300
|
+
const tag = manifest.moveId.slice(0, 8);
|
|
301
|
+
const rewrites = this.rewritesFor(manifest, mappings);
|
|
302
|
+
const total = { written: 0, unchanged: 0, replaced: 0, rewritten: 0 };
|
|
303
|
+
const add = (c) => {
|
|
304
|
+
total.written += c.written;
|
|
305
|
+
total.unchanged += c.unchanged;
|
|
306
|
+
total.replaced += c.replaced;
|
|
307
|
+
total.rewritten += c.rewritten;
|
|
308
|
+
};
|
|
309
|
+
for (const p of manifest.projects) {
|
|
310
|
+
const mapping = mappings.find((m) => m.projectId === p.id);
|
|
311
|
+
const src = path.join(staging, 'projects', p.id, 'data');
|
|
312
|
+
const dest = this.projectDataDir(p, mapping.to);
|
|
313
|
+
add(await this.copyTree(src, dest, rewrites, tag));
|
|
314
|
+
}
|
|
315
|
+
for (const member of manifest.team.members) {
|
|
316
|
+
add(await this.copyTree(path.join(staging, 'agents', member.sessionName), path.join(this.home, 'agents', member.sessionName), rewrites, tag));
|
|
317
|
+
}
|
|
318
|
+
add(await this.copyTree(path.join(staging, 'handover'), path.join(this.home, 'handover'), rewrites, tag));
|
|
319
|
+
return { filesWritten: total.written, filesUnchanged: total.unchanged, filesReplaced: total.replaced, pathsRewritten: total.rewritten };
|
|
320
|
+
}
|
|
321
|
+
projectDataDir(project, targetPath) {
|
|
322
|
+
return project.dataDir === 'home' ? this.home : resolveProjectDataDir(targetPath);
|
|
323
|
+
}
|
|
324
|
+
/** Source path to target path rewrites for the moved text files. */
|
|
325
|
+
rewritesFor(manifest, mappings) {
|
|
326
|
+
const out = [];
|
|
327
|
+
// Longest source path first so a nested project is not clobbered by its parent.
|
|
328
|
+
for (const m of [...mappings].sort((a, b) => b.from.length - a.from.length)) {
|
|
329
|
+
if (m.from !== m.to)
|
|
330
|
+
out.push([m.from, m.to]);
|
|
331
|
+
}
|
|
332
|
+
if (manifest.source.homePath && manifest.source.homePath !== this.home)
|
|
333
|
+
out.push([manifest.source.homePath, this.home]);
|
|
334
|
+
return out;
|
|
335
|
+
}
|
|
336
|
+
// -------------------------------------------------------------------------
|
|
337
|
+
// records
|
|
338
|
+
// -------------------------------------------------------------------------
|
|
339
|
+
async readRecord(staging, rel, rewrites, fallback) {
|
|
340
|
+
let text = await fs.readFile(path.join(staging, rel), 'utf8').catch(() => null);
|
|
341
|
+
if (text === null)
|
|
342
|
+
return fallback;
|
|
343
|
+
for (const [from, to] of rewrites)
|
|
344
|
+
text = rewritePathPrefix(text, from, to).text;
|
|
345
|
+
try {
|
|
346
|
+
return JSON.parse(text);
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
return fallback;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/** Task-pool items, decisions, scheduled messages, chat channels, Slack mapping. */
|
|
353
|
+
async importRecords(staging, manifest, mappings) {
|
|
354
|
+
const rewrites = this.rewritesFor(manifest, mappings);
|
|
355
|
+
const out = {};
|
|
356
|
+
// The Slack mapping first: the team's channel must be known before the team
|
|
357
|
+
// appears, or a second channel would be created for it.
|
|
358
|
+
const slack = await this.readRecord(staging, 'records/slack-team-channel.json', rewrites, { mapping: null });
|
|
359
|
+
out['slackMappingAdopted'] = slack.mapping && (await this.deps.adoptSlackMapping(slack.mapping)) ? 1 : 0;
|
|
360
|
+
const chat = await this.readRecord(staging, 'records/chat-channels.json', rewrites, { channels: [], members: [] });
|
|
361
|
+
const chatResult = (this.deps.applyChat ?? ((r) => applyTeamChat(this.home, r)))(chat);
|
|
362
|
+
out['chatChannelsAdded'] = chatResult.channelsAdded;
|
|
363
|
+
out['chatChannelsExisting'] = chatResult.channelsExisting;
|
|
364
|
+
const pool = await this.readRecord(staging, 'records/task-pool.json', rewrites, { workItems: [] });
|
|
365
|
+
out['taskPoolItemsAdded'] = await this.deps.addWorkItems(pool.workItems ?? []);
|
|
366
|
+
const decisions = await this.readRecord(staging, 'records/decisions.json', rewrites, { decisions: [] });
|
|
367
|
+
out['decisionsAdded'] = await this.deps.addDecisions(decisions.decisions ?? []);
|
|
368
|
+
const scheduled = await this.readRecord(staging, 'records/scheduled-messages.json', rewrites, { messages: [] });
|
|
369
|
+
const have = new Set((await this.deps.storage.getScheduledMessages()).map((m) => m.id));
|
|
370
|
+
let addedMessages = 0;
|
|
371
|
+
for (const m of scheduled.messages ?? []) {
|
|
372
|
+
if (have.has(m.id))
|
|
373
|
+
continue;
|
|
374
|
+
await this.deps.storage.saveScheduledMessage(m);
|
|
375
|
+
addedMessages += 1;
|
|
376
|
+
}
|
|
377
|
+
out['scheduledMessagesAdded'] = addedMessages;
|
|
378
|
+
return out;
|
|
379
|
+
}
|
|
380
|
+
// -------------------------------------------------------------------------
|
|
381
|
+
// team
|
|
382
|
+
// -------------------------------------------------------------------------
|
|
383
|
+
/** Copy the team folder, then register the team (its first save announces it everywhere). */
|
|
384
|
+
async registerTeam(staging, manifest, mappings) {
|
|
385
|
+
const rewrites = this.rewritesFor(manifest, mappings);
|
|
386
|
+
const tag = manifest.moveId.slice(0, 8);
|
|
387
|
+
const teamDir = path.join(this.home, 'teams', manifest.team.id);
|
|
388
|
+
const src = path.join(staging, 'team');
|
|
389
|
+
// Everything but config.json first, so triggers and cron tasks exist when the team is saved.
|
|
390
|
+
const config = await this.readRecord(staging, 'team/config.json', rewrites, null);
|
|
391
|
+
if (!config)
|
|
392
|
+
throw new TeamMoveImportError('the package has no team config', 'invalid_package');
|
|
393
|
+
await this.copyTree(src, teamDir, rewrites, tag, (rel) => rel === 'config.json');
|
|
394
|
+
const now = this.now();
|
|
395
|
+
const team = { ...config, updatedAt: now };
|
|
396
|
+
delete team.archived;
|
|
397
|
+
delete team.archivedAt;
|
|
398
|
+
delete team.moveArchive;
|
|
399
|
+
await this.deps.storage.saveTeam(team);
|
|
400
|
+
return { paused: !!config['paused'] };
|
|
401
|
+
}
|
|
402
|
+
async startTeam(manifest, paused) {
|
|
403
|
+
if (!this.deps.startTeam)
|
|
404
|
+
return { requested: false, ok: false };
|
|
405
|
+
if (paused)
|
|
406
|
+
return { requested: false, ok: false, error: 'the team is paused (the owner paused it before the move)' };
|
|
407
|
+
const result = await this.deps.startTeam(manifest.team.id);
|
|
408
|
+
return { requested: true, ok: result.ok, ...(result.error ? { error: result.error } : {}) };
|
|
409
|
+
}
|
|
410
|
+
// -------------------------------------------------------------------------
|
|
411
|
+
// report
|
|
412
|
+
// -------------------------------------------------------------------------
|
|
413
|
+
async buildReport(manifest, mappings, repoOutcome, data, records, started) {
|
|
414
|
+
const repos = repoOutcome.repos;
|
|
415
|
+
const toolMap = checkTools(manifest.requiredTools, this.deps.hasCommand);
|
|
416
|
+
const missingTools = Object.entries(toolMap).filter(([, ok]) => !ok).map(([tool]) => tool);
|
|
417
|
+
const logins = this.deps.runtimeLogins ? await this.deps.runtimeLogins().catch(() => ({})) : {};
|
|
418
|
+
const runtimesNotLoggedIn = manifest.requiredRuntimes.filter((r) => logins[r] !== true);
|
|
419
|
+
const reconnect = [];
|
|
420
|
+
for (const runtime of runtimesNotLoggedIn) {
|
|
421
|
+
reconnect.push({
|
|
422
|
+
label: `${runtime} login`,
|
|
423
|
+
kind: 'runtime',
|
|
424
|
+
detail: 'Tell Crewly Orc in Slack "log in to ' + runtime.replace(/-cli$/, '').replace(/-code$/, '') + '"; it sends you a login link for your phone.',
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
for (const connector of manifest.requiredConnectors ?? []) {
|
|
428
|
+
reconnect.push({ label: `${connector} connection`, kind: 'connector', url: CONNECTIONS_URL, detail: 'Connections are not moved; connect again on this machine.' });
|
|
429
|
+
}
|
|
430
|
+
for (const failure of repos.failed) {
|
|
431
|
+
reconnect.push({ label: `Git access for ${failure.name}`, kind: 'git', detail: failure.reason });
|
|
432
|
+
}
|
|
433
|
+
const warnings = [...repoOutcome.warnings];
|
|
434
|
+
for (const p of manifest.projects) {
|
|
435
|
+
if (p.skipped.length > 0)
|
|
436
|
+
warnings.push(`${p.name}: ${p.skipped.length} project file(s) were left out (size caps or secret scan).`);
|
|
437
|
+
if (p.sharedWithTeams.length > 0)
|
|
438
|
+
warnings.push(`${p.name} is also used by ${p.sharedWithTeams.join(', ')}; its Crewly data was copied and stays on the source too.`);
|
|
439
|
+
}
|
|
440
|
+
if ((data['filesReplaced'] ?? 0) > 0)
|
|
441
|
+
warnings.push(`${data['filesReplaced']} existing file(s) were replaced by the moved version; the old copies are next to them as *.pre-move-*.`);
|
|
442
|
+
const moved = { ...manifest.counts };
|
|
443
|
+
for (const [k, v] of Object.entries(records))
|
|
444
|
+
if (typeof v === 'number')
|
|
445
|
+
moved[k] = v;
|
|
446
|
+
moved['filesWritten'] = data['filesWritten'] ?? 0;
|
|
447
|
+
return {
|
|
448
|
+
moved,
|
|
449
|
+
repos,
|
|
450
|
+
missingTools,
|
|
451
|
+
runtimesNotLoggedIn,
|
|
452
|
+
reconnect,
|
|
453
|
+
paths: mappings.filter((m) => m.from !== m.to).map((m) => ({ projectId: m.projectId, name: m.name, from: m.from, to: m.to })),
|
|
454
|
+
started,
|
|
455
|
+
warnings,
|
|
456
|
+
notMoved: manifest.notMoved,
|
|
457
|
+
crewlyVersion: this.deps.crewlyVersion,
|
|
458
|
+
importedAt: this.now(),
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
//# sourceMappingURL=team-move-importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move-importer.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move-importer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team move journal — resumable, idempotent steps.
|
|
3
|
+
*
|
|
4
|
+
* Every move keeps a directory `~/.crewly/team-moves/<moveId>/` with
|
|
5
|
+
* `journal.json` (which steps finished and what they produced) and
|
|
6
|
+
* `state.json` (what Cloud last asked for). A step that is recorded as done is
|
|
7
|
+
* skipped when the move is resumed after a crash or restart, and the step
|
|
8
|
+
* functions themselves are written so that running one twice is harmless.
|
|
9
|
+
*
|
|
10
|
+
* @module services/team-move/team-move-journal
|
|
11
|
+
*/
|
|
12
|
+
import type { JournalEntry, LocalMoveState } from './team-move.types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Whether a string is a usable move id.
|
|
15
|
+
*
|
|
16
|
+
* @param value - Candidate
|
|
17
|
+
* @returns True for path-safe ids
|
|
18
|
+
*/
|
|
19
|
+
export declare function isMoveId(value: unknown): value is string;
|
|
20
|
+
/**
|
|
21
|
+
* Directory of all moves on this machine.
|
|
22
|
+
*
|
|
23
|
+
* @param home - Crewly home (default: the process's)
|
|
24
|
+
* @returns Absolute path
|
|
25
|
+
*/
|
|
26
|
+
export declare function teamMovesRoot(home?: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Directory of one move.
|
|
29
|
+
*
|
|
30
|
+
* @param moveId - Move id
|
|
31
|
+
* @param home - Crewly home
|
|
32
|
+
* @returns Absolute path
|
|
33
|
+
* @throws Error for an id that is not path-safe
|
|
34
|
+
*/
|
|
35
|
+
export declare function moveDirFor(moveId: string, home?: string): string;
|
|
36
|
+
/** Journal and state of one move. */
|
|
37
|
+
export declare class MoveJournal {
|
|
38
|
+
readonly moveId: string;
|
|
39
|
+
readonly dir: string;
|
|
40
|
+
private readonly journalFile;
|
|
41
|
+
private readonly stateFile;
|
|
42
|
+
private entries;
|
|
43
|
+
private readonly now;
|
|
44
|
+
/**
|
|
45
|
+
* @param moveId - Move id
|
|
46
|
+
* @param home - Crewly home
|
|
47
|
+
* @param now - Clock (tests)
|
|
48
|
+
*/
|
|
49
|
+
constructor(moveId: string, home?: string, now?: () => string);
|
|
50
|
+
/** Create the move directory. */
|
|
51
|
+
ensure(): Promise<void>;
|
|
52
|
+
private load;
|
|
53
|
+
private append;
|
|
54
|
+
/**
|
|
55
|
+
* All entries, oldest first.
|
|
56
|
+
*
|
|
57
|
+
* @returns Journal entries
|
|
58
|
+
*/
|
|
59
|
+
list(): Promise<JournalEntry[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Whether a step finished.
|
|
62
|
+
*
|
|
63
|
+
* @param step - Step name
|
|
64
|
+
* @returns True when its last entry is `done`
|
|
65
|
+
*/
|
|
66
|
+
isDone(step: string): Promise<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* What a finished step recorded.
|
|
69
|
+
*
|
|
70
|
+
* @param step - Step name
|
|
71
|
+
* @returns The `detail` of its last `done` entry, or undefined
|
|
72
|
+
*/
|
|
73
|
+
detailOf<T = unknown>(step: string): Promise<T | undefined>;
|
|
74
|
+
/**
|
|
75
|
+
* Run a step once. A step already `done` is skipped and its recorded detail
|
|
76
|
+
* returned; a failure is recorded and rethrown.
|
|
77
|
+
*
|
|
78
|
+
* @param step - Step name
|
|
79
|
+
* @param fn - The step; its return value is stored as the step's detail
|
|
80
|
+
* @returns The step's detail (fresh or recorded)
|
|
81
|
+
*/
|
|
82
|
+
run<T>(step: string, fn: () => Promise<T>): Promise<T>;
|
|
83
|
+
/**
|
|
84
|
+
* Forget a step so it runs again (e.g. a retry after the owner fixed something).
|
|
85
|
+
*
|
|
86
|
+
* @param step - Step name
|
|
87
|
+
*/
|
|
88
|
+
reset(step: string): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Read `state.json`.
|
|
91
|
+
*
|
|
92
|
+
* @returns The state, or null before the first write
|
|
93
|
+
*/
|
|
94
|
+
readState(): Promise<LocalMoveState | null>;
|
|
95
|
+
/**
|
|
96
|
+
* Merge a patch into `state.json`.
|
|
97
|
+
*
|
|
98
|
+
* @param patch - Fields to set
|
|
99
|
+
* @returns The new state
|
|
100
|
+
*/
|
|
101
|
+
writeState(patch: Partial<LocalMoveState> & Pick<LocalMoveState, 'role'>): Promise<LocalMoveState>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Ids of the moves that have a directory on this machine.
|
|
105
|
+
*
|
|
106
|
+
* @param home - Crewly home
|
|
107
|
+
* @returns Move ids
|
|
108
|
+
*/
|
|
109
|
+
export declare function listLocalMoveIds(home?: string): Promise<string[]>;
|
|
110
|
+
//# sourceMappingURL=team-move-journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move-journal.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move-journal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAKzE;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAA4B,GAAG,MAAM,CAExE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAA4B,GAAG,MAAM,CAGrF;AAED,qCAAqC;AACrC,qBAAa,WAAW;IAapB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAZzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IAEnC;;;;OAIG;gBAEQ,MAAM,EAAE,MAAM,EACvB,IAAI,GAAE,MAA4B,EAClC,GAAG,GAAE,MAAM,MAAuC;IAQpD,iCAAiC;IAC3B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;YAIf,IAAI;YAQJ,MAAM;IAOpB;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAIrC;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ5C;;;;;OAKG;IACG,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IASjE;;;;;;;OAOG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAa5D;;;;OAIG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxC;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAIjD;;;;;OAKG;IACG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;CAgBzG;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,MAA4B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG5F"}
|