crewly 1.20.133 → 1.20.134

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.
Files changed (219) hide show
  1. package/dist/backend/backend/src/constants.d.ts +82 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +87 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/controllers/bundle/bundle.controller.d.ts +44 -0
  6. package/dist/backend/backend/src/controllers/bundle/bundle.controller.d.ts.map +1 -0
  7. package/dist/backend/backend/src/controllers/bundle/bundle.controller.js +122 -0
  8. package/dist/backend/backend/src/controllers/bundle/bundle.controller.js.map +1 -0
  9. package/dist/backend/backend/src/controllers/bundle/bundle.routes.d.ts +25 -0
  10. package/dist/backend/backend/src/controllers/bundle/bundle.routes.d.ts.map +1 -0
  11. package/dist/backend/backend/src/controllers/bundle/bundle.routes.js +33 -0
  12. package/dist/backend/backend/src/controllers/bundle/bundle.routes.js.map +1 -0
  13. package/dist/backend/backend/src/index.d.ts.map +1 -1
  14. package/dist/backend/backend/src/index.js +14 -0
  15. package/dist/backend/backend/src/index.js.map +1 -1
  16. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  17. package/dist/backend/backend/src/routes/api.routes.js +4 -0
  18. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  19. package/dist/backend/backend/src/services/bundle/bundle-apply.factory.d.ts +62 -0
  20. package/dist/backend/backend/src/services/bundle/bundle-apply.factory.d.ts.map +1 -0
  21. package/dist/backend/backend/src/services/bundle/bundle-apply.factory.js +173 -0
  22. package/dist/backend/backend/src/services/bundle/bundle-apply.factory.js.map +1 -0
  23. package/dist/backend/backend/src/services/bundle/bundle-apply.service.d.ts +359 -0
  24. package/dist/backend/backend/src/services/bundle/bundle-apply.service.d.ts.map +1 -0
  25. package/dist/backend/backend/src/services/bundle/bundle-apply.service.js +888 -0
  26. package/dist/backend/backend/src/services/bundle/bundle-apply.service.js.map +1 -0
  27. package/dist/backend/backend/src/services/bundle/bundle-catalog.d.ts +167 -0
  28. package/dist/backend/backend/src/services/bundle/bundle-catalog.d.ts.map +1 -0
  29. package/dist/backend/backend/src/services/bundle/bundle-catalog.js +248 -0
  30. package/dist/backend/backend/src/services/bundle/bundle-catalog.js.map +1 -0
  31. package/dist/backend/backend/src/services/bundle/bundle-connectors.d.ts +43 -0
  32. package/dist/backend/backend/src/services/bundle/bundle-connectors.d.ts.map +1 -0
  33. package/dist/backend/backend/src/services/bundle/bundle-connectors.js +57 -0
  34. package/dist/backend/backend/src/services/bundle/bundle-connectors.js.map +1 -0
  35. package/dist/backend/backend/src/services/bundle/bundle-deps.d.ts +37 -0
  36. package/dist/backend/backend/src/services/bundle/bundle-deps.d.ts.map +1 -0
  37. package/dist/backend/backend/src/services/bundle/bundle-deps.js +60 -0
  38. package/dist/backend/backend/src/services/bundle/bundle-deps.js.map +1 -0
  39. package/dist/backend/backend/src/services/bundle/bundle-manifest.d.ts +93 -0
  40. package/dist/backend/backend/src/services/bundle/bundle-manifest.d.ts.map +1 -0
  41. package/dist/backend/backend/src/services/bundle/bundle-manifest.js +532 -0
  42. package/dist/backend/backend/src/services/bundle/bundle-manifest.js.map +1 -0
  43. package/dist/backend/backend/src/services/bundle/bundle-placeholders.d.ts +100 -0
  44. package/dist/backend/backend/src/services/bundle/bundle-placeholders.d.ts.map +1 -0
  45. package/dist/backend/backend/src/services/bundle/bundle-placeholders.js +183 -0
  46. package/dist/backend/backend/src/services/bundle/bundle-placeholders.js.map +1 -0
  47. package/dist/backend/backend/src/services/bundle/bundle-runtime.d.ts +36 -0
  48. package/dist/backend/backend/src/services/bundle/bundle-runtime.d.ts.map +1 -0
  49. package/dist/backend/backend/src/services/bundle/bundle-runtime.js +38 -0
  50. package/dist/backend/backend/src/services/bundle/bundle-runtime.js.map +1 -0
  51. package/dist/backend/backend/src/services/bundle/bundle-skill-installer.d.ts +105 -0
  52. package/dist/backend/backend/src/services/bundle/bundle-skill-installer.d.ts.map +1 -0
  53. package/dist/backend/backend/src/services/bundle/bundle-skill-installer.js +144 -0
  54. package/dist/backend/backend/src/services/bundle/bundle-skill-installer.js.map +1 -0
  55. package/dist/backend/backend/src/services/bundle/bundle-state.store.d.ts +48 -0
  56. package/dist/backend/backend/src/services/bundle/bundle-state.store.d.ts.map +1 -0
  57. package/dist/backend/backend/src/services/bundle/bundle-state.store.js +90 -0
  58. package/dist/backend/backend/src/services/bundle/bundle-state.store.js.map +1 -0
  59. package/dist/backend/backend/src/services/bundle/bundle-team.builder.d.ts +81 -0
  60. package/dist/backend/backend/src/services/bundle/bundle-team.builder.d.ts.map +1 -0
  61. package/dist/backend/backend/src/services/bundle/bundle-team.builder.js +172 -0
  62. package/dist/backend/backend/src/services/bundle/bundle-team.builder.js.map +1 -0
  63. package/dist/backend/backend/src/services/bundle/bundle-time.d.ts +59 -0
  64. package/dist/backend/backend/src/services/bundle/bundle-time.d.ts.map +1 -0
  65. package/dist/backend/backend/src/services/bundle/bundle-time.js +98 -0
  66. package/dist/backend/backend/src/services/bundle/bundle-time.js.map +1 -0
  67. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +5 -0
  69. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
  70. package/dist/backend/backend/src/services/core/storage.service.js +1 -1
  71. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  72. package/dist/backend/backend/src/services/core/teams-backup.service.d.ts.map +1 -1
  73. package/dist/backend/backend/src/services/core/teams-backup.service.js +4 -2
  74. package/dist/backend/backend/src/services/core/teams-backup.service.js.map +1 -1
  75. package/dist/backend/backend/src/services/onboarding/onboarding-checklist.factory.d.ts.map +1 -1
  76. package/dist/backend/backend/src/services/onboarding/onboarding-checklist.factory.js +2 -0
  77. package/dist/backend/backend/src/services/onboarding/onboarding-checklist.factory.js.map +1 -1
  78. package/dist/backend/backend/src/services/onboarding/onboarding-checklist.service.d.ts +14 -2
  79. package/dist/backend/backend/src/services/onboarding/onboarding-checklist.service.d.ts.map +1 -1
  80. package/dist/backend/backend/src/services/onboarding/onboarding-checklist.service.js +37 -1
  81. package/dist/backend/backend/src/services/onboarding/onboarding-checklist.service.js.map +1 -1
  82. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +21 -0
  83. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  84. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +85 -0
  85. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  86. package/dist/backend/backend/src/services/template/template.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/template/template.service.js +5 -2
  88. package/dist/backend/backend/src/services/template/template.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
  90. package/dist/backend/backend/src/services/workflow/cron-task.service.js +4 -2
  91. package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
  92. package/dist/backend/backend/src/types/solution-bundle.types.d.ts +367 -0
  93. package/dist/backend/backend/src/types/solution-bundle.types.d.ts.map +1 -0
  94. package/dist/backend/backend/src/types/solution-bundle.types.js +17 -0
  95. package/dist/backend/backend/src/types/solution-bundle.types.js.map +1 -0
  96. package/dist/backend/backend/src/types/team-template.types.d.ts +8 -0
  97. package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
  98. package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
  99. package/dist/backend/build-info.json +2 -2
  100. package/dist/cli/backend/src/constants.d.ts +82 -0
  101. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  102. package/dist/cli/backend/src/constants.js +87 -0
  103. package/dist/cli/backend/src/constants.js.map +1 -1
  104. package/dist/cli/backend/src/services/bundle/bundle-apply.service.d.ts +359 -0
  105. package/dist/cli/backend/src/services/bundle/bundle-apply.service.d.ts.map +1 -0
  106. package/dist/cli/backend/src/services/bundle/bundle-apply.service.js +888 -0
  107. package/dist/cli/backend/src/services/bundle/bundle-apply.service.js.map +1 -0
  108. package/dist/cli/backend/src/services/bundle/bundle-catalog.d.ts +167 -0
  109. package/dist/cli/backend/src/services/bundle/bundle-catalog.d.ts.map +1 -0
  110. package/dist/cli/backend/src/services/bundle/bundle-catalog.js +248 -0
  111. package/dist/cli/backend/src/services/bundle/bundle-catalog.js.map +1 -0
  112. package/dist/cli/backend/src/services/bundle/bundle-deps.d.ts +37 -0
  113. package/dist/cli/backend/src/services/bundle/bundle-deps.d.ts.map +1 -0
  114. package/dist/cli/backend/src/services/bundle/bundle-deps.js +60 -0
  115. package/dist/cli/backend/src/services/bundle/bundle-deps.js.map +1 -0
  116. package/dist/cli/backend/src/services/bundle/bundle-manifest.d.ts +93 -0
  117. package/dist/cli/backend/src/services/bundle/bundle-manifest.d.ts.map +1 -0
  118. package/dist/cli/backend/src/services/bundle/bundle-manifest.js +532 -0
  119. package/dist/cli/backend/src/services/bundle/bundle-manifest.js.map +1 -0
  120. package/dist/cli/backend/src/services/bundle/bundle-placeholders.d.ts +100 -0
  121. package/dist/cli/backend/src/services/bundle/bundle-placeholders.d.ts.map +1 -0
  122. package/dist/cli/backend/src/services/bundle/bundle-placeholders.js +183 -0
  123. package/dist/cli/backend/src/services/bundle/bundle-placeholders.js.map +1 -0
  124. package/dist/cli/backend/src/services/bundle/bundle-runtime.d.ts +36 -0
  125. package/dist/cli/backend/src/services/bundle/bundle-runtime.d.ts.map +1 -0
  126. package/dist/cli/backend/src/services/bundle/bundle-runtime.js +38 -0
  127. package/dist/cli/backend/src/services/bundle/bundle-runtime.js.map +1 -0
  128. package/dist/cli/backend/src/services/bundle/bundle-skill-installer.d.ts +105 -0
  129. package/dist/cli/backend/src/services/bundle/bundle-skill-installer.d.ts.map +1 -0
  130. package/dist/cli/backend/src/services/bundle/bundle-skill-installer.js +144 -0
  131. package/dist/cli/backend/src/services/bundle/bundle-skill-installer.js.map +1 -0
  132. package/dist/cli/backend/src/services/bundle/bundle-state.store.d.ts +48 -0
  133. package/dist/cli/backend/src/services/bundle/bundle-state.store.d.ts.map +1 -0
  134. package/dist/cli/backend/src/services/bundle/bundle-state.store.js +90 -0
  135. package/dist/cli/backend/src/services/bundle/bundle-state.store.js.map +1 -0
  136. package/dist/cli/backend/src/services/bundle/bundle-team.builder.d.ts +81 -0
  137. package/dist/cli/backend/src/services/bundle/bundle-team.builder.d.ts.map +1 -0
  138. package/dist/cli/backend/src/services/bundle/bundle-team.builder.js +172 -0
  139. package/dist/cli/backend/src/services/bundle/bundle-team.builder.js.map +1 -0
  140. package/dist/cli/backend/src/services/bundle/bundle-time.d.ts +59 -0
  141. package/dist/cli/backend/src/services/bundle/bundle-time.d.ts.map +1 -0
  142. package/dist/cli/backend/src/services/bundle/bundle-time.js +98 -0
  143. package/dist/cli/backend/src/services/bundle/bundle-time.js.map +1 -0
  144. package/dist/cli/backend/src/services/core/storage.service.js +1 -1
  145. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  146. package/dist/cli/backend/src/services/core/teams-backup.service.d.ts.map +1 -1
  147. package/dist/cli/backend/src/services/core/teams-backup.service.js +4 -2
  148. package/dist/cli/backend/src/services/core/teams-backup.service.js.map +1 -1
  149. package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.d.ts +72 -0
  150. package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -0
  151. package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.js +389 -0
  152. package/dist/cli/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -0
  153. package/dist/cli/backend/src/services/messaging/index.d.ts +15 -0
  154. package/dist/cli/backend/src/services/messaging/index.d.ts.map +1 -0
  155. package/dist/cli/backend/src/services/messaging/index.js +20 -0
  156. package/dist/cli/backend/src/services/messaging/index.js.map +1 -0
  157. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts +224 -0
  158. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -0
  159. package/dist/cli/backend/src/services/messaging/queue-processor.service.js +969 -0
  160. package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -0
  161. package/dist/cli/backend/src/services/messaging/response-router.service.d.ts +110 -0
  162. package/dist/cli/backend/src/services/messaging/response-router.service.d.ts.map +1 -0
  163. package/dist/cli/backend/src/services/messaging/response-router.service.js +268 -0
  164. package/dist/cli/backend/src/services/messaging/response-router.service.js.map +1 -0
  165. package/dist/cli/backend/src/services/onboarding/onboarding-checklist.service.d.ts +14 -2
  166. package/dist/cli/backend/src/services/onboarding/onboarding-checklist.service.d.ts.map +1 -1
  167. package/dist/cli/backend/src/services/onboarding/onboarding-checklist.service.js +37 -1
  168. package/dist/cli/backend/src/services/onboarding/onboarding-checklist.service.js.map +1 -1
  169. package/dist/cli/backend/src/services/orchestrator/commitment-approval-guard.d.ts +133 -0
  170. package/dist/cli/backend/src/services/orchestrator/commitment-approval-guard.d.ts.map +1 -0
  171. package/dist/cli/backend/src/services/orchestrator/commitment-approval-guard.js +232 -0
  172. package/dist/cli/backend/src/services/orchestrator/commitment-approval-guard.js.map +1 -0
  173. package/dist/cli/backend/src/services/skill/skill-catalog.service.d.ts +277 -0
  174. package/dist/cli/backend/src/services/skill/skill-catalog.service.d.ts.map +1 -0
  175. package/dist/cli/backend/src/services/skill/skill-catalog.service.js +708 -0
  176. package/dist/cli/backend/src/services/skill/skill-catalog.service.js.map +1 -0
  177. package/dist/cli/backend/src/services/skill-setup/skill-install-job.service.d.ts +243 -0
  178. package/dist/cli/backend/src/services/skill-setup/skill-install-job.service.d.ts.map +1 -0
  179. package/dist/cli/backend/src/services/skill-setup/skill-install-job.service.js +439 -0
  180. package/dist/cli/backend/src/services/skill-setup/skill-install-job.service.js.map +1 -0
  181. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +21 -0
  182. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  183. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +85 -0
  184. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  185. package/dist/cli/backend/src/services/template/template.service.d.ts.map +1 -1
  186. package/dist/cli/backend/src/services/template/template.service.js +5 -2
  187. package/dist/cli/backend/src/services/template/template.service.js.map +1 -1
  188. package/dist/cli/backend/src/services/workflow/cron-task.service.d.ts +316 -0
  189. package/dist/cli/backend/src/services/workflow/cron-task.service.d.ts.map +1 -0
  190. package/dist/cli/backend/src/services/workflow/cron-task.service.js +1043 -0
  191. package/dist/cli/backend/src/services/workflow/cron-task.service.js.map +1 -0
  192. package/dist/cli/backend/src/types/cron-task.types.d.ts +95 -0
  193. package/dist/cli/backend/src/types/cron-task.types.d.ts.map +1 -0
  194. package/dist/cli/backend/src/types/cron-task.types.js +10 -0
  195. package/dist/cli/backend/src/types/cron-task.types.js.map +1 -0
  196. package/dist/cli/backend/src/types/solution-bundle.types.d.ts +367 -0
  197. package/dist/cli/backend/src/types/solution-bundle.types.d.ts.map +1 -0
  198. package/dist/cli/backend/src/types/solution-bundle.types.js +17 -0
  199. package/dist/cli/backend/src/types/solution-bundle.types.js.map +1 -0
  200. package/dist/cli/backend/src/types/team-template.types.d.ts +8 -0
  201. package/dist/cli/backend/src/types/team-template.types.d.ts.map +1 -1
  202. package/dist/cli/backend/src/types/team-template.types.js.map +1 -1
  203. package/dist/cli/cli/src/commands/deploy-bundle.d.ts +160 -0
  204. package/dist/cli/cli/src/commands/deploy-bundle.d.ts.map +1 -0
  205. package/dist/cli/cli/src/commands/deploy-bundle.js +386 -0
  206. package/dist/cli/cli/src/commands/deploy-bundle.js.map +1 -0
  207. package/dist/cli/cli/src/commands/onboard.d.ts +32 -1
  208. package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
  209. package/dist/cli/cli/src/commands/onboard.js +80 -3
  210. package/dist/cli/cli/src/commands/onboard.js.map +1 -1
  211. package/dist/cli/cli/src/constants.d.ts +5 -0
  212. package/dist/cli/cli/src/constants.d.ts.map +1 -1
  213. package/dist/cli/cli/src/constants.js +5 -0
  214. package/dist/cli/cli/src/constants.js.map +1 -1
  215. package/dist/cli/cli/src/index.js +15 -0
  216. package/dist/cli/cli/src/index.js.map +1 -1
  217. package/frontend/dist/assets/{index-e6c403b6.js → index-97bb17d4.js} +274 -274
  218. package/frontend/dist/index.html +1 -1
  219. package/package.json +1 -1
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Skill installation for bundles, through the existing marketplace install.
3
+ *
4
+ * Kept behind {@link BundleSkillInstaller} so the apply engine can switch to
5
+ * the skill-autoinstall runner (`feat/skill-autoinstall`: skill discovery
6
+ * over bundled / installed / registry skills + install jobs with setup
7
+ * recipes) when it lands, without touching the engine.
8
+ *
9
+ * A skill counts as available when it is bundled with Crewly
10
+ * (`config/skills/{agent,team-leader,orchestrator}/**`) or already installed
11
+ * from the marketplace. Missing ones are installed with the marketplace
12
+ * installer (`POST /api/marketplace/:id/install` / `crewly install <id>`).
13
+ *
14
+ * @module services/bundle/bundle-skill-installer
15
+ */
16
+ import { existsSync, readdirSync, statSync } from 'fs';
17
+ import * as path from 'path';
18
+ /** Skill roots under `config/skills/` that ship with Crewly. */
19
+ const BUNDLED_SKILL_ROOTS = ['agent', 'team-leader', 'orchestrator'];
20
+ /** How deep a skill folder may sit under a root (e.g. agent/core/<id>). */
21
+ const MAX_SKILL_DEPTH = 3;
22
+ /** Files that make a folder a skill. */
23
+ const SKILL_MARKERS = ['SKILL.md', 'skill.json', 'execute.sh'];
24
+ /**
25
+ * Find a skill folder by id under the bundled skill roots.
26
+ *
27
+ * @param packageRoot - Crewly package root (contains `config/skills`)
28
+ * @param skillId - Skill id (folder name)
29
+ * @returns The folder, or null
30
+ */
31
+ export function findBundledSkill(packageRoot, skillId) {
32
+ const walk = (dir, depth) => {
33
+ let entries;
34
+ try {
35
+ entries = readdirSync(dir);
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ for (const entry of entries) {
41
+ if (entry.startsWith('.') || entry.startsWith('_'))
42
+ continue;
43
+ const full = path.join(dir, entry);
44
+ try {
45
+ if (!statSync(full).isDirectory())
46
+ continue;
47
+ }
48
+ catch {
49
+ continue;
50
+ }
51
+ if (entry === skillId && SKILL_MARKERS.some((m) => existsSync(path.join(full, m))))
52
+ return full;
53
+ if (depth < MAX_SKILL_DEPTH) {
54
+ const found = walk(full, depth + 1);
55
+ if (found)
56
+ return found;
57
+ }
58
+ }
59
+ return null;
60
+ };
61
+ for (const root of BUNDLED_SKILL_ROOTS) {
62
+ const found = walk(path.join(packageRoot, 'config', 'skills', root), 1);
63
+ if (found)
64
+ return found;
65
+ }
66
+ return null;
67
+ }
68
+ /**
69
+ * A {@link BundleSkillInstaller} over the marketplace.
70
+ *
71
+ * @param deps - Package root, homes and marketplace functions
72
+ * @returns Installer
73
+ */
74
+ export function createMarketplaceSkillInstaller(deps) {
75
+ return {
76
+ async isAvailable(skillId) {
77
+ if (findBundledSkill(deps.packageRoot, skillId))
78
+ return true;
79
+ try {
80
+ return existsSync(deps.installPath(skillId));
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ },
86
+ async install(skillId) {
87
+ if (path.resolve(deps.crewlyHome) !== path.resolve(deps.marketplaceHome)) {
88
+ return {
89
+ ok: false,
90
+ message: `Not installed: the marketplace installs into ${deps.marketplaceHome}, not this CREWLY_HOME (${deps.crewlyHome})`,
91
+ };
92
+ }
93
+ const registry = await deps.fetchRegistry();
94
+ const item = registry.items.find((i) => i.id === skillId && i.type === 'skill');
95
+ if (!item)
96
+ return { ok: false, message: `"${skillId}" is not in the marketplace` };
97
+ const result = await deps.installItem(item);
98
+ return { ok: result.success, message: result.message };
99
+ },
100
+ };
101
+ }
102
+ /**
103
+ * Bundle skill installer on the skill-setup services (specs/skill-auto-install.md):
104
+ * a skill counts as available only when its declared dependencies are set up,
105
+ * and installing runs that setup too (brew/apt/model downloads). Deploying a
106
+ * bundle is the owner's own action, so third-party skills in it install as
107
+ * the owner (`ownerDashboard`).
108
+ *
109
+ * @param deps - Discovery and install-job services
110
+ * @returns Installer for the apply engine
111
+ */
112
+ export function createSkillSetupInstaller(deps) {
113
+ return {
114
+ async isAvailable(skillId) {
115
+ const skill = await deps.discovery.resolve(skillId);
116
+ if (!skill || !skill.installed)
117
+ return false;
118
+ const probed = await deps.discovery.probe(skill);
119
+ return probed.ready !== false;
120
+ },
121
+ async install(skillId) {
122
+ const skill = await deps.discovery.resolve(skillId);
123
+ if (!skill)
124
+ return { ok: false, message: `"${skillId}" is not bundled with Crewly or listed in the marketplace` };
125
+ // A download from the marketplace lands in ~/.crewly whatever CREWLY_HOME
126
+ // says — refuse rather than write into the real home from a test deploy.
127
+ if (!skill.installed && path.resolve(deps.crewlyHome) !== path.resolve(deps.marketplaceHome)) {
128
+ return {
129
+ ok: false,
130
+ message: `Not installed: the marketplace installs into ${deps.marketplaceHome}, not this CREWLY_HOME (${deps.crewlyHome})`,
131
+ };
132
+ }
133
+ const started = await deps.jobs.startInstall({ skillId, ownerDashboard: true, resumeNote: 'solution bundle deploy' });
134
+ if (started.kind === 'already-ready')
135
+ return { ok: true, message: `${skillId} already set up` };
136
+ const job = await deps.jobs.waitForJob(started.job.jobId);
137
+ const tail = job.log.trim().split('\n').slice(-3).join(' | ');
138
+ return job.state === 'succeeded'
139
+ ? { ok: true, message: `${skillId} installed and set up` }
140
+ : { ok: false, message: `${skillId} install failed${tail ? `: ${tail}` : ''}` };
141
+ },
142
+ };
143
+ }
144
+ //# sourceMappingURL=bundle-skill-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-skill-installer.js","sourceRoot":"","sources":["../../../../../../backend/src/services/bundle/bundle-skill-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Bundle deployment store — `<crewlyHome>/bundles/<templateId>.json`.
3
+ *
4
+ * One file per deployed template. The apply engine writes it after every
5
+ * step, so a crash or a failed step leaves an accurate record and a re-run
6
+ * resumes from it. Writes are atomic (temp file + rename).
7
+ *
8
+ * @module services/bundle/bundle-state.store
9
+ */
10
+ import type { BundleDeployment } from '../../types/solution-bundle.types.js';
11
+ /**
12
+ * Persists bundle deployments.
13
+ */
14
+ export declare class BundleDeploymentStore {
15
+ private readonly dir;
16
+ /**
17
+ * @param crewlyHome - Crewly home directory
18
+ */
19
+ constructor(crewlyHome: string);
20
+ /**
21
+ * File of a template's deployment.
22
+ *
23
+ * @param templateId - Template id (kebab case)
24
+ * @returns Absolute path
25
+ * @throws Error for an id that is not a safe file name
26
+ */
27
+ fileFor(templateId: string): string;
28
+ /**
29
+ * Read a deployment.
30
+ *
31
+ * @param templateId - Template id
32
+ * @returns The deployment, or null when the template was never deployed (or the file is unreadable)
33
+ */
34
+ read(templateId: string): Promise<BundleDeployment | null>;
35
+ /**
36
+ * Write a deployment atomically.
37
+ *
38
+ * @param deployment - Deployment
39
+ */
40
+ write(deployment: BundleDeployment): Promise<void>;
41
+ /**
42
+ * Every stored deployment.
43
+ *
44
+ * @returns Deployments (unreadable files are skipped)
45
+ */
46
+ list(): Promise<BundleDeployment[]>;
47
+ }
48
+ //# sourceMappingURL=bundle-state.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-state.store.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/bundle/bundle-state.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAM7E;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B;;OAEG;gBACS,UAAU,EAAE,MAAM;IAI9B;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAKnC;;;;;OAKG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAShE;;;;OAIG;IACG,KAAK,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxD;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAiB1C"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Bundle deployment store — `<crewlyHome>/bundles/<templateId>.json`.
3
+ *
4
+ * One file per deployed template. The apply engine writes it after every
5
+ * step, so a crash or a failed step leaves an accurate record and a re-run
6
+ * resumes from it. Writes are atomic (temp file + rename).
7
+ *
8
+ * @module services/bundle/bundle-state.store
9
+ */
10
+ import { promises as fs } from 'fs';
11
+ import * as path from 'path';
12
+ import { BUNDLE_CONSTANTS } from '../../constants.js';
13
+ import { atomicWriteFile } from '../../utils/file-io.utils.js';
14
+ /** Template ids become file names; keep them to safe characters. */
15
+ const SAFE_ID_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
16
+ /**
17
+ * Persists bundle deployments.
18
+ */
19
+ export class BundleDeploymentStore {
20
+ dir;
21
+ /**
22
+ * @param crewlyHome - Crewly home directory
23
+ */
24
+ constructor(crewlyHome) {
25
+ this.dir = path.join(crewlyHome, BUNDLE_CONSTANTS.STATE_DIR);
26
+ }
27
+ /**
28
+ * File of a template's deployment.
29
+ *
30
+ * @param templateId - Template id (kebab case)
31
+ * @returns Absolute path
32
+ * @throws Error for an id that is not a safe file name
33
+ */
34
+ fileFor(templateId) {
35
+ if (!SAFE_ID_PATTERN.test(templateId))
36
+ throw new Error(`Invalid template id: ${templateId}`);
37
+ return path.join(this.dir, `${templateId}.json`);
38
+ }
39
+ /**
40
+ * Read a deployment.
41
+ *
42
+ * @param templateId - Template id
43
+ * @returns The deployment, or null when the template was never deployed (or the file is unreadable)
44
+ */
45
+ async read(templateId) {
46
+ try {
47
+ const parsed = JSON.parse(await fs.readFile(this.fileFor(templateId), 'utf-8'));
48
+ return parsed && parsed.templateId === templateId && Array.isArray(parsed.steps) ? parsed : null;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Write a deployment atomically.
56
+ *
57
+ * @param deployment - Deployment
58
+ */
59
+ async write(deployment) {
60
+ await fs.mkdir(this.dir, { recursive: true });
61
+ await atomicWriteFile(this.fileFor(deployment.templateId), JSON.stringify(deployment, null, 2));
62
+ }
63
+ /**
64
+ * Every stored deployment.
65
+ *
66
+ * @returns Deployments (unreadable files are skipped)
67
+ */
68
+ async list() {
69
+ let entries;
70
+ try {
71
+ entries = await fs.readdir(this.dir);
72
+ }
73
+ catch {
74
+ return [];
75
+ }
76
+ const out = [];
77
+ for (const entry of entries.sort()) {
78
+ if (!entry.endsWith('.json'))
79
+ continue;
80
+ const id = entry.slice(0, -'.json'.length);
81
+ if (!SAFE_ID_PATTERN.test(id))
82
+ continue;
83
+ const deployment = await this.read(id);
84
+ if (deployment)
85
+ out.push(deployment);
86
+ }
87
+ return out;
88
+ }
89
+ }
90
+ //# sourceMappingURL=bundle-state.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-state.store.js","sourceRoot":"","sources":["../../../../../../backend/src/services/bundle/bundle-state.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,oEAAoE;AACpE,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAE/C;;GAEG;AACH,MAAM,OAAO,qBAAqB;IACf,GAAG,CAAS;IAE7B;;OAEG;IACH,YAAY,UAAkB;QAC5B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,UAAkB;QACxB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;QAC7F,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,OAAO,CAAC,CAAC;IACnD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAC,UAAkB;QAC3B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAqB,CAAC;YACpG,OAAO,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QACnG,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,UAA4B;QACtC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClG,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,GAAG,GAAuB,EAAE,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACvC,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,SAAS;YACxC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvC,IAAI,UAAU;gBAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Builds the Crewly teams of a solution bundle.
3
+ *
4
+ * Mirrors `TemplateService.createTeamFromTemplate` (members per role,
5
+ * hierarchy wiring) with what bundles need on top: placeholder filling,
6
+ * deterministic team ids (so every re-run and the CLI find the same team),
7
+ * ASCII session names like the onboarding starters, and one runtime for
8
+ * every member.
9
+ *
10
+ * @module services/bundle/bundle-team.builder
11
+ */
12
+ import type { Team, TeamMember } from '../../types/index.js';
13
+ import type { BundleTemplate } from '../../types/solution-bundle.types.js';
14
+ import type { NormalizedBundleTeam } from './bundle-manifest.js';
15
+ import { type BundleAnswers } from './bundle-placeholders.js';
16
+ /**
17
+ * Lower-case ASCII slug.
18
+ *
19
+ * @param value - Any text
20
+ * @returns Slug (may be empty for non-ASCII text)
21
+ */
22
+ export declare function toSlug(value: string): string;
23
+ /**
24
+ * The deterministic id of a bundle team: the template id for the main
25
+ * team, `<templateId>--<key>` for extra teams.
26
+ *
27
+ * @param templateId - Template id
28
+ * @param teamKey - Team key
29
+ * @returns Team id
30
+ */
31
+ export declare function bundleTeamId(templateId: string, teamKey: string): string;
32
+ /**
33
+ * The member name of the n-th member of a role.
34
+ *
35
+ * @param defaultName - Role default name
36
+ * @param count - Members in the role
37
+ * @param index - 0-based index
38
+ * @returns Name (`Writer`, or `Writer1`, `Writer2` …)
39
+ */
40
+ export declare function memberNameFor(defaultName: string, count: number, index: number): string;
41
+ /**
42
+ * Values for a team's placeholders: the answers plus the built-ins.
43
+ *
44
+ * @param answers - Owner answers
45
+ * @param teamName - Filled team name
46
+ * @param leadName - The lead member's name
47
+ * @returns Placeholder values
48
+ */
49
+ export declare function teamPlaceholderValues(answers: BundleAnswers, teamName: string, leadName: string): BundleAnswers;
50
+ /** Input of {@link buildBundleTeam}. */
51
+ export interface BuildBundleTeamInput {
52
+ template: BundleTemplate;
53
+ team: NormalizedBundleTeam;
54
+ answers: BundleAnswers;
55
+ runtime: string;
56
+ now: Date;
57
+ }
58
+ /**
59
+ * Build one bundle team (not saved).
60
+ *
61
+ * @param input - Template, normalized team, answers, runtime, clock
62
+ * @returns The team, ready for `StorageService.saveTeam`
63
+ * @throws BundlePlaceholderError when a text keeps an unfilled placeholder
64
+ */
65
+ export declare function buildBundleTeam(input: BuildBundleTeamInput): Team;
66
+ /**
67
+ * Find the member a ref names in a built team.
68
+ *
69
+ * @param team - Saved team
70
+ * @param role - Role id (the first member of the role is returned)
71
+ * @returns The member, or undefined
72
+ */
73
+ export declare function memberForRole(team: Team, role: string): TeamMember | undefined;
74
+ /**
75
+ * The session name a member runs under (its permanent agent id).
76
+ *
77
+ * @param member - Member
78
+ * @returns Session name
79
+ */
80
+ export declare function memberSession(member: TeamMember): string;
81
+ //# sourceMappingURL=bundle-team.builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-team.builder.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/bundle/bundle-team.builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEhF;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAE/G;AAED,wCAAwC;AACxC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,IAAI,CAAC;CACX;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAmFjE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAExD"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Builds the Crewly teams of a solution bundle.
3
+ *
4
+ * Mirrors `TemplateService.createTeamFromTemplate` (members per role,
5
+ * hierarchy wiring) with what bundles need on top: placeholder filling,
6
+ * deterministic team ids (so every re-run and the CLI find the same team),
7
+ * ASCII session names like the onboarding starters, and one runtime for
8
+ * every member.
9
+ *
10
+ * @module services/bundle/bundle-team.builder
11
+ */
12
+ import { randomUUID } from 'crypto';
13
+ import { BUNDLE_CONSTANTS } from '../../constants.js';
14
+ import { fillPlaceholders } from './bundle-placeholders.js';
15
+ /**
16
+ * Lower-case ASCII slug.
17
+ *
18
+ * @param value - Any text
19
+ * @returns Slug (may be empty for non-ASCII text)
20
+ */
21
+ export function toSlug(value) {
22
+ return value
23
+ .toLowerCase()
24
+ .replace(/[^a-z0-9]+/g, '-')
25
+ .replace(/^-+|-+$/g, '');
26
+ }
27
+ /**
28
+ * The deterministic id of a bundle team: the template id for the main
29
+ * team, `<templateId>--<key>` for extra teams.
30
+ *
31
+ * @param templateId - Template id
32
+ * @param teamKey - Team key
33
+ * @returns Team id
34
+ */
35
+ export function bundleTeamId(templateId, teamKey) {
36
+ return teamKey === BUNDLE_CONSTANTS.MAIN_TEAM_KEY
37
+ ? templateId
38
+ : `${templateId}${BUNDLE_CONSTANTS.TEAM_ID_SEPARATOR}${teamKey}`;
39
+ }
40
+ /**
41
+ * The member name of the n-th member of a role.
42
+ *
43
+ * @param defaultName - Role default name
44
+ * @param count - Members in the role
45
+ * @param index - 0-based index
46
+ * @returns Name (`Writer`, or `Writer1`, `Writer2` …)
47
+ */
48
+ export function memberNameFor(defaultName, count, index) {
49
+ return count > 1 ? `${defaultName}${index + 1}` : defaultName;
50
+ }
51
+ /**
52
+ * Values for a team's placeholders: the answers plus the built-ins.
53
+ *
54
+ * @param answers - Owner answers
55
+ * @param teamName - Filled team name
56
+ * @param leadName - The lead member's name
57
+ * @returns Placeholder values
58
+ */
59
+ export function teamPlaceholderValues(answers, teamName, leadName) {
60
+ return { ...answers, team_name: teamName, lead_name: leadName };
61
+ }
62
+ /**
63
+ * Build one bundle team (not saved).
64
+ *
65
+ * @param input - Template, normalized team, answers, runtime, clock
66
+ * @returns The team, ready for `StorageService.saveTeam`
67
+ * @throws BundlePlaceholderError when a text keeps an unfilled placeholder
68
+ */
69
+ export function buildBundleTeam(input) {
70
+ const { template, team, answers, runtime, now } = input;
71
+ const iso = now.toISOString();
72
+ const teamId = bundleTeamId(template.id, team.key);
73
+ const teamSlug = toSlug(teamId) || 'team';
74
+ const leadRole = team.roles.find((r) => r.role === team.leadRole);
75
+ const leadName = leadRole ? memberNameFor(leadRole.defaultName, leadRole.count, 0) : '';
76
+ const nameValues = { ...answers, lead_name: leadName, team_name: '' };
77
+ const teamName = fillPlaceholders(team.name, nameValues, `team ${team.key} name`);
78
+ const values = teamPlaceholderValues(answers, teamName, leadName);
79
+ const members = [];
80
+ const idsByRole = new Map();
81
+ for (const role of team.roles) {
82
+ const ids = [];
83
+ for (let i = 0; i < role.count; i++) {
84
+ const id = randomUUID();
85
+ const name = memberNameFor(role.defaultName, role.count, i);
86
+ const sessionName = `${teamSlug}-${toSlug(name) || 'member'}-${id.slice(0, 8)}`;
87
+ const where = `${team.key}/${role.role}`;
88
+ members.push({
89
+ id,
90
+ name,
91
+ sessionName,
92
+ agentId: sessionName,
93
+ role: role.role,
94
+ systemPrompt: fillPlaceholders(role.promptAdditions ?? '', values, `${where} promptAdditions`),
95
+ agentStatus: 'inactive',
96
+ workingStatus: 'idle',
97
+ runtimeType: runtime,
98
+ hierarchyLevel: role.hierarchyLevel,
99
+ canDelegate: role.canDelegate,
100
+ skillOverrides: role.defaultSkills.length > 0 ? [...role.defaultSkills] : undefined,
101
+ excludedRoleSkills: role.excludedSkills,
102
+ createdAt: iso,
103
+ updatedAt: iso,
104
+ jobTitle: role.jobTitle ?? role.label,
105
+ jobDescription: role.jobDescription ? fillPlaceholders(role.jobDescription, values, `${where} jobDescription`) : undefined,
106
+ ownershipScope: role.ownershipScope,
107
+ responsibilityType: role.responsibilityType,
108
+ autonomyLevel: role.autonomyLevel,
109
+ expertId: role.expertId,
110
+ domainSOP: role.domainSOP,
111
+ riskPolicy: role.riskPolicy,
112
+ });
113
+ ids.push(id);
114
+ }
115
+ idsByRole.set(role.role, ids);
116
+ }
117
+ // Hierarchy: every member of a role reports to the first member of its parent role.
118
+ for (const role of team.roles) {
119
+ if (!role.reportsTo)
120
+ continue;
121
+ const parentId = idsByRole.get(role.reportsTo)?.[0];
122
+ if (!parentId)
123
+ continue;
124
+ const childIds = idsByRole.get(role.role) ?? [];
125
+ for (const childId of childIds) {
126
+ const child = members.find((m) => m.id === childId);
127
+ if (child)
128
+ child.parentMemberId = parentId;
129
+ }
130
+ const parent = members.find((m) => m.id === parentId);
131
+ if (parent)
132
+ parent.subordinateIds = [...(parent.subordinateIds ?? []), ...childIds];
133
+ }
134
+ const leaderId = idsByRole.get(team.leadRole)?.[0];
135
+ const description = team.description ? fillPlaceholders(team.description, values, `team ${team.key} description`) : undefined;
136
+ const mission = team.key === BUNDLE_CONSTANTS.MAIN_TEAM_KEY && template.mission
137
+ ? fillPlaceholders(template.mission, values, 'mission')
138
+ : undefined;
139
+ return {
140
+ id: teamId,
141
+ name: teamName,
142
+ ...(description ? { description } : {}),
143
+ members,
144
+ projectIds: [],
145
+ hierarchical: template.hierarchical ?? true,
146
+ ...(leaderId ? { leaderId, leaderIds: [leaderId] } : {}),
147
+ templateId: template.id,
148
+ ...(mission ? { mission } : {}),
149
+ createdAt: iso,
150
+ updatedAt: iso,
151
+ };
152
+ }
153
+ /**
154
+ * Find the member a ref names in a built team.
155
+ *
156
+ * @param team - Saved team
157
+ * @param role - Role id (the first member of the role is returned)
158
+ * @returns The member, or undefined
159
+ */
160
+ export function memberForRole(team, role) {
161
+ return team.members.find((m) => m.role === role);
162
+ }
163
+ /**
164
+ * The session name a member runs under (its permanent agent id).
165
+ *
166
+ * @param member - Member
167
+ * @returns Session name
168
+ */
169
+ export function memberSession(member) {
170
+ return member.agentId || member.sessionName;
171
+ }
172
+ //# sourceMappingURL=bundle-team.builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-team.builder.js","sourceRoot":"","sources":["../../../../../../backend/src/services/bundle/bundle-team.builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Time helpers for bundle first-week tasks: "day 2 at 09:00 in the
3
+ * bundle's timezone" as a UTC instant, independent of the server's own
4
+ * timezone (hosted servers run in UTC; owners mostly do not).
5
+ *
6
+ * @module services/bundle/bundle-time
7
+ */
8
+ /** Calendar date and time in some timezone. */
9
+ interface ZonedParts {
10
+ year: number;
11
+ month: number;
12
+ day: number;
13
+ hour: number;
14
+ minute: number;
15
+ }
16
+ /**
17
+ * Whether a string is a valid IANA timezone.
18
+ *
19
+ * @param tz - Candidate
20
+ * @returns True when Intl accepts it
21
+ */
22
+ export declare function isValidTimezone(tz: string): boolean;
23
+ /**
24
+ * Calendar parts of an instant in a timezone.
25
+ *
26
+ * @param date - Instant
27
+ * @param tz - IANA timezone
28
+ * @returns Year, month (1-12), day, hour, minute
29
+ */
30
+ export declare function zonedParts(date: Date, tz: string): ZonedParts;
31
+ /**
32
+ * The UTC instant of a wall-clock time in a timezone.
33
+ *
34
+ * Starts from the wall time read as UTC, then corrects by the zone's offset
35
+ * at that instant (twice, which settles DST edges).
36
+ *
37
+ * @param wall - Calendar date and time in `tz`
38
+ * @param tz - IANA timezone
39
+ * @returns The instant
40
+ */
41
+ export declare function zonedTimeToUtc(wall: ZonedParts, tz: string): Date;
42
+ /**
43
+ * When a first-week task is due.
44
+ *
45
+ * Day 0 is due at `deployedAt`. Day n is due at `time` (default 09:00) on
46
+ * the n-th calendar day after the deploy day, in `tz`.
47
+ *
48
+ * @param deployedAt - When the bundle was applied
49
+ * @param day - 0-based day
50
+ * @param time - `HH:MM` (optional)
51
+ * @param tz - IANA timezone
52
+ * @returns ISO timestamp
53
+ *
54
+ * @example
55
+ * firstWeekDueAt(new Date('2026-09-25T02:00:00Z'), 1, '09:00', 'Asia/Shanghai') // '2026-09-26T01:00:00.000Z'
56
+ */
57
+ export declare function firstWeekDueAt(deployedAt: Date, day: number, time: string | undefined, tz: string): string;
58
+ export {};
59
+ //# sourceMappingURL=bundle-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-time.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/bundle/bundle-time.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,+CAA+C;AAC/C,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAmB7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CASjE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAU1G"}