dsh-plugin-t-expert 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (619) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +215 -0
  3. package/THIRD-PARTY-NOTICES +33 -0
  4. package/cordis.patch.yml +7 -0
  5. package/data/experts/academic/academic-anthropologist.md +125 -0
  6. package/data/experts/academic/academic-geographer.md +127 -0
  7. package/data/experts/academic/academic-historian.md +123 -0
  8. package/data/experts/academic/academic-narratologist.md +118 -0
  9. package/data/experts/academic/academic-psychologist.md +118 -0
  10. package/data/experts/academic/academic-statistician.md +144 -0
  11. package/data/experts/design/design-brand-guardian.md +322 -0
  12. package/data/experts/design/design-image-prompt-engineer.md +236 -0
  13. package/data/experts/design/design-inclusive-visuals-specialist.md +71 -0
  14. package/data/experts/design/design-persona-walkthrough.md +272 -0
  15. package/data/experts/design/design-ui-designer.md +383 -0
  16. package/data/experts/design/design-ui-finish-gate-reviewer.md +217 -0
  17. package/data/experts/design/design-ux-architect.md +469 -0
  18. package/data/experts/design/design-ux-researcher.md +329 -0
  19. package/data/experts/design/design-visual-storyteller.md +149 -0
  20. package/data/experts/design/design-whimsy-injector.md +438 -0
  21. package/data/experts/engineering/engineering-ai-data-remediation-engineer.md +211 -0
  22. package/data/experts/engineering/engineering-ai-engineer.md +146 -0
  23. package/data/experts/engineering/engineering-api-platform-engineer.md +162 -0
  24. package/data/experts/engineering/engineering-ats-validator-architect.md +383 -0
  25. package/data/experts/engineering/engineering-autonomous-optimization-architect.md +107 -0
  26. package/data/experts/engineering/engineering-backend-architect.md +236 -0
  27. package/data/experts/engineering/engineering-china-network-engineer.md +252 -0
  28. package/data/experts/engineering/engineering-cms-developer.md +536 -0
  29. package/data/experts/engineering/engineering-code-reviewer.md +76 -0
  30. package/data/experts/engineering/engineering-codebase-onboarding-engineer.md +173 -0
  31. package/data/experts/engineering/engineering-data-engineer.md +306 -0
  32. package/data/experts/engineering/engineering-data-visualization-engineer.md +151 -0
  33. package/data/experts/engineering/engineering-database-optimizer.md +176 -0
  34. package/data/experts/engineering/engineering-database-reliability-engineer.md +162 -0
  35. package/data/experts/engineering/engineering-desktop-app-engineer.md +204 -0
  36. package/data/experts/engineering/engineering-developer-tooling-engineer.md +153 -0
  37. package/data/experts/engineering/engineering-devops-automator.md +376 -0
  38. package/data/experts/engineering/engineering-drupal-performance.md +347 -0
  39. package/data/experts/engineering/engineering-drupal-shopping-cart.md +360 -0
  40. package/data/experts/engineering/engineering-email-intelligence-engineer.md +353 -0
  41. package/data/experts/engineering/engineering-embedded-firmware-engineer.md +173 -0
  42. package/data/experts/engineering/engineering-feishu-integration-developer.md +598 -0
  43. package/data/experts/engineering/engineering-filament-optimization-specialist.md +283 -0
  44. package/data/experts/engineering/engineering-finops-engineer.md +153 -0
  45. package/data/experts/engineering/engineering-frontend-developer.md +225 -0
  46. package/data/experts/engineering/engineering-gaussdb-expert.md +334 -0
  47. package/data/experts/engineering/engineering-git-workflow-master.md +84 -0
  48. package/data/experts/engineering/engineering-i18n-engineer.md +184 -0
  49. package/data/experts/engineering/engineering-identity-access-engineer.md +196 -0
  50. package/data/experts/engineering/engineering-incident-response-commander.md +444 -0
  51. package/data/experts/engineering/engineering-iot-fleet-engineer.md +148 -0
  52. package/data/experts/engineering/engineering-it-service-manager.md +561 -0
  53. package/data/experts/engineering/engineering-knowledge-graph-engineer.md +368 -0
  54. package/data/experts/engineering/engineering-llm-post-training-engineer.md +166 -0
  55. package/data/experts/engineering/engineering-minimal-change-engineer.md +207 -0
  56. package/data/experts/engineering/engineering-mobile-app-builder.md +493 -0
  57. package/data/experts/engineering/engineering-mobile-release-engineer.md +163 -0
  58. package/data/experts/engineering/engineering-multi-agent-systems-architect.md +600 -0
  59. package/data/experts/engineering/engineering-network-engineer.md +239 -0
  60. package/data/experts/engineering/engineering-orgscript-engineer.md +113 -0
  61. package/data/experts/engineering/engineering-payments-billing-engineer.md +194 -0
  62. package/data/experts/engineering/engineering-pdf-engine-architect.md +666 -0
  63. package/data/experts/engineering/engineering-platform-engineer.md +270 -0
  64. package/data/experts/engineering/engineering-privacy-engineer.md +152 -0
  65. package/data/experts/engineering/engineering-prompt-engineer.md +202 -0
  66. package/data/experts/engineering/engineering-rag-pipeline-engineer.md +437 -0
  67. package/data/experts/engineering/engineering-rapid-prototyper.md +462 -0
  68. package/data/experts/engineering/engineering-realtime-collaboration-engineer.md +187 -0
  69. package/data/experts/engineering/engineering-rust-refactoring-specialist.md +313 -0
  70. package/data/experts/engineering/engineering-search-relevance-engineer.md +237 -0
  71. package/data/experts/engineering/engineering-section-508-specialist.md +339 -0
  72. package/data/experts/engineering/engineering-senior-developer.md +176 -0
  73. package/data/experts/engineering/engineering-software-architect.md +112 -0
  74. package/data/experts/engineering/engineering-solidity-smart-contract-engineer.md +522 -0
  75. package/data/experts/engineering/engineering-sre.md +90 -0
  76. package/data/experts/engineering/engineering-technical-writer.md +393 -0
  77. package/data/experts/engineering/engineering-universal-document-compiler.md +344 -0
  78. package/data/experts/engineering/engineering-uswds-developer.md +340 -0
  79. package/data/experts/engineering/engineering-video-streaming-engineer.md +150 -0
  80. package/data/experts/engineering/engineering-voice-ai-integration-engineer.md +561 -0
  81. package/data/experts/engineering/engineering-webassembly-engineer.md +156 -0
  82. package/data/experts/engineering/engineering-wechat-mini-program-developer.md +350 -0
  83. package/data/experts/engineering/engineering-wordpress-performance.md +346 -0
  84. package/data/experts/engineering/engineering-wordpress-shopping-cart.md +346 -0
  85. package/data/experts/finance/finance-bookkeeper-controller.md +260 -0
  86. package/data/experts/finance/finance-financial-analyst.md +234 -0
  87. package/data/experts/finance/finance-fpa-analyst.md +263 -0
  88. package/data/experts/finance/finance-investment-researcher.md +272 -0
  89. package/data/experts/finance/finance-tax-strategist.md +239 -0
  90. package/data/experts/game-development/blender/blender-addon-engineer.md +234 -0
  91. package/data/experts/game-development/economy-designer.md +156 -0
  92. package/data/experts/game-development/game-audio-engineer.md +264 -0
  93. package/data/experts/game-development/game-designer.md +167 -0
  94. package/data/experts/game-development/godot/godot-gameplay-scripter.md +334 -0
  95. package/data/experts/game-development/godot/godot-multiplayer-engineer.md +297 -0
  96. package/data/experts/game-development/godot/godot-shader-developer.md +266 -0
  97. package/data/experts/game-development/level-designer.md +208 -0
  98. package/data/experts/game-development/narrative-designer.md +243 -0
  99. package/data/experts/game-development/roblox-studio/roblox-avatar-creator.md +297 -0
  100. package/data/experts/game-development/roblox-studio/roblox-experience-designer.md +305 -0
  101. package/data/experts/game-development/roblox-studio/roblox-systems-scripter.md +325 -0
  102. package/data/experts/game-development/technical-artist.md +229 -0
  103. package/data/experts/game-development/unity/unity-architect.md +271 -0
  104. package/data/experts/game-development/unity/unity-editor-tool-developer.md +310 -0
  105. package/data/experts/game-development/unity/unity-multiplayer-engineer.md +321 -0
  106. package/data/experts/game-development/unity/unity-shader-graph-artist.md +269 -0
  107. package/data/experts/game-development/unreal-engine/unreal-multiplayer-architect.md +313 -0
  108. package/data/experts/game-development/unreal-engine/unreal-systems-engineer.md +310 -0
  109. package/data/experts/game-development/unreal-engine/unreal-technical-artist.md +256 -0
  110. package/data/experts/game-development/unreal-engine/unreal-world-builder.md +273 -0
  111. package/data/experts/gis/gis-3d-scene-developer.md +111 -0
  112. package/data/experts/gis/gis-analyst.md +91 -0
  113. package/data/experts/gis/gis-bim-specialist.md +108 -0
  114. package/data/experts/gis/gis-cartography-designer.md +150 -0
  115. package/data/experts/gis/gis-drone-reality-mapping.md +120 -0
  116. package/data/experts/gis/gis-geoai-ml-engineer.md +105 -0
  117. package/data/experts/gis/gis-geoprocessing-specialist.md +97 -0
  118. package/data/experts/gis/gis-qa-engineer.md +133 -0
  119. package/data/experts/gis/gis-solution-engineer.md +101 -0
  120. package/data/experts/gis/gis-spatial-data-engineer.md +97 -0
  121. package/data/experts/gis/gis-spatial-data-scientist.md +111 -0
  122. package/data/experts/gis/gis-technical-consultant.md +86 -0
  123. package/data/experts/gis/gis-web-gis-developer.md +108 -0
  124. package/data/experts/healthcare/healthcare-clinical-evidence-agent.md +231 -0
  125. package/data/experts/healthcare/healthcare-innovation-strategist.md +433 -0
  126. package/data/experts/healthcare/healthcare-sovereign-health-systems-agent.md +312 -0
  127. package/data/experts/marketing/marketing-aeo-foundations.md +264 -0
  128. package/data/experts/marketing/marketing-agentic-search-optimizer.md +313 -0
  129. package/data/experts/marketing/marketing-ai-citation-strategist.md +172 -0
  130. package/data/experts/marketing/marketing-app-store-optimizer.md +321 -0
  131. package/data/experts/marketing/marketing-baidu-seo-specialist.md +226 -0
  132. package/data/experts/marketing/marketing-bilibili-content-strategist.md +199 -0
  133. package/data/experts/marketing/marketing-book-co-author.md +110 -0
  134. package/data/experts/marketing/marketing-carousel-growth-engine.md +199 -0
  135. package/data/experts/marketing/marketing-china-ecommerce-operator.md +283 -0
  136. package/data/experts/marketing/marketing-china-market-localization-strategist.md +283 -0
  137. package/data/experts/marketing/marketing-content-creator.md +54 -0
  138. package/data/experts/marketing/marketing-cross-border-ecommerce.md +259 -0
  139. package/data/experts/marketing/marketing-douyin-strategist.md +149 -0
  140. package/data/experts/marketing/marketing-email-strategist.md +249 -0
  141. package/data/experts/marketing/marketing-global-podcast-strategist.md +206 -0
  142. package/data/experts/marketing/marketing-growth-hacker.md +54 -0
  143. package/data/experts/marketing/marketing-instagram-curator.md +113 -0
  144. package/data/experts/marketing/marketing-kuaishou-strategist.md +223 -0
  145. package/data/experts/marketing/marketing-linkedin-content-creator.md +214 -0
  146. package/data/experts/marketing/marketing-livestream-commerce-coach.md +305 -0
  147. package/data/experts/marketing/marketing-multi-platform-publisher.md +217 -0
  148. package/data/experts/marketing/marketing-podcast-strategist.md +277 -0
  149. package/data/experts/marketing/marketing-pr-communications-manager.md +473 -0
  150. package/data/experts/marketing/marketing-private-domain-operator.md +308 -0
  151. package/data/experts/marketing/marketing-reddit-community-builder.md +123 -0
  152. package/data/experts/marketing/marketing-seo-specialist.md +370 -0
  153. package/data/experts/marketing/marketing-short-video-editing-coach.md +412 -0
  154. package/data/experts/marketing/marketing-social-media-strategist.md +125 -0
  155. package/data/experts/marketing/marketing-tiktok-strategist.md +125 -0
  156. package/data/experts/marketing/marketing-twitter-engager.md +126 -0
  157. package/data/experts/marketing/marketing-video-optimization-specialist.md +119 -0
  158. package/data/experts/marketing/marketing-wechat-official-account.md +145 -0
  159. package/data/experts/marketing/marketing-weibo-strategist.md +240 -0
  160. package/data/experts/marketing/marketing-x-twitter-intelligence-analyst.md +161 -0
  161. package/data/experts/marketing/marketing-xiaohongshu-specialist.md +138 -0
  162. package/data/experts/marketing/marketing-zhihu-strategist.md +162 -0
  163. package/data/experts/paid-media/paid-media-auditor.md +71 -0
  164. package/data/experts/paid-media/paid-media-creative-strategist.md +71 -0
  165. package/data/experts/paid-media/paid-media-paid-social-strategist.md +71 -0
  166. package/data/experts/paid-media/paid-media-ppc-strategist.md +71 -0
  167. package/data/experts/paid-media/paid-media-programmatic-buyer.md +71 -0
  168. package/data/experts/paid-media/paid-media-search-query-analyst.md +71 -0
  169. package/data/experts/paid-media/paid-media-tracking-specialist.md +71 -0
  170. package/data/experts/product/product-behavioral-nudge-engine.md +80 -0
  171. package/data/experts/product/product-feedback-synthesizer.md +119 -0
  172. package/data/experts/product/product-manager.md +469 -0
  173. package/data/experts/product/product-sprint-prioritizer.md +154 -0
  174. package/data/experts/product/product-trend-researcher.md +159 -0
  175. package/data/experts/project-management/project-management-experiment-tracker.md +198 -0
  176. package/data/experts/project-management/project-management-jira-workflow-steward.md +230 -0
  177. package/data/experts/project-management/project-management-meeting-notes-specialist.md +95 -0
  178. package/data/experts/project-management/project-management-project-shepherd.md +194 -0
  179. package/data/experts/project-management/project-management-studio-operations.md +200 -0
  180. package/data/experts/project-management/project-management-studio-producer.md +203 -0
  181. package/data/experts/project-management/project-manager-senior.md +135 -0
  182. package/data/experts/research/research-synthesist.md +136 -0
  183. package/data/experts/sales/sales-account-strategist.md +227 -0
  184. package/data/experts/sales/sales-coach.md +271 -0
  185. package/data/experts/sales/sales-deal-strategist.md +180 -0
  186. package/data/experts/sales/sales-discovery-coach.md +225 -0
  187. package/data/experts/sales/sales-engineer.md +182 -0
  188. package/data/experts/sales/sales-offer-lead-gen-strategist.md +257 -0
  189. package/data/experts/sales/sales-outbound-strategist.md +201 -0
  190. package/data/experts/sales/sales-pipeline-analyst.md +267 -0
  191. package/data/experts/sales/sales-proposal-strategist.md +217 -0
  192. package/data/experts/security/security-ai-generated-code-auditor.md +207 -0
  193. package/data/experts/security/security-appsec-engineer.md +491 -0
  194. package/data/experts/security/security-architect.md +304 -0
  195. package/data/experts/security/security-blockchain-security-auditor.md +463 -0
  196. package/data/experts/security/security-cloud-security-architect.md +523 -0
  197. package/data/experts/security/security-compliance-auditor.md +158 -0
  198. package/data/experts/security/security-incident-responder.md +437 -0
  199. package/data/experts/security/security-penetration-tester.md +399 -0
  200. package/data/experts/security/security-secrets-credential-engineer.md +176 -0
  201. package/data/experts/security/security-senior-secops.md +750 -0
  202. package/data/experts/security/security-threat-detection-engineer.md +534 -0
  203. package/data/experts/security/security-threat-intelligence-analyst.md +644 -0
  204. package/data/experts/spatial-computing/macos-spatial-metal-engineer.md +337 -0
  205. package/data/experts/spatial-computing/terminal-integration-specialist.md +70 -0
  206. package/data/experts/spatial-computing/visionos-spatial-engineer.md +54 -0
  207. package/data/experts/spatial-computing/xr-cockpit-interaction-specialist.md +32 -0
  208. package/data/experts/spatial-computing/xr-immersive-developer.md +32 -0
  209. package/data/experts/spatial-computing/xr-interface-architect.md +32 -0
  210. package/data/experts/specialized/accounts-payable-agent.md +185 -0
  211. package/data/experts/specialized/agentic-identity-trust.md +387 -0
  212. package/data/experts/specialized/agents-orchestrator.md +367 -0
  213. package/data/experts/specialized/automation-governance-architect.md +216 -0
  214. package/data/experts/specialized/business-strategist.md +488 -0
  215. package/data/experts/specialized/change-management-consultant.md +497 -0
  216. package/data/experts/specialized/chief-financial-officer.md +388 -0
  217. package/data/experts/specialized/corporate-training-designer.md +192 -0
  218. package/data/experts/specialized/customer-service.md +398 -0
  219. package/data/experts/specialized/customer-success-manager.md +460 -0
  220. package/data/experts/specialized/data-consolidation-agent.md +60 -0
  221. package/data/experts/specialized/data-privacy-officer.md +412 -0
  222. package/data/experts/specialized/esg-sustainability-officer.md +396 -0
  223. package/data/experts/specialized/government-digital-presales-consultant.md +363 -0
  224. package/data/experts/specialized/grant-writer.md +511 -0
  225. package/data/experts/specialized/healthcare-aging-parent-care-companion.md +414 -0
  226. package/data/experts/specialized/healthcare-customer-service.md +389 -0
  227. package/data/experts/specialized/healthcare-marketing-compliance.md +395 -0
  228. package/data/experts/specialized/hospitality-guest-services.md +603 -0
  229. package/data/experts/specialized/hr-onboarding.md +451 -0
  230. package/data/experts/specialized/identity-graph-operator.md +260 -0
  231. package/data/experts/specialized/language-translator.md +264 -0
  232. package/data/experts/specialized/legal-billing-time-tracking.md +569 -0
  233. package/data/experts/specialized/legal-client-intake.md +492 -0
  234. package/data/experts/specialized/legal-document-review.md +454 -0
  235. package/data/experts/specialized/loan-officer-assistant.md +555 -0
  236. package/data/experts/specialized/lsp-index-engineer.md +314 -0
  237. package/data/experts/specialized/ma-integration-manager.md +427 -0
  238. package/data/experts/specialized/medical-billing-coding-specialist.md +491 -0
  239. package/data/experts/specialized/operations-manager.md +399 -0
  240. package/data/experts/specialized/organizational-psychologist.md +391 -0
  241. package/data/experts/specialized/personal-growth-mentor.md +159 -0
  242. package/data/experts/specialized/real-estate-buyer-seller.md +596 -0
  243. package/data/experts/specialized/recruitment-specialist.md +509 -0
  244. package/data/experts/specialized/report-distribution-agent.md +65 -0
  245. package/data/experts/specialized/resume-tailor.md +230 -0
  246. package/data/experts/specialized/retail-customer-returns.md +566 -0
  247. package/data/experts/specialized/sales-data-extraction-agent.md +67 -0
  248. package/data/experts/specialized/sales-outreach.md +425 -0
  249. package/data/experts/specialized/specialized-chief-of-staff.md +279 -0
  250. package/data/experts/specialized/specialized-civil-engineer.md +356 -0
  251. package/data/experts/specialized/specialized-codebase-archaeologist.md +341 -0
  252. package/data/experts/specialized/specialized-cultural-intelligence-strategist.md +88 -0
  253. package/data/experts/specialized/specialized-developer-advocate.md +317 -0
  254. package/data/experts/specialized/specialized-document-generator.md +55 -0
  255. package/data/experts/specialized/specialized-fedramp-rmf-compliance.md +378 -0
  256. package/data/experts/specialized/specialized-focus-music-architect.md +172 -0
  257. package/data/experts/specialized/specialized-french-consulting-market.md +194 -0
  258. package/data/experts/specialized/specialized-korean-business-navigator.md +216 -0
  259. package/data/experts/specialized/specialized-master-plan-architect.md +157 -0
  260. package/data/experts/specialized/specialized-mcp-builder.md +248 -0
  261. package/data/experts/specialized/specialized-model-qa.md +488 -0
  262. package/data/experts/specialized/specialized-pricing-analyst.md +243 -0
  263. package/data/experts/specialized/specialized-salesforce-architect.md +182 -0
  264. package/data/experts/specialized/specialized-strategy-duel-agent.md +130 -0
  265. package/data/experts/specialized/specialized-workflow-architect.md +597 -0
  266. package/data/experts/specialized/study-abroad-advisor.md +282 -0
  267. package/data/experts/specialized/supply-chain-strategist.md +582 -0
  268. package/data/experts/specialized/zk-steward.md +211 -0
  269. package/data/experts/support/support-analytics-reporter.md +365 -0
  270. package/data/experts/support/support-executive-summary-generator.md +212 -0
  271. package/data/experts/support/support-finance-tracker.md +442 -0
  272. package/data/experts/support/support-infrastructure-maintainer.md +618 -0
  273. package/data/experts/support/support-legal-compliance-checker.md +588 -0
  274. package/data/experts/support/support-support-responder.md +585 -0
  275. package/data/experts/testing/testing-accessibility-auditor.md +316 -0
  276. package/data/experts/testing/testing-api-tester.md +306 -0
  277. package/data/experts/testing/testing-evidence-collector.md +210 -0
  278. package/data/experts/testing/testing-performance-benchmarker.md +268 -0
  279. package/data/experts/testing/testing-reality-checker.md +249 -0
  280. package/data/experts/testing/testing-test-automation-engineer.md +179 -0
  281. package/data/experts/testing/testing-test-results-analyzer.md +305 -0
  282. package/data/experts/testing/testing-tool-evaluator.md +394 -0
  283. package/data/experts/testing/testing-workflow-optimizer.md +450 -0
  284. package/data/source.json +27 -0
  285. package/data/t-team.config.json +998 -0
  286. package/data/team-profiles.py +365 -0
  287. package/data/teams.json +581 -0
  288. package/data/teams.resolved.json +1121 -0
  289. package/data/zh/COVERAGE.json +20 -0
  290. package/data/zh/academic/academic-anthropologist.md +124 -0
  291. package/data/zh/academic/academic-geographer.md +126 -0
  292. package/data/zh/academic/academic-historian.md +122 -0
  293. package/data/zh/academic/academic-narratologist.md +117 -0
  294. package/data/zh/academic/academic-psychologist.md +117 -0
  295. package/data/zh/academic/academic-statistician.md +40 -0
  296. package/data/zh/descriptions.json +281 -0
  297. package/data/zh/design/design-brand-guardian.md +321 -0
  298. package/data/zh/design/design-image-prompt-engineer.md +255 -0
  299. package/data/zh/design/design-inclusive-visuals-specialist.md +177 -0
  300. package/data/zh/design/design-persona-walkthrough.md +271 -0
  301. package/data/zh/design/design-ui-designer.md +382 -0
  302. package/data/zh/design/design-ui-finish-gate-reviewer.md +40 -0
  303. package/data/zh/design/design-ux-architect.md +482 -0
  304. package/data/zh/design/design-ux-researcher.md +328 -0
  305. package/data/zh/design/design-visual-storyteller.md +159 -0
  306. package/data/zh/design/design-whimsy-injector.md +453 -0
  307. package/data/zh/divisions.json +74 -0
  308. package/data/zh/engineering/engineering-ai-data-remediation-engineer.md +209 -0
  309. package/data/zh/engineering/engineering-ai-engineer.md +161 -0
  310. package/data/zh/engineering/engineering-api-platform-engineer.md +40 -0
  311. package/data/zh/engineering/engineering-ats-validator-architect.md +383 -0
  312. package/data/zh/engineering/engineering-autonomous-optimization-architect.md +115 -0
  313. package/data/zh/engineering/engineering-backend-architect.md +234 -0
  314. package/data/zh/engineering/engineering-china-network-engineer.md +252 -0
  315. package/data/zh/engineering/engineering-cms-developer.md +534 -0
  316. package/data/zh/engineering/engineering-code-reviewer.md +172 -0
  317. package/data/zh/engineering/engineering-codebase-onboarding-engineer.md +172 -0
  318. package/data/zh/engineering/engineering-data-engineer.md +324 -0
  319. package/data/zh/engineering/engineering-data-visualization-engineer.md +40 -0
  320. package/data/zh/engineering/engineering-database-optimizer.md +175 -0
  321. package/data/zh/engineering/engineering-database-reliability-engineer.md +40 -0
  322. package/data/zh/engineering/engineering-desktop-app-engineer.md +40 -0
  323. package/data/zh/engineering/engineering-developer-tooling-engineer.md +40 -0
  324. package/data/zh/engineering/engineering-devops-automator.md +375 -0
  325. package/data/zh/engineering/engineering-drupal-performance.md +40 -0
  326. package/data/zh/engineering/engineering-drupal-shopping-cart.md +359 -0
  327. package/data/zh/engineering/engineering-email-intelligence-engineer.md +349 -0
  328. package/data/zh/engineering/engineering-embedded-firmware-engineer.md +168 -0
  329. package/data/zh/engineering/engineering-feishu-integration-developer.md +597 -0
  330. package/data/zh/engineering/engineering-filament-optimization-specialist.md +283 -0
  331. package/data/zh/engineering/engineering-finops-engineer.md +40 -0
  332. package/data/zh/engineering/engineering-frontend-developer.md +224 -0
  333. package/data/zh/engineering/engineering-gaussdb-expert.md +40 -0
  334. package/data/zh/engineering/engineering-git-workflow-master.md +220 -0
  335. package/data/zh/engineering/engineering-i18n-engineer.md +40 -0
  336. package/data/zh/engineering/engineering-identity-access-engineer.md +40 -0
  337. package/data/zh/engineering/engineering-incident-response-commander.md +465 -0
  338. package/data/zh/engineering/engineering-iot-fleet-engineer.md +40 -0
  339. package/data/zh/engineering/engineering-it-service-manager.md +560 -0
  340. package/data/zh/engineering/engineering-knowledge-graph-engineer.md +40 -0
  341. package/data/zh/engineering/engineering-llm-post-training-engineer.md +40 -0
  342. package/data/zh/engineering/engineering-minimal-change-engineer.md +206 -0
  343. package/data/zh/engineering/engineering-mobile-app-builder.md +434 -0
  344. package/data/zh/engineering/engineering-mobile-release-engineer.md +40 -0
  345. package/data/zh/engineering/engineering-multi-agent-systems-architect.md +599 -0
  346. package/data/zh/engineering/engineering-network-engineer.md +40 -0
  347. package/data/zh/engineering/engineering-orgscript-engineer.md +112 -0
  348. package/data/zh/engineering/engineering-payments-billing-engineer.md +40 -0
  349. package/data/zh/engineering/engineering-pdf-engine-architect.md +666 -0
  350. package/data/zh/engineering/engineering-platform-engineer.md +271 -0
  351. package/data/zh/engineering/engineering-privacy-engineer.md +40 -0
  352. package/data/zh/engineering/engineering-prompt-engineer.md +203 -0
  353. package/data/zh/engineering/engineering-rag-pipeline-engineer.md +40 -0
  354. package/data/zh/engineering/engineering-rapid-prototyper.md +461 -0
  355. package/data/zh/engineering/engineering-realtime-collaboration-engineer.md +40 -0
  356. package/data/zh/engineering/engineering-rust-refactoring-specialist.md +40 -0
  357. package/data/zh/engineering/engineering-search-relevance-engineer.md +40 -0
  358. package/data/zh/engineering/engineering-section-508-specialist.md +40 -0
  359. package/data/zh/engineering/engineering-senior-developer.md +177 -0
  360. package/data/zh/engineering/engineering-software-architect.md +200 -0
  361. package/data/zh/engineering/engineering-solidity-smart-contract-engineer.md +541 -0
  362. package/data/zh/engineering/engineering-sre.md +233 -0
  363. package/data/zh/engineering/engineering-technical-writer.md +409 -0
  364. package/data/zh/engineering/engineering-universal-document-compiler.md +344 -0
  365. package/data/zh/engineering/engineering-uswds-developer.md +40 -0
  366. package/data/zh/engineering/engineering-video-streaming-engineer.md +40 -0
  367. package/data/zh/engineering/engineering-voice-ai-integration-engineer.md +560 -0
  368. package/data/zh/engineering/engineering-webassembly-engineer.md +40 -0
  369. package/data/zh/engineering/engineering-wechat-mini-program-developer.md +288 -0
  370. package/data/zh/engineering/engineering-wordpress-performance.md +40 -0
  371. package/data/zh/engineering/engineering-wordpress-shopping-cart.md +345 -0
  372. package/data/zh/finance/finance-bookkeeper-controller.md +271 -0
  373. package/data/zh/finance/finance-financial-analyst.md +244 -0
  374. package/data/zh/finance/finance-fpa-analyst.md +272 -0
  375. package/data/zh/finance/finance-investment-researcher.md +283 -0
  376. package/data/zh/finance/finance-tax-strategist.md +250 -0
  377. package/data/zh/game-development/blender/blender-addon-engineer.md +233 -0
  378. package/data/zh/game-development/economy-designer.md +40 -0
  379. package/data/zh/game-development/game-audio-engineer.md +265 -0
  380. package/data/zh/game-development/game-designer.md +168 -0
  381. package/data/zh/game-development/godot/godot-gameplay-scripter.md +335 -0
  382. package/data/zh/game-development/godot/godot-multiplayer-engineer.md +296 -0
  383. package/data/zh/game-development/godot/godot-shader-developer.md +267 -0
  384. package/data/zh/game-development/level-designer.md +209 -0
  385. package/data/zh/game-development/narrative-designer.md +244 -0
  386. package/data/zh/game-development/roblox-studio/roblox-avatar-creator.md +298 -0
  387. package/data/zh/game-development/roblox-studio/roblox-experience-designer.md +306 -0
  388. package/data/zh/game-development/roblox-studio/roblox-systems-scripter.md +325 -0
  389. package/data/zh/game-development/technical-artist.md +230 -0
  390. package/data/zh/game-development/unity/unity-architect.md +272 -0
  391. package/data/zh/game-development/unity/unity-editor-tool-developer.md +300 -0
  392. package/data/zh/game-development/unity/unity-multiplayer-engineer.md +238 -0
  393. package/data/zh/game-development/unity/unity-shader-graph-artist.md +270 -0
  394. package/data/zh/game-development/unreal-engine/unreal-multiplayer-architect.md +314 -0
  395. package/data/zh/game-development/unreal-engine/unreal-systems-engineer.md +311 -0
  396. package/data/zh/game-development/unreal-engine/unreal-technical-artist.md +256 -0
  397. package/data/zh/game-development/unreal-engine/unreal-world-builder.md +274 -0
  398. package/data/zh/gis/gis-3d-scene-developer.md +110 -0
  399. package/data/zh/gis/gis-analyst.md +90 -0
  400. package/data/zh/gis/gis-bim-specialist.md +107 -0
  401. package/data/zh/gis/gis-cartography-designer.md +149 -0
  402. package/data/zh/gis/gis-drone-reality-mapping.md +119 -0
  403. package/data/zh/gis/gis-geoai-ml-engineer.md +104 -0
  404. package/data/zh/gis/gis-geoprocessing-specialist.md +96 -0
  405. package/data/zh/gis/gis-qa-engineer.md +132 -0
  406. package/data/zh/gis/gis-solution-engineer.md +100 -0
  407. package/data/zh/gis/gis-spatial-data-engineer.md +96 -0
  408. package/data/zh/gis/gis-spatial-data-scientist.md +110 -0
  409. package/data/zh/gis/gis-technical-consultant.md +85 -0
  410. package/data/zh/gis/gis-web-gis-developer.md +107 -0
  411. package/data/zh/healthcare/healthcare-clinical-evidence-agent.md +40 -0
  412. package/data/zh/healthcare/healthcare-innovation-strategist.md +40 -0
  413. package/data/zh/healthcare/healthcare-sovereign-health-systems-agent.md +40 -0
  414. package/data/zh/manual-bodies/engineering/engineering-ats-validator-architect.md +383 -0
  415. package/data/zh/manual-bodies/engineering/engineering-china-network-engineer.md +252 -0
  416. package/data/zh/manual-bodies/engineering/engineering-pdf-engine-architect.md +666 -0
  417. package/data/zh/manual-bodies/engineering/engineering-platform-engineer.md +271 -0
  418. package/data/zh/manual-bodies/engineering/engineering-universal-document-compiler.md +344 -0
  419. package/data/zh/manual-bodies/specialized/specialized-focus-music-architect.md +172 -0
  420. package/data/zh/manual.json +22 -0
  421. package/data/zh/marketing/marketing-aeo-foundations.md +263 -0
  422. package/data/zh/marketing/marketing-agentic-search-optimizer.md +312 -0
  423. package/data/zh/marketing/marketing-ai-citation-strategist.md +169 -0
  424. package/data/zh/marketing/marketing-app-store-optimizer.md +319 -0
  425. package/data/zh/marketing/marketing-baidu-seo-specialist.md +220 -0
  426. package/data/zh/marketing/marketing-bilibili-content-strategist.md +40 -0
  427. package/data/zh/marketing/marketing-book-co-author.md +109 -0
  428. package/data/zh/marketing/marketing-carousel-growth-engine.md +215 -0
  429. package/data/zh/marketing/marketing-china-ecommerce-operator.md +277 -0
  430. package/data/zh/marketing/marketing-china-market-localization-strategist.md +282 -0
  431. package/data/zh/marketing/marketing-content-creator.md +145 -0
  432. package/data/zh/marketing/marketing-cross-border-ecommerce.md +260 -0
  433. package/data/zh/marketing/marketing-douyin-strategist.md +150 -0
  434. package/data/zh/marketing/marketing-email-strategist.md +248 -0
  435. package/data/zh/marketing/marketing-global-podcast-strategist.md +204 -0
  436. package/data/zh/marketing/marketing-growth-hacker.md +121 -0
  437. package/data/zh/marketing/marketing-instagram-curator.md +179 -0
  438. package/data/zh/marketing/marketing-kuaishou-strategist.md +182 -0
  439. package/data/zh/marketing/marketing-linkedin-content-creator.md +232 -0
  440. package/data/zh/marketing/marketing-livestream-commerce-coach.md +303 -0
  441. package/data/zh/marketing/marketing-multi-platform-publisher.md +216 -0
  442. package/data/zh/marketing/marketing-podcast-strategist.md +278 -0
  443. package/data/zh/marketing/marketing-pr-communications-manager.md +472 -0
  444. package/data/zh/marketing/marketing-private-domain-operator.md +309 -0
  445. package/data/zh/marketing/marketing-reddit-community-builder.md +127 -0
  446. package/data/zh/marketing/marketing-seo-specialist.md +298 -0
  447. package/data/zh/marketing/marketing-short-video-editing-coach.md +413 -0
  448. package/data/zh/marketing/marketing-social-media-strategist.md +118 -0
  449. package/data/zh/marketing/marketing-tiktok-strategist.md +124 -0
  450. package/data/zh/marketing/marketing-twitter-engager.md +132 -0
  451. package/data/zh/marketing/marketing-video-optimization-specialist.md +128 -0
  452. package/data/zh/marketing/marketing-wechat-official-account.md +158 -0
  453. package/data/zh/marketing/marketing-weibo-strategist.md +241 -0
  454. package/data/zh/marketing/marketing-x-twitter-intelligence-analyst.md +160 -0
  455. package/data/zh/marketing/marketing-xiaohongshu-specialist.md +151 -0
  456. package/data/zh/marketing/marketing-zhihu-strategist.md +175 -0
  457. package/data/zh/names.json +281 -0
  458. package/data/zh/paid-media/paid-media-auditor.md +170 -0
  459. package/data/zh/paid-media/paid-media-creative-strategist.md +173 -0
  460. package/data/zh/paid-media/paid-media-paid-social-strategist.md +180 -0
  461. package/data/zh/paid-media/paid-media-ppc-strategist.md +180 -0
  462. package/data/zh/paid-media/paid-media-programmatic-buyer.md +177 -0
  463. package/data/zh/paid-media/paid-media-search-query-analyst.md +182 -0
  464. package/data/zh/paid-media/paid-media-tracking-specialist.md +199 -0
  465. package/data/zh/product/product-behavioral-nudge-engine.md +246 -0
  466. package/data/zh/product/product-feedback-synthesizer.md +175 -0
  467. package/data/zh/product/product-manager.md +474 -0
  468. package/data/zh/product/product-sprint-prioritizer.md +133 -0
  469. package/data/zh/product/product-trend-researcher.md +143 -0
  470. package/data/zh/project-management/project-management-experiment-tracker.md +206 -0
  471. package/data/zh/project-management/project-management-jira-workflow-steward.md +249 -0
  472. package/data/zh/project-management/project-management-meeting-notes-specialist.md +94 -0
  473. package/data/zh/project-management/project-management-project-shepherd.md +202 -0
  474. package/data/zh/project-management/project-management-studio-operations.md +208 -0
  475. package/data/zh/project-management/project-management-studio-producer.md +211 -0
  476. package/data/zh/project-management/project-manager-senior.md +135 -0
  477. package/data/zh/research/research-synthesist.md +40 -0
  478. package/data/zh/sales/sales-account-strategist.md +243 -0
  479. package/data/zh/sales/sales-coach.md +291 -0
  480. package/data/zh/sales/sales-deal-strategist.md +204 -0
  481. package/data/zh/sales/sales-discovery-coach.md +230 -0
  482. package/data/zh/sales/sales-engineer.md +200 -0
  483. package/data/zh/sales/sales-offer-lead-gen-strategist.md +256 -0
  484. package/data/zh/sales/sales-outbound-strategist.md +208 -0
  485. package/data/zh/sales/sales-pipeline-analyst.md +284 -0
  486. package/data/zh/sales/sales-proposal-strategist.md +233 -0
  487. package/data/zh/security/security-ai-generated-code-auditor.md +40 -0
  488. package/data/zh/security/security-appsec-engineer.md +490 -0
  489. package/data/zh/security/security-architect.md +303 -0
  490. package/data/zh/security/security-blockchain-security-auditor.md +462 -0
  491. package/data/zh/security/security-cloud-security-architect.md +522 -0
  492. package/data/zh/security/security-compliance-auditor.md +157 -0
  493. package/data/zh/security/security-incident-responder.md +436 -0
  494. package/data/zh/security/security-penetration-tester.md +398 -0
  495. package/data/zh/security/security-secrets-credential-engineer.md +40 -0
  496. package/data/zh/security/security-senior-secops.md +751 -0
  497. package/data/zh/security/security-threat-detection-engineer.md +533 -0
  498. package/data/zh/security/security-threat-intelligence-analyst.md +643 -0
  499. package/data/zh/spatial-computing/macos-spatial-metal-engineer.md +337 -0
  500. package/data/zh/spatial-computing/terminal-integration-specialist.md +236 -0
  501. package/data/zh/spatial-computing/visionos-spatial-engineer.md +282 -0
  502. package/data/zh/spatial-computing/xr-cockpit-interaction-specialist.md +220 -0
  503. package/data/zh/spatial-computing/xr-immersive-developer.md +229 -0
  504. package/data/zh/spatial-computing/xr-interface-architect.md +253 -0
  505. package/data/zh/specialized/accounts-payable-agent.md +212 -0
  506. package/data/zh/specialized/agentic-identity-trust.md +388 -0
  507. package/data/zh/specialized/agents-orchestrator.md +366 -0
  508. package/data/zh/specialized/automation-governance-architect.md +215 -0
  509. package/data/zh/specialized/business-strategist.md +487 -0
  510. package/data/zh/specialized/change-management-consultant.md +495 -0
  511. package/data/zh/specialized/chief-financial-officer.md +390 -0
  512. package/data/zh/specialized/corporate-training-designer.md +191 -0
  513. package/data/zh/specialized/customer-service.md +40 -0
  514. package/data/zh/specialized/customer-success-manager.md +458 -0
  515. package/data/zh/specialized/data-consolidation-agent.md +327 -0
  516. package/data/zh/specialized/data-privacy-officer.md +411 -0
  517. package/data/zh/specialized/esg-sustainability-officer.md +395 -0
  518. package/data/zh/specialized/government-digital-presales-consultant.md +362 -0
  519. package/data/zh/specialized/grant-writer.md +510 -0
  520. package/data/zh/specialized/healthcare-aging-parent-care-companion.md +40 -0
  521. package/data/zh/specialized/healthcare-customer-service.md +388 -0
  522. package/data/zh/specialized/healthcare-marketing-compliance.md +394 -0
  523. package/data/zh/specialized/hospitality-guest-services.md +597 -0
  524. package/data/zh/specialized/hr-onboarding.md +450 -0
  525. package/data/zh/specialized/identity-graph-operator.md +270 -0
  526. package/data/zh/specialized/language-translator.md +275 -0
  527. package/data/zh/specialized/legal-billing-time-tracking.md +566 -0
  528. package/data/zh/specialized/legal-client-intake.md +487 -0
  529. package/data/zh/specialized/legal-document-review.md +452 -0
  530. package/data/zh/specialized/loan-officer-assistant.md +549 -0
  531. package/data/zh/specialized/lsp-index-engineer.md +334 -0
  532. package/data/zh/specialized/ma-integration-manager.md +426 -0
  533. package/data/zh/specialized/medical-billing-coding-specialist.md +489 -0
  534. package/data/zh/specialized/operations-manager.md +398 -0
  535. package/data/zh/specialized/organizational-psychologist.md +390 -0
  536. package/data/zh/specialized/personal-growth-mentor.md +158 -0
  537. package/data/zh/specialized/real-estate-buyer-seller.md +594 -0
  538. package/data/zh/specialized/recruitment-specialist.md +49 -0
  539. package/data/zh/specialized/report-distribution-agent.md +354 -0
  540. package/data/zh/specialized/resume-tailor.md +40 -0
  541. package/data/zh/specialized/retail-customer-returns.md +564 -0
  542. package/data/zh/specialized/sales-data-extraction-agent.md +159 -0
  543. package/data/zh/specialized/sales-outreach.md +40 -0
  544. package/data/zh/specialized/specialized-chief-of-staff.md +40 -0
  545. package/data/zh/specialized/specialized-civil-engineer.md +355 -0
  546. package/data/zh/specialized/specialized-codebase-archaeologist.md +40 -0
  547. package/data/zh/specialized/specialized-cultural-intelligence-strategist.md +168 -0
  548. package/data/zh/specialized/specialized-developer-advocate.md +334 -0
  549. package/data/zh/specialized/specialized-document-generator.md +346 -0
  550. package/data/zh/specialized/specialized-fedramp-rmf-compliance.md +40 -0
  551. package/data/zh/specialized/specialized-focus-music-architect.md +172 -0
  552. package/data/zh/specialized/specialized-french-consulting-market.md +46 -0
  553. package/data/zh/specialized/specialized-korean-business-navigator.md +46 -0
  554. package/data/zh/specialized/specialized-master-plan-architect.md +40 -0
  555. package/data/zh/specialized/specialized-mcp-builder.md +351 -0
  556. package/data/zh/specialized/specialized-model-qa.md +507 -0
  557. package/data/zh/specialized/specialized-pricing-analyst.md +242 -0
  558. package/data/zh/specialized/specialized-salesforce-architect.md +179 -0
  559. package/data/zh/specialized/specialized-strategy-duel-agent.md +129 -0
  560. package/data/zh/specialized/specialized-workflow-architect.md +596 -0
  561. package/data/zh/specialized/study-abroad-advisor.md +281 -0
  562. package/data/zh/specialized/supply-chain-strategist.md +581 -0
  563. package/data/zh/specialized/zk-steward.md +228 -0
  564. package/data/zh/support/support-analytics-reporter.md +364 -0
  565. package/data/zh/support/support-executive-summary-generator.md +217 -0
  566. package/data/zh/support/support-finance-tracker.md +447 -0
  567. package/data/zh/support/support-infrastructure-maintainer.md +623 -0
  568. package/data/zh/support/support-legal-compliance-checker.md +587 -0
  569. package/data/zh/support/support-support-responder.md +584 -0
  570. package/data/zh/testing/testing-accessibility-auditor.md +329 -0
  571. package/data/zh/testing/testing-api-tester.md +305 -0
  572. package/data/zh/testing/testing-evidence-collector.md +153 -0
  573. package/data/zh/testing/testing-performance-benchmarker.md +196 -0
  574. package/data/zh/testing/testing-reality-checker.md +235 -0
  575. package/data/zh/testing/testing-test-automation-engineer.md +40 -0
  576. package/data/zh/testing/testing-test-results-analyzer.md +313 -0
  577. package/data/zh/testing/testing-tool-evaluator.md +402 -0
  578. package/data/zh/testing/testing-workflow-optimizer.md +458 -0
  579. package/lib/assets/t-team/action-celebrating-v2.png +0 -0
  580. package/lib/assets/t-team/action-reporting-v2.png +0 -0
  581. package/lib/assets/t-team/action-sending-v2.png +0 -0
  582. package/lib/assets/t-team/action-sleeping-v2.png +0 -0
  583. package/lib/assets/t-team/action-thinking-v2.png +0 -0
  584. package/lib/assets/t-team/action-working-v2.png +0 -0
  585. package/lib/assets/t-team/member-data-v2.png +0 -0
  586. package/lib/assets/t-team/member-designer-v2.png +0 -0
  587. package/lib/assets/t-team/member-docs-v2.png +0 -0
  588. package/lib/assets/t-team/member-engineer-v2.png +0 -0
  589. package/lib/assets/t-team/member-operator-v2.png +0 -0
  590. package/lib/assets/t-team/member-qa-v2.png +0 -0
  591. package/lib/assets/t-team/member-researcher-v2.png +0 -0
  592. package/lib/assets/t-team/member-security-v2.png +0 -0
  593. package/lib/assets/t-team/team-lead-v2.png +0 -0
  594. package/lib/bootstrap.js +85 -0
  595. package/lib/catalog.js +376 -0
  596. package/lib/client.js +21034 -0
  597. package/lib/command.js +228 -0
  598. package/lib/i18n.js +136 -0
  599. package/lib/index.js +686 -0
  600. package/lib/plan-check.js +171 -0
  601. package/lib/remote.js +353 -0
  602. package/lib/squads.js +231 -0
  603. package/lib/teams/capabilities.js +106 -0
  604. package/lib/teams/command.js +143 -0
  605. package/lib/teams/event-types.js +12 -0
  606. package/lib/teams/events.js +60 -0
  607. package/lib/teams/harness-compat.js +179 -0
  608. package/lib/teams/index.js +441 -0
  609. package/lib/teams/members.js +602 -0
  610. package/lib/teams/profiles.js +572 -0
  611. package/lib/teams/quality-gates.js +822 -0
  612. package/lib/teams/scheduler.js +434 -0
  613. package/lib/teams/snapshot.js +181 -0
  614. package/lib/teams/state.js +925 -0
  615. package/lib/teams/tool-names.js +11 -0
  616. package/lib/teams/tools.js +2279 -0
  617. package/lib/teams/types.js +22 -0
  618. package/lib/teams/web-routes.js +86 -0
  619. package/package.json +191 -0
package/lib/squads.js ADDED
@@ -0,0 +1,231 @@
1
+ /**
2
+ * T专家 小队数据层:读写 `teams.json`,并把改动编译成引擎配置。
3
+ *
4
+ * 职责边界:本文件只管**小队定义**(有哪些队、谁在里面、别名、启停),
5
+ * 编译交给既有的 `team-profiles.py`(它已内置成员名撞键预检、别名校验、人格注入)。
6
+ * 这样 UI 编辑器不需要复制一份校验逻辑,生成器仍是唯一权威。
7
+ */
8
+ import { readFileSync, writeFileSync, statSync, existsSync } from "node:fs";
9
+ import { execFileSync } from "node:child_process";
10
+ import { createHash } from "node:crypto";
11
+ import { dirname, join } from "node:path";
12
+
13
+ /** profile key 只允许小写 ASCII + 数字 + 连字符(引擎按它生成命令别名)。 */
14
+ const KEY_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
15
+
16
+ function text(value) {
17
+ return typeof value === "string" ? value : "";
18
+ }
19
+
20
+ function fail(code, message, details = {}) {
21
+ const error = new Error(message);
22
+ error.code = code;
23
+ error.details = details;
24
+ return error;
25
+ }
26
+
27
+ /** members 允许两种写法:slug 字符串,或 {slug|name, role} 对象(兼容手写)。 */
28
+ function memberSlug(member) {
29
+ if (typeof member === "string") return member.trim();
30
+ if (member !== null && typeof member === "object") {
31
+ for (const key of ["slug", "name", "role"]) {
32
+ if (typeof member[key] === "string" && member[key].trim() !== "") return member[key].trim();
33
+ }
34
+ }
35
+ return "";
36
+ }
37
+
38
+ export function createSquadService({ teamsFile, catalog, python = "python3" }) {
39
+ const dataDir = dirname(teamsFile);
40
+ const generator = join(dataDir, "team-profiles.py");
41
+ let lastBuild = { at: 0, ok: true, output: "" };
42
+
43
+ function readSpec() {
44
+ try {
45
+ const spec = JSON.parse(readFileSync(teamsFile, "utf8"));
46
+ return spec !== null && typeof spec === "object" ? spec : {};
47
+ } catch (error) {
48
+ throw fail("tTeam/squads-unreadable", `读不到小队定义 ${teamsFile}:${String(error)}`);
49
+ }
50
+ }
51
+
52
+ function revisionOf() {
53
+ try {
54
+ const stat = statSync(teamsFile);
55
+ const hash = createHash("sha256").update(readFileSync(teamsFile)).digest("hex").slice(0, 12);
56
+ return `${stat.mtimeMs.toString(36)}-${hash}`;
57
+ } catch {
58
+ return "missing";
59
+ }
60
+ }
61
+
62
+ /** 名册快照(成员选择器用):slug / 中英文名 / 分区 / 是否已启用。 */
63
+ async function roster() {
64
+ let experts = [];
65
+ let enabled = new Set();
66
+ try {
67
+ // 名册服务的 snapshot() 是异步的(它要读 settings),必须 await。
68
+ const snapshot = await catalog?.snapshot?.();
69
+ experts = snapshot?.experts ?? [];
70
+ enabled = new Set(snapshot?.enabled ?? []);
71
+ } catch {
72
+ /* 名册不可用时只给小队本身 */
73
+ }
74
+ const bySlug = new Map(experts.map((expert) => [expert.slug, expert]));
75
+ return {
76
+ experts: experts.map((expert) => ({
77
+ slug: expert.slug,
78
+ name: expert.name,
79
+ nameZh: expert.nameZh ?? expert.name,
80
+ division: expert.division,
81
+ divisionZh: expert.divisionZh ?? expert.division,
82
+ enabled: enabled.has(expert.slug),
83
+ conflict: expert.conflict === true,
84
+ })),
85
+ bySlug,
86
+ };
87
+ }
88
+
89
+ function describeMembers(members, bySlug) {
90
+ return (Array.isArray(members) ? members : []).map((member) => {
91
+ const slug = memberSlug(member);
92
+ const expert = bySlug.get(slug);
93
+ return {
94
+ slug,
95
+ role: typeof member === "object" && member !== null && typeof member.role === "string" ? member.role : "",
96
+ name: expert?.name ?? slug,
97
+ nameZh: expert?.nameZh ?? expert?.name ?? slug,
98
+ division: expert?.division ?? "",
99
+ divisionZh: expert?.divisionZh ?? expert?.division ?? "",
100
+ known: expert !== undefined,
101
+ };
102
+ });
103
+ }
104
+
105
+ async function list() {
106
+ const spec = readSpec();
107
+ const { bySlug, experts } = await roster();
108
+ const rawProfiles = spec.profiles !== null && typeof spec.profiles === "object" ? spec.profiles : {};
109
+ const squads = Object.entries(rawProfiles).map(([key, profile]) => {
110
+ const source = profile !== null && typeof profile === "object" ? profile : {};
111
+ return {
112
+ key,
113
+ description: text(source.description),
114
+ aliases: Array.isArray(source.aliases) ? source.aliases.filter((alias) => typeof alias === "string") : [],
115
+ taskPlanning: source.taskPlanning === "seed" ? "seed" : "captain",
116
+ // 缺省视为启用(老定义没有这个字段)
117
+ enabled: source.enabled !== false,
118
+ members: describeMembers(source.members, bySlug),
119
+ };
120
+ });
121
+ return {
122
+ revision: revisionOf(),
123
+ teamsFile,
124
+ squads,
125
+ experts,
126
+ engine: spec.engine ?? {},
127
+ defaults: spec.defaults ?? {},
128
+ lastBuild,
129
+ };
130
+ }
131
+
132
+ /** 校验(生成器之外的第一道闸门,错误信息面向面板)。 */
133
+ function validate(squads) {
134
+ if (!Array.isArray(squads) || squads.length === 0) {
135
+ throw fail("tTeam/squads-invalid", "至少要保留一个小队。");
136
+ }
137
+ const seenKeys = new Set();
138
+ const seenAliases = new Map();
139
+ squads.forEach((squad, index) => {
140
+ const label = `第 ${index + 1} 个小队`;
141
+ const key = text(squad?.key).trim();
142
+ if (!KEY_RE.test(key)) {
143
+ throw fail("tTeam/squads-invalid", `${label} 的 key「${key}」不合法:只能用小写字母、数字和连字符(例如 t-team-writing)。`);
144
+ }
145
+ if (seenKeys.has(key)) throw fail("tTeam/squads-invalid", `小队 key 重复:${key}`);
146
+ seenKeys.add(key);
147
+ const members = Array.isArray(squad?.members) ? squad.members.map(memberSlug).filter((slug) => slug !== "") : [];
148
+ if (members.length === 0) throw fail("tTeam/squads-invalid", `「${key}」没有成员:至少要选一位专家。`);
149
+ for (const alias of Array.isArray(squad?.aliases) ? squad.aliases : []) {
150
+ const value = text(alias).trim();
151
+ if (value === "") continue;
152
+ const owner = seenAliases.get(value);
153
+ if (owner !== undefined && owner !== key) {
154
+ throw fail("tTeam/squads-invalid", `别名「${value}」被 ${owner} 和 ${key} 同时占用,会让 /t 无法判断用哪个小队。`);
155
+ }
156
+ seenAliases.set(value, key);
157
+ }
158
+ });
159
+ }
160
+
161
+ /** 把 UI 传来的小队列表写回 teams.json(保留 engine/defaults 等顶层字段)。 */
162
+ function serialize(spec, squads) {
163
+ const previous = spec.profiles !== null && typeof spec.profiles === "object" ? spec.profiles : {};
164
+ const profiles = {};
165
+ for (const squad of squads) {
166
+ const key = text(squad.key).trim();
167
+ const members = (Array.isArray(squad.members) ? squad.members : [])
168
+ .map(memberSlug)
169
+ .filter((slug) => slug !== "");
170
+ // 保留面板没建模的字段(personaMode / personaBudget 等),只覆盖面板负责的那几项。
171
+ const merged = {
172
+ ...(previous[key] !== null && typeof previous[key] === "object" ? previous[key] : {}),
173
+ description: text(squad.description),
174
+ aliases: (Array.isArray(squad.aliases) ? squad.aliases : [])
175
+ .map((alias) => text(alias).trim())
176
+ .filter((alias) => alias !== ""),
177
+ taskPlanning: squad.taskPlanning === "seed" ? "seed" : "captain",
178
+ members,
179
+ };
180
+ if (squad.enabled === false) merged.enabled = false;
181
+ else delete merged.enabled;
182
+ profiles[key] = merged;
183
+ }
184
+ return { ...spec, profiles };
185
+ }
186
+
187
+ /** 跑生成器:编译 t-team.config.json + teams.resolved.json(失败即回滚 teams.json)。 */
188
+ function build() {
189
+ if (!existsSync(generator)) {
190
+ lastBuild = { at: Date.now(), ok: false, output: `找不到生成器 ${generator}` };
191
+ return lastBuild;
192
+ }
193
+ try {
194
+ const output = execFileSync(python, [generator, "--teams", teamsFile], {
195
+ cwd: dataDir,
196
+ encoding: "utf8",
197
+ stdio: ["ignore", "pipe", "pipe"],
198
+ timeout: 60_000,
199
+ });
200
+ lastBuild = { at: Date.now(), ok: true, output: output.trim().split("\n").slice(-6).join("\n") };
201
+ } catch (error) {
202
+ const output = [error?.stdout, error?.stderr].map((part) => text(part).trim()).filter((part) => part !== "").join("\n");
203
+ lastBuild = { at: Date.now(), ok: false, output: output === "" ? String(error) : output };
204
+ }
205
+ return lastBuild;
206
+ }
207
+
208
+ async function save(squads, expectedRevision) {
209
+ validate(squads);
210
+ const current = revisionOf();
211
+ if (typeof expectedRevision === "string" && expectedRevision !== "" && expectedRevision !== current) {
212
+ throw fail("tTeam/squads-conflict", "小队定义已在别处改动,请刷新后重试。", {
213
+ expectedRevision,
214
+ actualRevision: current,
215
+ });
216
+ }
217
+ const previousText = readFileSync(teamsFile, "utf8");
218
+ const nextSpec = serialize(readSpec(), squads);
219
+ writeFileSync(teamsFile, `${JSON.stringify(nextSpec, null, 2)}\n`);
220
+ const built = build();
221
+ if (!built.ok) {
222
+ writeFileSync(teamsFile, previousText); // 回滚,别把坏定义留在盘上
223
+ throw fail("tTeam/squads-build-failed", `配置生成失败,已回滚 teams.json:\n${built.output}`, {
224
+ actualRevision: revisionOf(),
225
+ });
226
+ }
227
+ return await list();
228
+ }
229
+
230
+ return { list, save, validate, revision: revisionOf, generator, dataDir };
231
+ }
@@ -0,0 +1,106 @@
1
+ import { readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { readTeamSync, readRetiredMemberIdsSync } from "./state.js";
4
+ import { MEMBER_TOOL_NAMES, TEAM_TOOL_NAMES } from "./tool-names.js";
5
+ export const TEAM_ACTIVATION_PROMPT = 'T Team (T专家 团队) provides multi-agent team collaboration. Apply these rules when the user requests it (including /t-team) or when continuing an existing team. Mentioning, quoting, discussing, or declining T Team alone is not a request to start work.';
6
+ export const TEAM_MEMBER_PROMPT = 'You are an T Team member. Follow your assigned member persona and task contract. Use t_team_claim_task, t_team_update_task, t_team_send_message and t_team_status for your own work. Include the current attempt_id in updates; report completion or failure to the captain. Do not create, approve, edit or resume a team. If your durable membership is unavailable, report that to the parent instead of creating a replacement.';
7
+ function stateRoot(agent, config) {
8
+ return join(agent.session.header.cwd ?? process.cwd(), config.stateDir);
9
+ }
10
+ /** Synchronous startup/HMR hydration must finish before the first assembly. */
11
+ function currentTeam(agent, config) {
12
+ const root = stateRoot(agent, config);
13
+ let entries;
14
+ try {
15
+ entries = readdirSync(root, { withFileTypes: true });
16
+ }
17
+ catch (error) {
18
+ if (error.code === 'ENOENT')
19
+ return undefined;
20
+ throw error;
21
+ }
22
+ let found;
23
+ for (const entry of entries) {
24
+ if (!entry.isDirectory() || entry.name === 'archive')
25
+ continue;
26
+ const team = readTeamSync(root, entry.name);
27
+ if (team === undefined || (team.captainSessionId !== agent.id
28
+ && !team.members.some(member => member.id === agent.id)))
29
+ continue;
30
+ if (found !== undefined)
31
+ throw new Error('ambiguous T Team membership');
32
+ found = team;
33
+ }
34
+ return found;
35
+ }
36
+ /** Call once, after all business definitions have registered. Never per member. */
37
+ export function installTeamCapabilities(ctx, config) {
38
+ const states = new WeakMap();
39
+ const active = new Set();
40
+ let mounted = true;
41
+ // Snapshot policy once: profiles, team state, and tool results must never
42
+ // rewrite this prefix or control whether core instructions are available.
43
+ const captainPrompt = `${TEAM_ACTIVATION_PROMPT}\n\n${config.captainPrompt()}`;
44
+ function attach(agent) {
45
+ const prior = states.get(agent);
46
+ if (prior !== undefined)
47
+ return prior;
48
+ if (!mounted)
49
+ throw new Error('T Team capability provider is disposed');
50
+ // Determine a member's role before its first request and retain it for the
51
+ // lifetime of this scope. Team creation/archive must never rewrite the
52
+ // captain's system/tools prefix, even after a long ordinary conversation.
53
+ let member = config.isPendingMember(agent);
54
+ try {
55
+ member ||= readRetiredMemberIdsSync(stateRoot(agent, config)).has(agent.id);
56
+ const team = currentTeam(agent, config);
57
+ member ||= team !== undefined && team.captainSessionId !== agent.id;
58
+ }
59
+ catch (error) {
60
+ // Unrelated damaged state must not disable ordinary conversation.
61
+ // Business tools still validate durable team state before acting.
62
+ ctx.logger.warn(`t-team: capability hydration failed: ${String(error)}`);
63
+ }
64
+ const state = { member, dispose: () => undefined };
65
+ let revoke;
66
+ let disposed = false;
67
+ let releaseLifetime;
68
+ state.dispose = () => {
69
+ if (disposed)
70
+ return;
71
+ disposed = true;
72
+ revoke?.();
73
+ releaseLifetime?.();
74
+ states.delete(agent);
75
+ active.delete(state);
76
+ };
77
+ states.set(agent, state);
78
+ active.add(state);
79
+ try {
80
+ if (member)
81
+ revoke = agent.ctx.tools.restrict({
82
+ deny: TEAM_TOOL_NAMES.filter(name => !MEMBER_TOOL_NAMES.includes(name)),
83
+ });
84
+ releaseLifetime = agent.ctx.effect(() => state.dispose, 't-team: capability lifetime');
85
+ return state;
86
+ }
87
+ catch (error) {
88
+ state.dispose();
89
+ throw error;
90
+ }
91
+ }
92
+ ctx.systemPrompt.section({
93
+ name: 't-team:usage', order: config.order ?? 117,
94
+ text: ({ agent }) => {
95
+ return agent !== undefined && states.get(agent)?.member ? TEAM_MEMBER_PROMPT : captainPrompt;
96
+ },
97
+ });
98
+ ctx.on('agent/session-start', ({ agent }) => { attach(agent); });
99
+ ctx.effect(() => () => {
100
+ mounted = false;
101
+ for (const state of [...active])
102
+ state.dispose();
103
+ }, 't-team: capability scopes');
104
+ for (const agent of ctx.agents.list())
105
+ attach(agent);
106
+ }
@@ -0,0 +1,143 @@
1
+ import { createUserMessage } from '@deepseek-ai/dsh-llm';
2
+ import { parseProfileInvocation, resolveProfileTaskPlanning } from "./profiles.js";
3
+ export const T_TEAM_COMMAND = 't';
4
+ const PROFILE_COMMAND_PREFIX = `${T_TEAM_COMMAND}-`;
5
+ const GESTURE = /^\/t(?=$|[\t\n\r ])/u;
6
+ /**
7
+ * Convert a configured profile key into a stable, closed-namespace command
8
+ * suffix. Only lowercase ASCII letters, digits and dashes are representable;
9
+ * this deliberately prevents accidental command aliases for ambiguous profile
10
+ * names such as `foo bar`, `foo_bar`, or non-ASCII keys.
11
+ */
12
+ export function profileCommandName(profileName) {
13
+ const normalized = profileName.trim().toLowerCase();
14
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(normalized))
15
+ return undefined;
16
+ return `${PROFILE_COMMAND_PREFIX}${normalized}`;
17
+ }
18
+ /** Resolve a profile command only when it maps uniquely to a live profile. */
19
+ function profileForCommand(commandName, profiles) {
20
+ const matches = Object.keys(profiles).filter((profileName) => profileCommandName(profileName) === commandName);
21
+ return matches.length === 1 ? matches[0] : undefined;
22
+ }
23
+ /** Parse either the generic command or one generated profile alias. */
24
+ function parseCommandText(text, profiles) {
25
+ const trimmed = text.trimStart();
26
+ if (GESTURE.test(trimmed))
27
+ return parseProfileInvocation(trimmed.slice(T_TEAM_COMMAND.length + 1).trim());
28
+ if (!trimmed.startsWith(`/${PROFILE_COMMAND_PREFIX}`))
29
+ return undefined;
30
+ const tokenEnd = trimmed.search(/[\t\n\r ]/u);
31
+ const commandName = trimmed.slice(1, tokenEnd === -1 ? undefined : tokenEnd);
32
+ const profile = profileForCommand(commandName, profiles);
33
+ if (profile === undefined)
34
+ return undefined;
35
+ return { profile, goal: (tokenEnd === -1 ? '' : trimmed.slice(tokenEnd)).trim() };
36
+ }
37
+ export function invokedTTeamInvocation(messages, getProfiles = () => ({})) {
38
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
39
+ const message = messages[index];
40
+ if (message === undefined || message.source.kind !== 'user')
41
+ continue;
42
+ for (const block of message.content) {
43
+ if (block.type !== 'text')
44
+ continue;
45
+ const invocation = parseCommandText(block.text, getProfiles());
46
+ if (invocation !== undefined)
47
+ return invocation;
48
+ }
49
+ }
50
+ return undefined;
51
+ }
52
+ export function invokedTTeamGoal(messages) {
53
+ return invokedTTeamInvocation(messages)?.goal;
54
+ }
55
+ export function buildActivationDirective(goal, profile, taskPlanning = 'seed') {
56
+ const lines = [
57
+ 'The user invoked a T Team slash command. Follow the T Team protocol already in your system instructions. Inspect existing team state with t_team_status when needed.',
58
+ 'Respect the current team state. Continue an existing plan or team without recreating it. Only when no current team exists, call t_team_create with approval="required". Build the complete staged roster and DAG, then stop and ask the user to review the Web plan. Do not approve or start it in this same turn.',
59
+ ];
60
+ if (profile !== undefined) {
61
+ lines.push(`Use profile="${profile}" when creating a new team.`);
62
+ if (taskPlanning === 'captain') {
63
+ lines.push('This profile supplies the roster and guardrails. After create, do not recreate members.', 'Derive the smallest useful task graph from the goal while the team is staged; do not ask the user whether to split, merge, serialize, or parallelize.', 'Independent supplemental work must become separate ready tasks so idle members can run in parallel. Add dependencies only for genuine prerequisites and later synthesis.');
64
+ }
65
+ else {
66
+ lines.push('Do not recreate the same members or seed tasks manually.');
67
+ }
68
+ }
69
+ lines.push(goal === '' ? 'The goal was not given — ask the user what the team should accomplish.' : `Goal: ${goal}`);
70
+ return lines.join('\n');
71
+ }
72
+ export function registerTTeamCommand(ctx, getProfiles = () => ({})) {
73
+ ctx.effect(() => {
74
+ const dispose = [];
75
+ dispose.push(ctx.commands.register({
76
+ name: T_TEAM_COMMAND,
77
+ description: 'run a goal with a multi-agent team (you become the captain)',
78
+ input: { hint: '[--profile <name>] <goal>' },
79
+ handler(invocation) {
80
+ let parsed;
81
+ try {
82
+ parsed = parseProfileInvocation(invocation.rawInput.trim());
83
+ }
84
+ catch (error) {
85
+ return { kind: 'error', text: String(error) };
86
+ }
87
+ if (parsed.profile !== undefined && !Object.keys(getProfiles()).some(key => key.trim() === parsed.profile))
88
+ return { kind: 'error', text: `未知的 T专家 小队「${parsed.profile}」` };
89
+ if (parsed.profile === undefined && parsed.goal === '')
90
+ return { kind: 'error', text: `Usage: /${T_TEAM_COMMAND} [--profile <name>] <goal>` };
91
+ invocation.agent.followup(createUserMessage({ content: [{ type: 'text', text: `/${T_TEAM_COMMAND}${invocation.rawInput}` }], source: { kind: 'user' } }));
92
+ return { kind: 'success', text: `T专家 小队已激活${parsed.profile === undefined ? '' : `(${parsed.profile})`} —— 队长会先组装团队。` };
93
+ },
94
+ }));
95
+ for (const profileName of Object.keys(getProfiles())) {
96
+ const commandName = profileCommandName(profileName);
97
+ if (commandName === undefined)
98
+ continue;
99
+ dispose.push(ctx.commands.register({
100
+ name: commandName,
101
+ description: `run a goal with the T Team ${profileName} profile`,
102
+ input: { hint: '<goal>' },
103
+ handler(invocation) {
104
+ const profile = profileForCommand(commandName, getProfiles());
105
+ if (profile === undefined)
106
+ return { kind: 'error', text: `T Team profile command "/${commandName}" is unavailable` };
107
+ invocation.agent.followup(createUserMessage({ content: [{ type: 'text', text: `/${commandName}${invocation.rawInput}` }], source: { kind: 'user' } }));
108
+ return { kind: 'success', text: `T专家 小队已激活(${profile})—— 队长会先组装团队。` };
109
+ },
110
+ }));
111
+ }
112
+ return () => {
113
+ for (const unregister of dispose.reverse())
114
+ unregister();
115
+ };
116
+ }, 't-team: slash commands');
117
+ }
118
+ export function installTTeamGestureBoundary(ctx, getProfiles = () => ({})) {
119
+ ctx.on('agent/pre-step', async ({ messages, signal }, next) => {
120
+ const decision = await next();
121
+ if (decision.kind === 'reject')
122
+ return decision;
123
+ let invocation;
124
+ try {
125
+ invocation = invokedTTeamInvocation(messages, getProfiles);
126
+ }
127
+ catch (error) {
128
+ return { kind: 'enter', messages: [...decision.messages, createUserMessage({ content: [{ type: 'text', text: `T专家 小队解析失败:${String(error)}` }], source: { kind: 't-team-command' } })] };
129
+ }
130
+ if (invocation === undefined)
131
+ return decision;
132
+ signal.throwIfAborted();
133
+ const profiles = getProfiles();
134
+ const matched = invocation.profile === undefined
135
+ ? undefined
136
+ : Object.entries(profiles).find(([key]) => key.trim() === invocation.profile);
137
+ const known = invocation.profile === undefined || matched !== undefined;
138
+ const text = !known
139
+ ? `T专家 小队「${invocation.profile}」不存在。可用小队:${Object.keys(profiles).join('、') || '(无)'}。不要创建团队。`
140
+ : buildActivationDirective(invocation.goal, invocation.profile, resolveProfileTaskPlanning(matched?.[1]));
141
+ return { kind: 'enter', messages: [...decision.messages, createUserMessage({ content: [{ type: 'text', text }], source: { kind: 't-team-command', ...invocation.goal === '' ? {} : { goal: invocation.goal }, ...invocation.profile === undefined ? {} : { profile: invocation.profile } } })] };
142
+ });
143
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * T Team session event types — pure types only, zero imports.
3
+ *
4
+ * This file intentionally imports nothing: both the host program (the
5
+ * emitter in `events.ts`) and the browser program (the Conversation Node
6
+ * definition) must be able to load these types and the `SessionEventMap`
7
+ * declaration merge without pulling in host-side `Context` augmentations
8
+ * (dsh-session's index declares `Context.sessions: SessionStore`, which
9
+ * collides with the browser runtime's `ISessions` under the same name).
10
+ * @module t-team/event-types
11
+ */
12
+ export {};
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Durable T Team session events and their emitter.
3
+ *
4
+ * Every team-state mutation appends one event to the captain's Session, so
5
+ * the web client's Conversation Node mechanism can fold the tree view from
6
+ * the session log deterministically (same mechanism as `tool-workflow`'s
7
+ * `tool-workflow/*` record events). Events append to the captain's session
8
+ * even when a member agent performed the mutation, so the captain's
9
+ * conversation stream stays the single authoritative monitor surface.
10
+ *
11
+ * Types and the `SessionEventMap` merge live in `event-types.ts` (zero
12
+ * imports) so the browser program can load them without host augmentations.
13
+ * @module t-team/events
14
+ */
15
+ import * as dshSession from '@deepseek-ai/dsh-session';
16
+ /** Event types already reported as unsupported, to avoid repetitive logs. */
17
+ const skippedEventTypes = new Set();
18
+ /**
19
+ * Append one T Team event to a Session, containing failures (a broken
20
+ * durable record must never break team tool execution).
21
+ * @param ctx - the plugin context (for logging).
22
+ * @param session - the session to record into (the captain's, normally).
23
+ * @param type - the event type.
24
+ * @param data - the event payload.
25
+ */
26
+ export function appendTeamEvent(ctx, session, type, data) {
27
+ // Out-of-repo events are not in the harness's generated vocabulary today.
28
+ // Mutating that ReadonlySet would make readability depend on which plugins
29
+ // happen to be loaded. Until Session.append exposes the official
30
+ // `ignorable: true` writer surface, omit these informational records unless
31
+ // the running harness already recognizes them. Disk state remains the
32
+ // authoritative source for the activity panel.
33
+ const known = dshSession.KNOWN_SESSION_EVENT_TYPES;
34
+ if (known?.has(type) !== true) {
35
+ if (!skippedEventTypes.has(type)) {
36
+ skippedEventTypes.add(type);
37
+ ctx.logger.debug(`t-team: session event "${type}" omitted because this harness does not recognize it`);
38
+ }
39
+ return;
40
+ }
41
+ try {
42
+ session.append(type, data);
43
+ }
44
+ catch (error) {
45
+ ctx.logger.warn(`t-team: session record failed after ${type}: ${String(error)}`);
46
+ }
47
+ }
48
+ /**
49
+ * Resolve the captain's live Session for event recording. The captain agent
50
+ * may be offline (its team outlives the session), in which case the caller's
51
+ * own session is used as the fallback record target.
52
+ * @param ctx - the plugin context (injects `agents`).
53
+ * @param captainSessionId - the captain's durable session id.
54
+ * @param fallback - the calling agent's session, used when the captain is not live.
55
+ * @returns the session to record into.
56
+ */
57
+ export function captainSessionOf(ctx, captainSessionId, fallback) {
58
+ const captain = ctx.agents.get(captainSessionId);
59
+ return captain?.session ?? fallback;
60
+ }