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.
- package/LICENSE +21 -0
- package/README.md +215 -0
- package/THIRD-PARTY-NOTICES +33 -0
- package/cordis.patch.yml +7 -0
- package/data/experts/academic/academic-anthropologist.md +125 -0
- package/data/experts/academic/academic-geographer.md +127 -0
- package/data/experts/academic/academic-historian.md +123 -0
- package/data/experts/academic/academic-narratologist.md +118 -0
- package/data/experts/academic/academic-psychologist.md +118 -0
- package/data/experts/academic/academic-statistician.md +144 -0
- package/data/experts/design/design-brand-guardian.md +322 -0
- package/data/experts/design/design-image-prompt-engineer.md +236 -0
- package/data/experts/design/design-inclusive-visuals-specialist.md +71 -0
- package/data/experts/design/design-persona-walkthrough.md +272 -0
- package/data/experts/design/design-ui-designer.md +383 -0
- package/data/experts/design/design-ui-finish-gate-reviewer.md +217 -0
- package/data/experts/design/design-ux-architect.md +469 -0
- package/data/experts/design/design-ux-researcher.md +329 -0
- package/data/experts/design/design-visual-storyteller.md +149 -0
- package/data/experts/design/design-whimsy-injector.md +438 -0
- package/data/experts/engineering/engineering-ai-data-remediation-engineer.md +211 -0
- package/data/experts/engineering/engineering-ai-engineer.md +146 -0
- package/data/experts/engineering/engineering-api-platform-engineer.md +162 -0
- package/data/experts/engineering/engineering-ats-validator-architect.md +383 -0
- package/data/experts/engineering/engineering-autonomous-optimization-architect.md +107 -0
- package/data/experts/engineering/engineering-backend-architect.md +236 -0
- package/data/experts/engineering/engineering-china-network-engineer.md +252 -0
- package/data/experts/engineering/engineering-cms-developer.md +536 -0
- package/data/experts/engineering/engineering-code-reviewer.md +76 -0
- package/data/experts/engineering/engineering-codebase-onboarding-engineer.md +173 -0
- package/data/experts/engineering/engineering-data-engineer.md +306 -0
- package/data/experts/engineering/engineering-data-visualization-engineer.md +151 -0
- package/data/experts/engineering/engineering-database-optimizer.md +176 -0
- package/data/experts/engineering/engineering-database-reliability-engineer.md +162 -0
- package/data/experts/engineering/engineering-desktop-app-engineer.md +204 -0
- package/data/experts/engineering/engineering-developer-tooling-engineer.md +153 -0
- package/data/experts/engineering/engineering-devops-automator.md +376 -0
- package/data/experts/engineering/engineering-drupal-performance.md +347 -0
- package/data/experts/engineering/engineering-drupal-shopping-cart.md +360 -0
- package/data/experts/engineering/engineering-email-intelligence-engineer.md +353 -0
- package/data/experts/engineering/engineering-embedded-firmware-engineer.md +173 -0
- package/data/experts/engineering/engineering-feishu-integration-developer.md +598 -0
- package/data/experts/engineering/engineering-filament-optimization-specialist.md +283 -0
- package/data/experts/engineering/engineering-finops-engineer.md +153 -0
- package/data/experts/engineering/engineering-frontend-developer.md +225 -0
- package/data/experts/engineering/engineering-gaussdb-expert.md +334 -0
- package/data/experts/engineering/engineering-git-workflow-master.md +84 -0
- package/data/experts/engineering/engineering-i18n-engineer.md +184 -0
- package/data/experts/engineering/engineering-identity-access-engineer.md +196 -0
- package/data/experts/engineering/engineering-incident-response-commander.md +444 -0
- package/data/experts/engineering/engineering-iot-fleet-engineer.md +148 -0
- package/data/experts/engineering/engineering-it-service-manager.md +561 -0
- package/data/experts/engineering/engineering-knowledge-graph-engineer.md +368 -0
- package/data/experts/engineering/engineering-llm-post-training-engineer.md +166 -0
- package/data/experts/engineering/engineering-minimal-change-engineer.md +207 -0
- package/data/experts/engineering/engineering-mobile-app-builder.md +493 -0
- package/data/experts/engineering/engineering-mobile-release-engineer.md +163 -0
- package/data/experts/engineering/engineering-multi-agent-systems-architect.md +600 -0
- package/data/experts/engineering/engineering-network-engineer.md +239 -0
- package/data/experts/engineering/engineering-orgscript-engineer.md +113 -0
- package/data/experts/engineering/engineering-payments-billing-engineer.md +194 -0
- package/data/experts/engineering/engineering-pdf-engine-architect.md +666 -0
- package/data/experts/engineering/engineering-platform-engineer.md +270 -0
- package/data/experts/engineering/engineering-privacy-engineer.md +152 -0
- package/data/experts/engineering/engineering-prompt-engineer.md +202 -0
- package/data/experts/engineering/engineering-rag-pipeline-engineer.md +437 -0
- package/data/experts/engineering/engineering-rapid-prototyper.md +462 -0
- package/data/experts/engineering/engineering-realtime-collaboration-engineer.md +187 -0
- package/data/experts/engineering/engineering-rust-refactoring-specialist.md +313 -0
- package/data/experts/engineering/engineering-search-relevance-engineer.md +237 -0
- package/data/experts/engineering/engineering-section-508-specialist.md +339 -0
- package/data/experts/engineering/engineering-senior-developer.md +176 -0
- package/data/experts/engineering/engineering-software-architect.md +112 -0
- package/data/experts/engineering/engineering-solidity-smart-contract-engineer.md +522 -0
- package/data/experts/engineering/engineering-sre.md +90 -0
- package/data/experts/engineering/engineering-technical-writer.md +393 -0
- package/data/experts/engineering/engineering-universal-document-compiler.md +344 -0
- package/data/experts/engineering/engineering-uswds-developer.md +340 -0
- package/data/experts/engineering/engineering-video-streaming-engineer.md +150 -0
- package/data/experts/engineering/engineering-voice-ai-integration-engineer.md +561 -0
- package/data/experts/engineering/engineering-webassembly-engineer.md +156 -0
- package/data/experts/engineering/engineering-wechat-mini-program-developer.md +350 -0
- package/data/experts/engineering/engineering-wordpress-performance.md +346 -0
- package/data/experts/engineering/engineering-wordpress-shopping-cart.md +346 -0
- package/data/experts/finance/finance-bookkeeper-controller.md +260 -0
- package/data/experts/finance/finance-financial-analyst.md +234 -0
- package/data/experts/finance/finance-fpa-analyst.md +263 -0
- package/data/experts/finance/finance-investment-researcher.md +272 -0
- package/data/experts/finance/finance-tax-strategist.md +239 -0
- package/data/experts/game-development/blender/blender-addon-engineer.md +234 -0
- package/data/experts/game-development/economy-designer.md +156 -0
- package/data/experts/game-development/game-audio-engineer.md +264 -0
- package/data/experts/game-development/game-designer.md +167 -0
- package/data/experts/game-development/godot/godot-gameplay-scripter.md +334 -0
- package/data/experts/game-development/godot/godot-multiplayer-engineer.md +297 -0
- package/data/experts/game-development/godot/godot-shader-developer.md +266 -0
- package/data/experts/game-development/level-designer.md +208 -0
- package/data/experts/game-development/narrative-designer.md +243 -0
- package/data/experts/game-development/roblox-studio/roblox-avatar-creator.md +297 -0
- package/data/experts/game-development/roblox-studio/roblox-experience-designer.md +305 -0
- package/data/experts/game-development/roblox-studio/roblox-systems-scripter.md +325 -0
- package/data/experts/game-development/technical-artist.md +229 -0
- package/data/experts/game-development/unity/unity-architect.md +271 -0
- package/data/experts/game-development/unity/unity-editor-tool-developer.md +310 -0
- package/data/experts/game-development/unity/unity-multiplayer-engineer.md +321 -0
- package/data/experts/game-development/unity/unity-shader-graph-artist.md +269 -0
- package/data/experts/game-development/unreal-engine/unreal-multiplayer-architect.md +313 -0
- package/data/experts/game-development/unreal-engine/unreal-systems-engineer.md +310 -0
- package/data/experts/game-development/unreal-engine/unreal-technical-artist.md +256 -0
- package/data/experts/game-development/unreal-engine/unreal-world-builder.md +273 -0
- package/data/experts/gis/gis-3d-scene-developer.md +111 -0
- package/data/experts/gis/gis-analyst.md +91 -0
- package/data/experts/gis/gis-bim-specialist.md +108 -0
- package/data/experts/gis/gis-cartography-designer.md +150 -0
- package/data/experts/gis/gis-drone-reality-mapping.md +120 -0
- package/data/experts/gis/gis-geoai-ml-engineer.md +105 -0
- package/data/experts/gis/gis-geoprocessing-specialist.md +97 -0
- package/data/experts/gis/gis-qa-engineer.md +133 -0
- package/data/experts/gis/gis-solution-engineer.md +101 -0
- package/data/experts/gis/gis-spatial-data-engineer.md +97 -0
- package/data/experts/gis/gis-spatial-data-scientist.md +111 -0
- package/data/experts/gis/gis-technical-consultant.md +86 -0
- package/data/experts/gis/gis-web-gis-developer.md +108 -0
- package/data/experts/healthcare/healthcare-clinical-evidence-agent.md +231 -0
- package/data/experts/healthcare/healthcare-innovation-strategist.md +433 -0
- package/data/experts/healthcare/healthcare-sovereign-health-systems-agent.md +312 -0
- package/data/experts/marketing/marketing-aeo-foundations.md +264 -0
- package/data/experts/marketing/marketing-agentic-search-optimizer.md +313 -0
- package/data/experts/marketing/marketing-ai-citation-strategist.md +172 -0
- package/data/experts/marketing/marketing-app-store-optimizer.md +321 -0
- package/data/experts/marketing/marketing-baidu-seo-specialist.md +226 -0
- package/data/experts/marketing/marketing-bilibili-content-strategist.md +199 -0
- package/data/experts/marketing/marketing-book-co-author.md +110 -0
- package/data/experts/marketing/marketing-carousel-growth-engine.md +199 -0
- package/data/experts/marketing/marketing-china-ecommerce-operator.md +283 -0
- package/data/experts/marketing/marketing-china-market-localization-strategist.md +283 -0
- package/data/experts/marketing/marketing-content-creator.md +54 -0
- package/data/experts/marketing/marketing-cross-border-ecommerce.md +259 -0
- package/data/experts/marketing/marketing-douyin-strategist.md +149 -0
- package/data/experts/marketing/marketing-email-strategist.md +249 -0
- package/data/experts/marketing/marketing-global-podcast-strategist.md +206 -0
- package/data/experts/marketing/marketing-growth-hacker.md +54 -0
- package/data/experts/marketing/marketing-instagram-curator.md +113 -0
- package/data/experts/marketing/marketing-kuaishou-strategist.md +223 -0
- package/data/experts/marketing/marketing-linkedin-content-creator.md +214 -0
- package/data/experts/marketing/marketing-livestream-commerce-coach.md +305 -0
- package/data/experts/marketing/marketing-multi-platform-publisher.md +217 -0
- package/data/experts/marketing/marketing-podcast-strategist.md +277 -0
- package/data/experts/marketing/marketing-pr-communications-manager.md +473 -0
- package/data/experts/marketing/marketing-private-domain-operator.md +308 -0
- package/data/experts/marketing/marketing-reddit-community-builder.md +123 -0
- package/data/experts/marketing/marketing-seo-specialist.md +370 -0
- package/data/experts/marketing/marketing-short-video-editing-coach.md +412 -0
- package/data/experts/marketing/marketing-social-media-strategist.md +125 -0
- package/data/experts/marketing/marketing-tiktok-strategist.md +125 -0
- package/data/experts/marketing/marketing-twitter-engager.md +126 -0
- package/data/experts/marketing/marketing-video-optimization-specialist.md +119 -0
- package/data/experts/marketing/marketing-wechat-official-account.md +145 -0
- package/data/experts/marketing/marketing-weibo-strategist.md +240 -0
- package/data/experts/marketing/marketing-x-twitter-intelligence-analyst.md +161 -0
- package/data/experts/marketing/marketing-xiaohongshu-specialist.md +138 -0
- package/data/experts/marketing/marketing-zhihu-strategist.md +162 -0
- package/data/experts/paid-media/paid-media-auditor.md +71 -0
- package/data/experts/paid-media/paid-media-creative-strategist.md +71 -0
- package/data/experts/paid-media/paid-media-paid-social-strategist.md +71 -0
- package/data/experts/paid-media/paid-media-ppc-strategist.md +71 -0
- package/data/experts/paid-media/paid-media-programmatic-buyer.md +71 -0
- package/data/experts/paid-media/paid-media-search-query-analyst.md +71 -0
- package/data/experts/paid-media/paid-media-tracking-specialist.md +71 -0
- package/data/experts/product/product-behavioral-nudge-engine.md +80 -0
- package/data/experts/product/product-feedback-synthesizer.md +119 -0
- package/data/experts/product/product-manager.md +469 -0
- package/data/experts/product/product-sprint-prioritizer.md +154 -0
- package/data/experts/product/product-trend-researcher.md +159 -0
- package/data/experts/project-management/project-management-experiment-tracker.md +198 -0
- package/data/experts/project-management/project-management-jira-workflow-steward.md +230 -0
- package/data/experts/project-management/project-management-meeting-notes-specialist.md +95 -0
- package/data/experts/project-management/project-management-project-shepherd.md +194 -0
- package/data/experts/project-management/project-management-studio-operations.md +200 -0
- package/data/experts/project-management/project-management-studio-producer.md +203 -0
- package/data/experts/project-management/project-manager-senior.md +135 -0
- package/data/experts/research/research-synthesist.md +136 -0
- package/data/experts/sales/sales-account-strategist.md +227 -0
- package/data/experts/sales/sales-coach.md +271 -0
- package/data/experts/sales/sales-deal-strategist.md +180 -0
- package/data/experts/sales/sales-discovery-coach.md +225 -0
- package/data/experts/sales/sales-engineer.md +182 -0
- package/data/experts/sales/sales-offer-lead-gen-strategist.md +257 -0
- package/data/experts/sales/sales-outbound-strategist.md +201 -0
- package/data/experts/sales/sales-pipeline-analyst.md +267 -0
- package/data/experts/sales/sales-proposal-strategist.md +217 -0
- package/data/experts/security/security-ai-generated-code-auditor.md +207 -0
- package/data/experts/security/security-appsec-engineer.md +491 -0
- package/data/experts/security/security-architect.md +304 -0
- package/data/experts/security/security-blockchain-security-auditor.md +463 -0
- package/data/experts/security/security-cloud-security-architect.md +523 -0
- package/data/experts/security/security-compliance-auditor.md +158 -0
- package/data/experts/security/security-incident-responder.md +437 -0
- package/data/experts/security/security-penetration-tester.md +399 -0
- package/data/experts/security/security-secrets-credential-engineer.md +176 -0
- package/data/experts/security/security-senior-secops.md +750 -0
- package/data/experts/security/security-threat-detection-engineer.md +534 -0
- package/data/experts/security/security-threat-intelligence-analyst.md +644 -0
- package/data/experts/spatial-computing/macos-spatial-metal-engineer.md +337 -0
- package/data/experts/spatial-computing/terminal-integration-specialist.md +70 -0
- package/data/experts/spatial-computing/visionos-spatial-engineer.md +54 -0
- package/data/experts/spatial-computing/xr-cockpit-interaction-specialist.md +32 -0
- package/data/experts/spatial-computing/xr-immersive-developer.md +32 -0
- package/data/experts/spatial-computing/xr-interface-architect.md +32 -0
- package/data/experts/specialized/accounts-payable-agent.md +185 -0
- package/data/experts/specialized/agentic-identity-trust.md +387 -0
- package/data/experts/specialized/agents-orchestrator.md +367 -0
- package/data/experts/specialized/automation-governance-architect.md +216 -0
- package/data/experts/specialized/business-strategist.md +488 -0
- package/data/experts/specialized/change-management-consultant.md +497 -0
- package/data/experts/specialized/chief-financial-officer.md +388 -0
- package/data/experts/specialized/corporate-training-designer.md +192 -0
- package/data/experts/specialized/customer-service.md +398 -0
- package/data/experts/specialized/customer-success-manager.md +460 -0
- package/data/experts/specialized/data-consolidation-agent.md +60 -0
- package/data/experts/specialized/data-privacy-officer.md +412 -0
- package/data/experts/specialized/esg-sustainability-officer.md +396 -0
- package/data/experts/specialized/government-digital-presales-consultant.md +363 -0
- package/data/experts/specialized/grant-writer.md +511 -0
- package/data/experts/specialized/healthcare-aging-parent-care-companion.md +414 -0
- package/data/experts/specialized/healthcare-customer-service.md +389 -0
- package/data/experts/specialized/healthcare-marketing-compliance.md +395 -0
- package/data/experts/specialized/hospitality-guest-services.md +603 -0
- package/data/experts/specialized/hr-onboarding.md +451 -0
- package/data/experts/specialized/identity-graph-operator.md +260 -0
- package/data/experts/specialized/language-translator.md +264 -0
- package/data/experts/specialized/legal-billing-time-tracking.md +569 -0
- package/data/experts/specialized/legal-client-intake.md +492 -0
- package/data/experts/specialized/legal-document-review.md +454 -0
- package/data/experts/specialized/loan-officer-assistant.md +555 -0
- package/data/experts/specialized/lsp-index-engineer.md +314 -0
- package/data/experts/specialized/ma-integration-manager.md +427 -0
- package/data/experts/specialized/medical-billing-coding-specialist.md +491 -0
- package/data/experts/specialized/operations-manager.md +399 -0
- package/data/experts/specialized/organizational-psychologist.md +391 -0
- package/data/experts/specialized/personal-growth-mentor.md +159 -0
- package/data/experts/specialized/real-estate-buyer-seller.md +596 -0
- package/data/experts/specialized/recruitment-specialist.md +509 -0
- package/data/experts/specialized/report-distribution-agent.md +65 -0
- package/data/experts/specialized/resume-tailor.md +230 -0
- package/data/experts/specialized/retail-customer-returns.md +566 -0
- package/data/experts/specialized/sales-data-extraction-agent.md +67 -0
- package/data/experts/specialized/sales-outreach.md +425 -0
- package/data/experts/specialized/specialized-chief-of-staff.md +279 -0
- package/data/experts/specialized/specialized-civil-engineer.md +356 -0
- package/data/experts/specialized/specialized-codebase-archaeologist.md +341 -0
- package/data/experts/specialized/specialized-cultural-intelligence-strategist.md +88 -0
- package/data/experts/specialized/specialized-developer-advocate.md +317 -0
- package/data/experts/specialized/specialized-document-generator.md +55 -0
- package/data/experts/specialized/specialized-fedramp-rmf-compliance.md +378 -0
- package/data/experts/specialized/specialized-focus-music-architect.md +172 -0
- package/data/experts/specialized/specialized-french-consulting-market.md +194 -0
- package/data/experts/specialized/specialized-korean-business-navigator.md +216 -0
- package/data/experts/specialized/specialized-master-plan-architect.md +157 -0
- package/data/experts/specialized/specialized-mcp-builder.md +248 -0
- package/data/experts/specialized/specialized-model-qa.md +488 -0
- package/data/experts/specialized/specialized-pricing-analyst.md +243 -0
- package/data/experts/specialized/specialized-salesforce-architect.md +182 -0
- package/data/experts/specialized/specialized-strategy-duel-agent.md +130 -0
- package/data/experts/specialized/specialized-workflow-architect.md +597 -0
- package/data/experts/specialized/study-abroad-advisor.md +282 -0
- package/data/experts/specialized/supply-chain-strategist.md +582 -0
- package/data/experts/specialized/zk-steward.md +211 -0
- package/data/experts/support/support-analytics-reporter.md +365 -0
- package/data/experts/support/support-executive-summary-generator.md +212 -0
- package/data/experts/support/support-finance-tracker.md +442 -0
- package/data/experts/support/support-infrastructure-maintainer.md +618 -0
- package/data/experts/support/support-legal-compliance-checker.md +588 -0
- package/data/experts/support/support-support-responder.md +585 -0
- package/data/experts/testing/testing-accessibility-auditor.md +316 -0
- package/data/experts/testing/testing-api-tester.md +306 -0
- package/data/experts/testing/testing-evidence-collector.md +210 -0
- package/data/experts/testing/testing-performance-benchmarker.md +268 -0
- package/data/experts/testing/testing-reality-checker.md +249 -0
- package/data/experts/testing/testing-test-automation-engineer.md +179 -0
- package/data/experts/testing/testing-test-results-analyzer.md +305 -0
- package/data/experts/testing/testing-tool-evaluator.md +394 -0
- package/data/experts/testing/testing-workflow-optimizer.md +450 -0
- package/data/source.json +27 -0
- package/data/t-team.config.json +998 -0
- package/data/team-profiles.py +365 -0
- package/data/teams.json +581 -0
- package/data/teams.resolved.json +1121 -0
- package/data/zh/COVERAGE.json +20 -0
- package/data/zh/academic/academic-anthropologist.md +124 -0
- package/data/zh/academic/academic-geographer.md +126 -0
- package/data/zh/academic/academic-historian.md +122 -0
- package/data/zh/academic/academic-narratologist.md +117 -0
- package/data/zh/academic/academic-psychologist.md +117 -0
- package/data/zh/academic/academic-statistician.md +40 -0
- package/data/zh/descriptions.json +281 -0
- package/data/zh/design/design-brand-guardian.md +321 -0
- package/data/zh/design/design-image-prompt-engineer.md +255 -0
- package/data/zh/design/design-inclusive-visuals-specialist.md +177 -0
- package/data/zh/design/design-persona-walkthrough.md +271 -0
- package/data/zh/design/design-ui-designer.md +382 -0
- package/data/zh/design/design-ui-finish-gate-reviewer.md +40 -0
- package/data/zh/design/design-ux-architect.md +482 -0
- package/data/zh/design/design-ux-researcher.md +328 -0
- package/data/zh/design/design-visual-storyteller.md +159 -0
- package/data/zh/design/design-whimsy-injector.md +453 -0
- package/data/zh/divisions.json +74 -0
- package/data/zh/engineering/engineering-ai-data-remediation-engineer.md +209 -0
- package/data/zh/engineering/engineering-ai-engineer.md +161 -0
- package/data/zh/engineering/engineering-api-platform-engineer.md +40 -0
- package/data/zh/engineering/engineering-ats-validator-architect.md +383 -0
- package/data/zh/engineering/engineering-autonomous-optimization-architect.md +115 -0
- package/data/zh/engineering/engineering-backend-architect.md +234 -0
- package/data/zh/engineering/engineering-china-network-engineer.md +252 -0
- package/data/zh/engineering/engineering-cms-developer.md +534 -0
- package/data/zh/engineering/engineering-code-reviewer.md +172 -0
- package/data/zh/engineering/engineering-codebase-onboarding-engineer.md +172 -0
- package/data/zh/engineering/engineering-data-engineer.md +324 -0
- package/data/zh/engineering/engineering-data-visualization-engineer.md +40 -0
- package/data/zh/engineering/engineering-database-optimizer.md +175 -0
- package/data/zh/engineering/engineering-database-reliability-engineer.md +40 -0
- package/data/zh/engineering/engineering-desktop-app-engineer.md +40 -0
- package/data/zh/engineering/engineering-developer-tooling-engineer.md +40 -0
- package/data/zh/engineering/engineering-devops-automator.md +375 -0
- package/data/zh/engineering/engineering-drupal-performance.md +40 -0
- package/data/zh/engineering/engineering-drupal-shopping-cart.md +359 -0
- package/data/zh/engineering/engineering-email-intelligence-engineer.md +349 -0
- package/data/zh/engineering/engineering-embedded-firmware-engineer.md +168 -0
- package/data/zh/engineering/engineering-feishu-integration-developer.md +597 -0
- package/data/zh/engineering/engineering-filament-optimization-specialist.md +283 -0
- package/data/zh/engineering/engineering-finops-engineer.md +40 -0
- package/data/zh/engineering/engineering-frontend-developer.md +224 -0
- package/data/zh/engineering/engineering-gaussdb-expert.md +40 -0
- package/data/zh/engineering/engineering-git-workflow-master.md +220 -0
- package/data/zh/engineering/engineering-i18n-engineer.md +40 -0
- package/data/zh/engineering/engineering-identity-access-engineer.md +40 -0
- package/data/zh/engineering/engineering-incident-response-commander.md +465 -0
- package/data/zh/engineering/engineering-iot-fleet-engineer.md +40 -0
- package/data/zh/engineering/engineering-it-service-manager.md +560 -0
- package/data/zh/engineering/engineering-knowledge-graph-engineer.md +40 -0
- package/data/zh/engineering/engineering-llm-post-training-engineer.md +40 -0
- package/data/zh/engineering/engineering-minimal-change-engineer.md +206 -0
- package/data/zh/engineering/engineering-mobile-app-builder.md +434 -0
- package/data/zh/engineering/engineering-mobile-release-engineer.md +40 -0
- package/data/zh/engineering/engineering-multi-agent-systems-architect.md +599 -0
- package/data/zh/engineering/engineering-network-engineer.md +40 -0
- package/data/zh/engineering/engineering-orgscript-engineer.md +112 -0
- package/data/zh/engineering/engineering-payments-billing-engineer.md +40 -0
- package/data/zh/engineering/engineering-pdf-engine-architect.md +666 -0
- package/data/zh/engineering/engineering-platform-engineer.md +271 -0
- package/data/zh/engineering/engineering-privacy-engineer.md +40 -0
- package/data/zh/engineering/engineering-prompt-engineer.md +203 -0
- package/data/zh/engineering/engineering-rag-pipeline-engineer.md +40 -0
- package/data/zh/engineering/engineering-rapid-prototyper.md +461 -0
- package/data/zh/engineering/engineering-realtime-collaboration-engineer.md +40 -0
- package/data/zh/engineering/engineering-rust-refactoring-specialist.md +40 -0
- package/data/zh/engineering/engineering-search-relevance-engineer.md +40 -0
- package/data/zh/engineering/engineering-section-508-specialist.md +40 -0
- package/data/zh/engineering/engineering-senior-developer.md +177 -0
- package/data/zh/engineering/engineering-software-architect.md +200 -0
- package/data/zh/engineering/engineering-solidity-smart-contract-engineer.md +541 -0
- package/data/zh/engineering/engineering-sre.md +233 -0
- package/data/zh/engineering/engineering-technical-writer.md +409 -0
- package/data/zh/engineering/engineering-universal-document-compiler.md +344 -0
- package/data/zh/engineering/engineering-uswds-developer.md +40 -0
- package/data/zh/engineering/engineering-video-streaming-engineer.md +40 -0
- package/data/zh/engineering/engineering-voice-ai-integration-engineer.md +560 -0
- package/data/zh/engineering/engineering-webassembly-engineer.md +40 -0
- package/data/zh/engineering/engineering-wechat-mini-program-developer.md +288 -0
- package/data/zh/engineering/engineering-wordpress-performance.md +40 -0
- package/data/zh/engineering/engineering-wordpress-shopping-cart.md +345 -0
- package/data/zh/finance/finance-bookkeeper-controller.md +271 -0
- package/data/zh/finance/finance-financial-analyst.md +244 -0
- package/data/zh/finance/finance-fpa-analyst.md +272 -0
- package/data/zh/finance/finance-investment-researcher.md +283 -0
- package/data/zh/finance/finance-tax-strategist.md +250 -0
- package/data/zh/game-development/blender/blender-addon-engineer.md +233 -0
- package/data/zh/game-development/economy-designer.md +40 -0
- package/data/zh/game-development/game-audio-engineer.md +265 -0
- package/data/zh/game-development/game-designer.md +168 -0
- package/data/zh/game-development/godot/godot-gameplay-scripter.md +335 -0
- package/data/zh/game-development/godot/godot-multiplayer-engineer.md +296 -0
- package/data/zh/game-development/godot/godot-shader-developer.md +267 -0
- package/data/zh/game-development/level-designer.md +209 -0
- package/data/zh/game-development/narrative-designer.md +244 -0
- package/data/zh/game-development/roblox-studio/roblox-avatar-creator.md +298 -0
- package/data/zh/game-development/roblox-studio/roblox-experience-designer.md +306 -0
- package/data/zh/game-development/roblox-studio/roblox-systems-scripter.md +325 -0
- package/data/zh/game-development/technical-artist.md +230 -0
- package/data/zh/game-development/unity/unity-architect.md +272 -0
- package/data/zh/game-development/unity/unity-editor-tool-developer.md +300 -0
- package/data/zh/game-development/unity/unity-multiplayer-engineer.md +238 -0
- package/data/zh/game-development/unity/unity-shader-graph-artist.md +270 -0
- package/data/zh/game-development/unreal-engine/unreal-multiplayer-architect.md +314 -0
- package/data/zh/game-development/unreal-engine/unreal-systems-engineer.md +311 -0
- package/data/zh/game-development/unreal-engine/unreal-technical-artist.md +256 -0
- package/data/zh/game-development/unreal-engine/unreal-world-builder.md +274 -0
- package/data/zh/gis/gis-3d-scene-developer.md +110 -0
- package/data/zh/gis/gis-analyst.md +90 -0
- package/data/zh/gis/gis-bim-specialist.md +107 -0
- package/data/zh/gis/gis-cartography-designer.md +149 -0
- package/data/zh/gis/gis-drone-reality-mapping.md +119 -0
- package/data/zh/gis/gis-geoai-ml-engineer.md +104 -0
- package/data/zh/gis/gis-geoprocessing-specialist.md +96 -0
- package/data/zh/gis/gis-qa-engineer.md +132 -0
- package/data/zh/gis/gis-solution-engineer.md +100 -0
- package/data/zh/gis/gis-spatial-data-engineer.md +96 -0
- package/data/zh/gis/gis-spatial-data-scientist.md +110 -0
- package/data/zh/gis/gis-technical-consultant.md +85 -0
- package/data/zh/gis/gis-web-gis-developer.md +107 -0
- package/data/zh/healthcare/healthcare-clinical-evidence-agent.md +40 -0
- package/data/zh/healthcare/healthcare-innovation-strategist.md +40 -0
- package/data/zh/healthcare/healthcare-sovereign-health-systems-agent.md +40 -0
- package/data/zh/manual-bodies/engineering/engineering-ats-validator-architect.md +383 -0
- package/data/zh/manual-bodies/engineering/engineering-china-network-engineer.md +252 -0
- package/data/zh/manual-bodies/engineering/engineering-pdf-engine-architect.md +666 -0
- package/data/zh/manual-bodies/engineering/engineering-platform-engineer.md +271 -0
- package/data/zh/manual-bodies/engineering/engineering-universal-document-compiler.md +344 -0
- package/data/zh/manual-bodies/specialized/specialized-focus-music-architect.md +172 -0
- package/data/zh/manual.json +22 -0
- package/data/zh/marketing/marketing-aeo-foundations.md +263 -0
- package/data/zh/marketing/marketing-agentic-search-optimizer.md +312 -0
- package/data/zh/marketing/marketing-ai-citation-strategist.md +169 -0
- package/data/zh/marketing/marketing-app-store-optimizer.md +319 -0
- package/data/zh/marketing/marketing-baidu-seo-specialist.md +220 -0
- package/data/zh/marketing/marketing-bilibili-content-strategist.md +40 -0
- package/data/zh/marketing/marketing-book-co-author.md +109 -0
- package/data/zh/marketing/marketing-carousel-growth-engine.md +215 -0
- package/data/zh/marketing/marketing-china-ecommerce-operator.md +277 -0
- package/data/zh/marketing/marketing-china-market-localization-strategist.md +282 -0
- package/data/zh/marketing/marketing-content-creator.md +145 -0
- package/data/zh/marketing/marketing-cross-border-ecommerce.md +260 -0
- package/data/zh/marketing/marketing-douyin-strategist.md +150 -0
- package/data/zh/marketing/marketing-email-strategist.md +248 -0
- package/data/zh/marketing/marketing-global-podcast-strategist.md +204 -0
- package/data/zh/marketing/marketing-growth-hacker.md +121 -0
- package/data/zh/marketing/marketing-instagram-curator.md +179 -0
- package/data/zh/marketing/marketing-kuaishou-strategist.md +182 -0
- package/data/zh/marketing/marketing-linkedin-content-creator.md +232 -0
- package/data/zh/marketing/marketing-livestream-commerce-coach.md +303 -0
- package/data/zh/marketing/marketing-multi-platform-publisher.md +216 -0
- package/data/zh/marketing/marketing-podcast-strategist.md +278 -0
- package/data/zh/marketing/marketing-pr-communications-manager.md +472 -0
- package/data/zh/marketing/marketing-private-domain-operator.md +309 -0
- package/data/zh/marketing/marketing-reddit-community-builder.md +127 -0
- package/data/zh/marketing/marketing-seo-specialist.md +298 -0
- package/data/zh/marketing/marketing-short-video-editing-coach.md +413 -0
- package/data/zh/marketing/marketing-social-media-strategist.md +118 -0
- package/data/zh/marketing/marketing-tiktok-strategist.md +124 -0
- package/data/zh/marketing/marketing-twitter-engager.md +132 -0
- package/data/zh/marketing/marketing-video-optimization-specialist.md +128 -0
- package/data/zh/marketing/marketing-wechat-official-account.md +158 -0
- package/data/zh/marketing/marketing-weibo-strategist.md +241 -0
- package/data/zh/marketing/marketing-x-twitter-intelligence-analyst.md +160 -0
- package/data/zh/marketing/marketing-xiaohongshu-specialist.md +151 -0
- package/data/zh/marketing/marketing-zhihu-strategist.md +175 -0
- package/data/zh/names.json +281 -0
- package/data/zh/paid-media/paid-media-auditor.md +170 -0
- package/data/zh/paid-media/paid-media-creative-strategist.md +173 -0
- package/data/zh/paid-media/paid-media-paid-social-strategist.md +180 -0
- package/data/zh/paid-media/paid-media-ppc-strategist.md +180 -0
- package/data/zh/paid-media/paid-media-programmatic-buyer.md +177 -0
- package/data/zh/paid-media/paid-media-search-query-analyst.md +182 -0
- package/data/zh/paid-media/paid-media-tracking-specialist.md +199 -0
- package/data/zh/product/product-behavioral-nudge-engine.md +246 -0
- package/data/zh/product/product-feedback-synthesizer.md +175 -0
- package/data/zh/product/product-manager.md +474 -0
- package/data/zh/product/product-sprint-prioritizer.md +133 -0
- package/data/zh/product/product-trend-researcher.md +143 -0
- package/data/zh/project-management/project-management-experiment-tracker.md +206 -0
- package/data/zh/project-management/project-management-jira-workflow-steward.md +249 -0
- package/data/zh/project-management/project-management-meeting-notes-specialist.md +94 -0
- package/data/zh/project-management/project-management-project-shepherd.md +202 -0
- package/data/zh/project-management/project-management-studio-operations.md +208 -0
- package/data/zh/project-management/project-management-studio-producer.md +211 -0
- package/data/zh/project-management/project-manager-senior.md +135 -0
- package/data/zh/research/research-synthesist.md +40 -0
- package/data/zh/sales/sales-account-strategist.md +243 -0
- package/data/zh/sales/sales-coach.md +291 -0
- package/data/zh/sales/sales-deal-strategist.md +204 -0
- package/data/zh/sales/sales-discovery-coach.md +230 -0
- package/data/zh/sales/sales-engineer.md +200 -0
- package/data/zh/sales/sales-offer-lead-gen-strategist.md +256 -0
- package/data/zh/sales/sales-outbound-strategist.md +208 -0
- package/data/zh/sales/sales-pipeline-analyst.md +284 -0
- package/data/zh/sales/sales-proposal-strategist.md +233 -0
- package/data/zh/security/security-ai-generated-code-auditor.md +40 -0
- package/data/zh/security/security-appsec-engineer.md +490 -0
- package/data/zh/security/security-architect.md +303 -0
- package/data/zh/security/security-blockchain-security-auditor.md +462 -0
- package/data/zh/security/security-cloud-security-architect.md +522 -0
- package/data/zh/security/security-compliance-auditor.md +157 -0
- package/data/zh/security/security-incident-responder.md +436 -0
- package/data/zh/security/security-penetration-tester.md +398 -0
- package/data/zh/security/security-secrets-credential-engineer.md +40 -0
- package/data/zh/security/security-senior-secops.md +751 -0
- package/data/zh/security/security-threat-detection-engineer.md +533 -0
- package/data/zh/security/security-threat-intelligence-analyst.md +643 -0
- package/data/zh/spatial-computing/macos-spatial-metal-engineer.md +337 -0
- package/data/zh/spatial-computing/terminal-integration-specialist.md +236 -0
- package/data/zh/spatial-computing/visionos-spatial-engineer.md +282 -0
- package/data/zh/spatial-computing/xr-cockpit-interaction-specialist.md +220 -0
- package/data/zh/spatial-computing/xr-immersive-developer.md +229 -0
- package/data/zh/spatial-computing/xr-interface-architect.md +253 -0
- package/data/zh/specialized/accounts-payable-agent.md +212 -0
- package/data/zh/specialized/agentic-identity-trust.md +388 -0
- package/data/zh/specialized/agents-orchestrator.md +366 -0
- package/data/zh/specialized/automation-governance-architect.md +215 -0
- package/data/zh/specialized/business-strategist.md +487 -0
- package/data/zh/specialized/change-management-consultant.md +495 -0
- package/data/zh/specialized/chief-financial-officer.md +390 -0
- package/data/zh/specialized/corporate-training-designer.md +191 -0
- package/data/zh/specialized/customer-service.md +40 -0
- package/data/zh/specialized/customer-success-manager.md +458 -0
- package/data/zh/specialized/data-consolidation-agent.md +327 -0
- package/data/zh/specialized/data-privacy-officer.md +411 -0
- package/data/zh/specialized/esg-sustainability-officer.md +395 -0
- package/data/zh/specialized/government-digital-presales-consultant.md +362 -0
- package/data/zh/specialized/grant-writer.md +510 -0
- package/data/zh/specialized/healthcare-aging-parent-care-companion.md +40 -0
- package/data/zh/specialized/healthcare-customer-service.md +388 -0
- package/data/zh/specialized/healthcare-marketing-compliance.md +394 -0
- package/data/zh/specialized/hospitality-guest-services.md +597 -0
- package/data/zh/specialized/hr-onboarding.md +450 -0
- package/data/zh/specialized/identity-graph-operator.md +270 -0
- package/data/zh/specialized/language-translator.md +275 -0
- package/data/zh/specialized/legal-billing-time-tracking.md +566 -0
- package/data/zh/specialized/legal-client-intake.md +487 -0
- package/data/zh/specialized/legal-document-review.md +452 -0
- package/data/zh/specialized/loan-officer-assistant.md +549 -0
- package/data/zh/specialized/lsp-index-engineer.md +334 -0
- package/data/zh/specialized/ma-integration-manager.md +426 -0
- package/data/zh/specialized/medical-billing-coding-specialist.md +489 -0
- package/data/zh/specialized/operations-manager.md +398 -0
- package/data/zh/specialized/organizational-psychologist.md +390 -0
- package/data/zh/specialized/personal-growth-mentor.md +158 -0
- package/data/zh/specialized/real-estate-buyer-seller.md +594 -0
- package/data/zh/specialized/recruitment-specialist.md +49 -0
- package/data/zh/specialized/report-distribution-agent.md +354 -0
- package/data/zh/specialized/resume-tailor.md +40 -0
- package/data/zh/specialized/retail-customer-returns.md +564 -0
- package/data/zh/specialized/sales-data-extraction-agent.md +159 -0
- package/data/zh/specialized/sales-outreach.md +40 -0
- package/data/zh/specialized/specialized-chief-of-staff.md +40 -0
- package/data/zh/specialized/specialized-civil-engineer.md +355 -0
- package/data/zh/specialized/specialized-codebase-archaeologist.md +40 -0
- package/data/zh/specialized/specialized-cultural-intelligence-strategist.md +168 -0
- package/data/zh/specialized/specialized-developer-advocate.md +334 -0
- package/data/zh/specialized/specialized-document-generator.md +346 -0
- package/data/zh/specialized/specialized-fedramp-rmf-compliance.md +40 -0
- package/data/zh/specialized/specialized-focus-music-architect.md +172 -0
- package/data/zh/specialized/specialized-french-consulting-market.md +46 -0
- package/data/zh/specialized/specialized-korean-business-navigator.md +46 -0
- package/data/zh/specialized/specialized-master-plan-architect.md +40 -0
- package/data/zh/specialized/specialized-mcp-builder.md +351 -0
- package/data/zh/specialized/specialized-model-qa.md +507 -0
- package/data/zh/specialized/specialized-pricing-analyst.md +242 -0
- package/data/zh/specialized/specialized-salesforce-architect.md +179 -0
- package/data/zh/specialized/specialized-strategy-duel-agent.md +129 -0
- package/data/zh/specialized/specialized-workflow-architect.md +596 -0
- package/data/zh/specialized/study-abroad-advisor.md +281 -0
- package/data/zh/specialized/supply-chain-strategist.md +581 -0
- package/data/zh/specialized/zk-steward.md +228 -0
- package/data/zh/support/support-analytics-reporter.md +364 -0
- package/data/zh/support/support-executive-summary-generator.md +217 -0
- package/data/zh/support/support-finance-tracker.md +447 -0
- package/data/zh/support/support-infrastructure-maintainer.md +623 -0
- package/data/zh/support/support-legal-compliance-checker.md +587 -0
- package/data/zh/support/support-support-responder.md +584 -0
- package/data/zh/testing/testing-accessibility-auditor.md +329 -0
- package/data/zh/testing/testing-api-tester.md +305 -0
- package/data/zh/testing/testing-evidence-collector.md +153 -0
- package/data/zh/testing/testing-performance-benchmarker.md +196 -0
- package/data/zh/testing/testing-reality-checker.md +235 -0
- package/data/zh/testing/testing-test-automation-engineer.md +40 -0
- package/data/zh/testing/testing-test-results-analyzer.md +313 -0
- package/data/zh/testing/testing-tool-evaluator.md +402 -0
- package/data/zh/testing/testing-workflow-optimizer.md +458 -0
- package/lib/assets/t-team/action-celebrating-v2.png +0 -0
- package/lib/assets/t-team/action-reporting-v2.png +0 -0
- package/lib/assets/t-team/action-sending-v2.png +0 -0
- package/lib/assets/t-team/action-sleeping-v2.png +0 -0
- package/lib/assets/t-team/action-thinking-v2.png +0 -0
- package/lib/assets/t-team/action-working-v2.png +0 -0
- package/lib/assets/t-team/member-data-v2.png +0 -0
- package/lib/assets/t-team/member-designer-v2.png +0 -0
- package/lib/assets/t-team/member-docs-v2.png +0 -0
- package/lib/assets/t-team/member-engineer-v2.png +0 -0
- package/lib/assets/t-team/member-operator-v2.png +0 -0
- package/lib/assets/t-team/member-qa-v2.png +0 -0
- package/lib/assets/t-team/member-researcher-v2.png +0 -0
- package/lib/assets/t-team/member-security-v2.png +0 -0
- package/lib/assets/t-team/team-lead-v2.png +0 -0
- package/lib/bootstrap.js +85 -0
- package/lib/catalog.js +376 -0
- package/lib/client.js +21034 -0
- package/lib/command.js +228 -0
- package/lib/i18n.js +136 -0
- package/lib/index.js +686 -0
- package/lib/plan-check.js +171 -0
- package/lib/remote.js +353 -0
- package/lib/squads.js +231 -0
- package/lib/teams/capabilities.js +106 -0
- package/lib/teams/command.js +143 -0
- package/lib/teams/event-types.js +12 -0
- package/lib/teams/events.js +60 -0
- package/lib/teams/harness-compat.js +179 -0
- package/lib/teams/index.js +441 -0
- package/lib/teams/members.js +602 -0
- package/lib/teams/profiles.js +572 -0
- package/lib/teams/quality-gates.js +822 -0
- package/lib/teams/scheduler.js +434 -0
- package/lib/teams/snapshot.js +181 -0
- package/lib/teams/state.js +925 -0
- package/lib/teams/tool-names.js +11 -0
- package/lib/teams/tools.js +2279 -0
- package/lib/teams/types.js +22 -0
- package/lib/teams/web-routes.js +86 -0
- package/package.json +191 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { SubagentError } from '@deepseek-ai/dsh-subagent';
|
|
2
|
+
/**
|
|
3
|
+
* Exact protocol exported by dsh-subagent/internal in Alpha.5 and rc.1.
|
|
4
|
+
* That subpath does not exist in Alpha.2, so importing it statically prevents
|
|
5
|
+
* the plugin from loading there. This small adapter uses the same process-
|
|
6
|
+
* stable symbol and call signature as upstream queueHostSubagentPrompt.
|
|
7
|
+
* Source: packages/subagent/subagent/src/internal.ts at dsh-v0.1.2-rc.1.
|
|
8
|
+
*/
|
|
9
|
+
const hostPromptQueue = Symbol.for('dsh.subagent.queuePrompt');
|
|
10
|
+
// 0.1.5 keeps queueHostSubagentPrompt but replaces its symbol with this
|
|
11
|
+
// delivery-mode-aware implementation (packages/subagent/subagent/src/internal.ts).
|
|
12
|
+
const hostPromptDeliver = Symbol.for('dsh.subagent.deliverPrompt');
|
|
13
|
+
function boundary(runtime) {
|
|
14
|
+
return runtime;
|
|
15
|
+
}
|
|
16
|
+
function unsupported(detail) {
|
|
17
|
+
throw new Error(`t-team: unsupported Harness subagent contract (${detail}); use an explicitly tested Harness version and a coherent dependency installation`);
|
|
18
|
+
}
|
|
19
|
+
/** Read child-owned history, excluding any descriptor inherited from a parent. */
|
|
20
|
+
export function sessionOwnEvents(session) {
|
|
21
|
+
const current = session;
|
|
22
|
+
if (typeof current.ownEvents === 'function')
|
|
23
|
+
return current.ownEvents.call(session);
|
|
24
|
+
const legacy = session;
|
|
25
|
+
if (!Array.isArray(legacy.events))
|
|
26
|
+
return unsupported('missing ownEvents/legacy session log');
|
|
27
|
+
return legacy.events.slice(legacy.header.seedLength ?? 0);
|
|
28
|
+
}
|
|
29
|
+
/** Install before the first request, including cold resume, with HMR cleanup. */
|
|
30
|
+
export function installContinuableMemberSetup(ctx, setup) {
|
|
31
|
+
const runtime = boundary(ctx.subagents);
|
|
32
|
+
if (typeof runtime.registerContinuableSetup === 'function') {
|
|
33
|
+
// Upstream owns this registration with this.ctx.effect. Cordis resolves
|
|
34
|
+
// that ctx to the accessing plugin, so its disposal revokes installations
|
|
35
|
+
// even while the subagents service and child Agents remain live.
|
|
36
|
+
runtime.registerContinuableSetup.call(ctx.subagents, (childCtx) => {
|
|
37
|
+
if (childCtx.agent === undefined)
|
|
38
|
+
return unsupported('legacy setup lacks child Agent');
|
|
39
|
+
return setup(childCtx, childCtx.agent);
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if ((typeof runtime[hostPromptQueue] !== 'function' && typeof runtime[hostPromptDeliver] !== 'function') || typeof runtime.sendMessage !== 'function') {
|
|
44
|
+
return unsupported('missing continuable setup and modern host queue');
|
|
45
|
+
}
|
|
46
|
+
const installed = new WeakSet();
|
|
47
|
+
const active = new Set();
|
|
48
|
+
ctx.effect(() => {
|
|
49
|
+
const stop = ctx.on('agent/session-start', ({ agent }) => {
|
|
50
|
+
if (installed.has(agent))
|
|
51
|
+
return;
|
|
52
|
+
// Deliberately synchronous: awaiting here loses the first-request race.
|
|
53
|
+
let teardown;
|
|
54
|
+
try {
|
|
55
|
+
teardown = setup(agent.ctx, agent);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
// session-start is a notification: Harness logs a thrown listener and
|
|
59
|
+
// still admits the first prompt. Reject request assembly explicitly so
|
|
60
|
+
// a malformed saved route cannot silently execute on a default model.
|
|
61
|
+
const failure = new Error(`t-team: member initialization failed: ${String(error)}`, { cause: error });
|
|
62
|
+
ctx.logger.warn(failure.message);
|
|
63
|
+
teardown = agent.ctx.on('agent/request', () => { throw failure; });
|
|
64
|
+
}
|
|
65
|
+
installed.add(agent);
|
|
66
|
+
let disposed = false;
|
|
67
|
+
const dispose = () => {
|
|
68
|
+
if (disposed)
|
|
69
|
+
return;
|
|
70
|
+
disposed = true;
|
|
71
|
+
active.delete(dispose);
|
|
72
|
+
installed.delete(agent);
|
|
73
|
+
teardown();
|
|
74
|
+
};
|
|
75
|
+
active.add(dispose);
|
|
76
|
+
// Listeners contributed to agent.ctx already follow its lifetime. Also
|
|
77
|
+
// release our bookkeeping and remove them if this plugin is reloaded.
|
|
78
|
+
try {
|
|
79
|
+
agent.ctx.effect(() => dispose, 't-team: child compatibility setup');
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
dispose();
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return () => {
|
|
87
|
+
stop();
|
|
88
|
+
for (const dispose of [...active])
|
|
89
|
+
dispose();
|
|
90
|
+
};
|
|
91
|
+
}, 't-team: member lifecycle compatibility');
|
|
92
|
+
}
|
|
93
|
+
/** Queue a distinct host-authored turn; never substitute model-message steer. */
|
|
94
|
+
export async function queueMemberPrompt(runtime, parent, childId, content, signal) {
|
|
95
|
+
const host = boundary(runtime);
|
|
96
|
+
const source = { kind: 'plugin', plugin: 't-team' };
|
|
97
|
+
if (typeof host.followup === 'function') {
|
|
98
|
+
return host.followup.call(runtime, parent, childId, content, { source, signal });
|
|
99
|
+
}
|
|
100
|
+
const deliver = host[hostPromptDeliver];
|
|
101
|
+
if (typeof deliver === 'function')
|
|
102
|
+
return deliver.call(runtime, parent, childId, content, source, signal, 'queue');
|
|
103
|
+
const queue = host[hostPromptQueue];
|
|
104
|
+
if (typeof queue !== 'function')
|
|
105
|
+
return unsupported('missing host FIFO delivery');
|
|
106
|
+
return queue.call(runtime, parent, childId, content, source, signal);
|
|
107
|
+
}
|
|
108
|
+
/** Guard all resumable delivery paths, preserving the native service receiver. */
|
|
109
|
+
export function guardSubagentDelivery(ctx, isRetired) {
|
|
110
|
+
const runtime = ctx.subagents;
|
|
111
|
+
const host = boundary(runtime);
|
|
112
|
+
const legacy = host.followup;
|
|
113
|
+
const queue = host[hostPromptQueue];
|
|
114
|
+
const deliver = host[hostPromptDeliver];
|
|
115
|
+
const send = host.sendMessage;
|
|
116
|
+
if (typeof legacy !== 'function' && ((typeof queue !== 'function' && typeof deliver !== 'function') || typeof send !== 'function')) {
|
|
117
|
+
return unsupported('cannot install complete retired-member guard');
|
|
118
|
+
}
|
|
119
|
+
ctx.effect(() => {
|
|
120
|
+
const descriptors = new Map([
|
|
121
|
+
['followup', Object.getOwnPropertyDescriptor(host, 'followup')],
|
|
122
|
+
[hostPromptQueue, Object.getOwnPropertyDescriptor(host, hostPromptQueue)],
|
|
123
|
+
[hostPromptDeliver, Object.getOwnPropertyDescriptor(host, hostPromptDeliver)],
|
|
124
|
+
['sendMessage', Object.getOwnPropertyDescriptor(host, 'sendMessage')],
|
|
125
|
+
]);
|
|
126
|
+
let active = true;
|
|
127
|
+
const check = async (sender, targetId) => {
|
|
128
|
+
if (active && await isRetired(sender, targetId)) {
|
|
129
|
+
throw new SubagentError(`T Team member "${targetId}" was retired and cannot be resumed`, 'NOT_RESUMABLE');
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const guardedLegacy = async (parent, childId, content, options) => {
|
|
133
|
+
await check(parent, childId);
|
|
134
|
+
return legacy.call(runtime, parent, childId, content, options);
|
|
135
|
+
};
|
|
136
|
+
const guardedQueue = async (parent, childId, content, source, signal) => {
|
|
137
|
+
await check(parent, childId);
|
|
138
|
+
return queue.call(runtime, parent, childId, content, source, signal);
|
|
139
|
+
};
|
|
140
|
+
const guardedSend = async (sender, targetId, content, options) => {
|
|
141
|
+
await check(sender, targetId);
|
|
142
|
+
return send.call(runtime, sender, targetId, content, options);
|
|
143
|
+
};
|
|
144
|
+
const guardedDeliver = async (parent, childId, content, source, signal, delivery) => {
|
|
145
|
+
await check(parent, childId);
|
|
146
|
+
return deliver.call(runtime, parent, childId, content, source, signal, delivery);
|
|
147
|
+
};
|
|
148
|
+
if (typeof legacy === 'function')
|
|
149
|
+
host.followup = guardedLegacy;
|
|
150
|
+
if (typeof queue === 'function')
|
|
151
|
+
host[hostPromptQueue] = guardedQueue;
|
|
152
|
+
if (typeof deliver === 'function')
|
|
153
|
+
host[hostPromptDeliver] = guardedDeliver;
|
|
154
|
+
if (typeof send === 'function')
|
|
155
|
+
host.sendMessage = guardedSend;
|
|
156
|
+
// Cordis wraps method reads in fresh Proxies. Compare the actual own
|
|
157
|
+
// descriptor to restore only our contribution, including prototype methods.
|
|
158
|
+
const restore = (key, installed) => {
|
|
159
|
+
if (Object.getOwnPropertyDescriptor(host, key)?.value !== installed)
|
|
160
|
+
return;
|
|
161
|
+
const original = descriptors.get(key);
|
|
162
|
+
if (original === undefined)
|
|
163
|
+
Reflect.deleteProperty(host, key);
|
|
164
|
+
else
|
|
165
|
+
Object.defineProperty(host, key, original);
|
|
166
|
+
};
|
|
167
|
+
return () => {
|
|
168
|
+
active = false;
|
|
169
|
+
if (typeof legacy === 'function')
|
|
170
|
+
restore('followup', guardedLegacy);
|
|
171
|
+
if (typeof queue === 'function')
|
|
172
|
+
restore(hostPromptQueue, guardedQueue);
|
|
173
|
+
if (typeof deliver === 'function')
|
|
174
|
+
restore(hostPromptDeliver, guardedDeliver);
|
|
175
|
+
if (typeof send === 'function')
|
|
176
|
+
restore('sendMessage', guardedSend);
|
|
177
|
+
};
|
|
178
|
+
}, 't-team: retired member guard');
|
|
179
|
+
}
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T Team for DeepSeek Harness.
|
|
3
|
+
*
|
|
4
|
+
* A host-plane plugin that registers the `t_team_*` tools and one usage
|
|
5
|
+
* agent-scoped usage section. Each session keeps a stable tool set and core
|
|
6
|
+
* instructions. Existing business tools cover the complete team lifecycle.
|
|
7
|
+
* After installation any session can
|
|
8
|
+
* run multi-agent teamwork through natural language (e.g. "use T Team to research X"):
|
|
9
|
+
* the model creates a team (it becomes the captain), spawns members as
|
|
10
|
+
* durable continuable subagents, breaks the goal into tasks with
|
|
11
|
+
* dependencies, wakes members with messages, relays reports, and collects
|
|
12
|
+
* results.
|
|
13
|
+
*
|
|
14
|
+
* Installation (bundle): `dsh plugin --profile <name> add dsh-plugin-t-expert`
|
|
15
|
+
* (or a local path). The bundle patch mounts this plugin row into the host
|
|
16
|
+
* composition; the tools register into the shared `tools` registry and the
|
|
17
|
+
* usage section into the global system prompt, so the plugin needs no realm.
|
|
18
|
+
*
|
|
19
|
+
* @module t-team
|
|
20
|
+
*/
|
|
21
|
+
import z from '@deepseek-ai/schemastery';
|
|
22
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
23
|
+
import { haltTeamWork, stagedPlanApprovedContext, registerTTeamTools, } from "./tools.js";
|
|
24
|
+
import { installTTeamGestureBoundary, registerTTeamCommand } from "./command.js";
|
|
25
|
+
import { readFile } from 'node:fs/promises';
|
|
26
|
+
import { join } from 'node:path';
|
|
27
|
+
import { fileURLToPath } from 'node:url';
|
|
28
|
+
import { collectArchivedTeamsActivity, collectTeamsActivity } from "./snapshot.js";
|
|
29
|
+
import { findTeamByCaptain } from "./state.js";
|
|
30
|
+
import { formatProfilesForPrompt } from "./profiles.js";
|
|
31
|
+
import { installTeamCapabilities } from "./capabilities.js";
|
|
32
|
+
import { TEAM_TOOL_NAMES } from "./tool-names.js";
|
|
33
|
+
import { authenticatedWebRoutes, readJsonRequest, RequestBodyError } from "./web-routes.js";
|
|
34
|
+
/** Web-server service key candidates, newest first. */
|
|
35
|
+
const WEB_SERVER_KEYS = ['webServer', 'httpServer'];
|
|
36
|
+
/** Workspace registry service key candidates, newest first. */
|
|
37
|
+
const WORKSPACE_KEYS = ['workspaceRegistry', 'workspace'];
|
|
38
|
+
export const name = 't-team';
|
|
39
|
+
export const inject = ['tools', 'llm', 'subagents', 'systemPrompt', 'agents'];
|
|
40
|
+
// `z.object()` has an implicit `{}` default in Schemastery. Fallback routes
|
|
41
|
+
// are optional, so model absence explicitly; otherwise a missing route is
|
|
42
|
+
// validated as an empty object and fails on the required provider/model keys.
|
|
43
|
+
const fallbackRouteConfig = z.union([
|
|
44
|
+
z.object({ provider: z.string().required(), model: z.string().required() }),
|
|
45
|
+
z.const(undefined),
|
|
46
|
+
]);
|
|
47
|
+
export const Config = z.object({
|
|
48
|
+
stateDir: z.string().default('.t-team'),
|
|
49
|
+
memberProvider: z.string().default('spawn'),
|
|
50
|
+
memberModel: z.string(),
|
|
51
|
+
executionPrompt: z.string(),
|
|
52
|
+
fallback: fallbackRouteConfig,
|
|
53
|
+
profiles: z.dict(z.object({
|
|
54
|
+
description: z.string(),
|
|
55
|
+
protocol: z.string(),
|
|
56
|
+
executionPrompt: z.string(),
|
|
57
|
+
fallback: fallbackRouteConfig,
|
|
58
|
+
members: z.array(z.object({
|
|
59
|
+
name: z.string().required(),
|
|
60
|
+
role: z.string(),
|
|
61
|
+
provider: z.string(),
|
|
62
|
+
model: z.string(),
|
|
63
|
+
reasoning_effort: z.string(),
|
|
64
|
+
executionPrompt: z.string(),
|
|
65
|
+
fallback: fallbackRouteConfig,
|
|
66
|
+
})).min(1).required(),
|
|
67
|
+
taskPlanning: z.union([z.const('captain'), z.const('seed')]),
|
|
68
|
+
reviewPolicy: z.object({
|
|
69
|
+
requirementsMinRounds: z.natural().min(1),
|
|
70
|
+
requirementsMaxRounds: z.natural().min(1),
|
|
71
|
+
codeMaxRounds: z.natural().min(1),
|
|
72
|
+
maxRepairAttempts: z.natural().min(1),
|
|
73
|
+
requiredReviewers: z.array(z.string()),
|
|
74
|
+
}),
|
|
75
|
+
tasks: z.array(z.object({
|
|
76
|
+
id: z.string().required(),
|
|
77
|
+
subject: z.string().required(),
|
|
78
|
+
description: z.string(),
|
|
79
|
+
assignee: z.string(),
|
|
80
|
+
dependencies: z.array(z.string()),
|
|
81
|
+
})),
|
|
82
|
+
})).default({}),
|
|
83
|
+
memberMaxDepth: z.natural().default(1),
|
|
84
|
+
maxMembers: z.natural().min(1).default(8),
|
|
85
|
+
promptSectionOrder: z.natural().default(117),
|
|
86
|
+
slashCommand: z.boolean().default(true),
|
|
87
|
+
});
|
|
88
|
+
/** The model-facing usage policy: when and how to drive T Team. */
|
|
89
|
+
export function usageSectionText(toolNames, profilesText = '') {
|
|
90
|
+
return `T Team captain protocol:
|
|
91
|
+
1. Inspect current team state when needed, using t_team_status. Continue existing work without duplicating its roster/tasks. Create only when no current team exists, with the user's goal as description and approval="required"; automatic approval requires an explicit request to run immediately. Staged plans never spawn or schedule work.
|
|
92
|
+
2. Add each needed role once; members inherit your model route unless another is requested/needed. A requested profile goes to create({profile}); it supplies its roster. Seed profiles also supply tasks; captain-planning profiles require your DAG. Do not duplicate either.
|
|
93
|
+
3. Build the complete smallest useful DAG while staged. Every task needs a subject; dependencies represent prerequisites. Give every required contributor a task or explicit message. Present the plan and end your turn for review; never approve in that planning turn. Approve only after a later explicit user approval or the Web action.
|
|
94
|
+
4. Respect Web approve/return/discard control messages. On return, ask what to change before editing; after the answer, use one atomic t_team_edit_plan batch (edit downstream references before removals), summarize and await review again. Never inspect or edit .t-team state files or plugin source code to revise plans. Discard does not authorize a replacement.
|
|
95
|
+
5. The scheduler dispatches ready tasks after approval. Delegate; do not duplicate slow work or send messages merely to start a stage. Handle reports/user work, then yield when waiting is all that remains: reports wake you automatically. Use status after a delivery or user request, never busy-poll or wait for unassigned members.
|
|
96
|
+
6. Tasks carry attempt_id capabilities. Use the current attempt_id; stale means ownership changed. Pause members only on explicit request; later guidance via send_message continues that same attempt. Retry, transfer or take over through reassign_task first; it revokes the old attempt and waits for quiescence. Prefer a member. Captain implementation/review takeover requires a user request. Every takeover is one ready task at a time, finished in this turn; never yield with captain-owned work open.
|
|
97
|
+
7. Quality kinds (requirements, implementation, verification, review, repair, integration) require objective + acceptance; implementation/repair also require inScope + verify. Derive paths/commands from the workspace/profile, never assume src/ or pnpm test. Review/requirements complete only with verdict=pass; needs_revision/reject fail with findings. Never approve your own implementation or ask for a deliberate failure.
|
|
98
|
+
8. When full quality mode is requested: requirements → implementation → verification → review → integration. Plan the entire DAG while staged, including implementation before requirements finishes and integration depending on review round 1. Failed review automatically adds repair + next review and rewires pending downstream gates. Do not recreate this loop, omit integration or depend on a failed task. Review acceptance judges the latest implementation. Do not put smoke-test scripts into task instructions.
|
|
99
|
+
9. Halted means the user stopped work (including the captain turn). Resume only on a later explicit user request with a reason, via t_team_resume or create_task({resume:true,resumeReason}); creating tasks alone never resumes. Escalated means the review loop hit its limit, not a halt. Deployment requires explicit user confirmation.
|
|
100
|
+
10. Wait for all required tasks to be terminal and members idle/ready, present results, then delete/archive unless the user wants to continue. Never discard unfinished work without authorization.
|
|
101
|
+
Tools: ${toolNames}${profilesText === '' ? '' : `\n\n${profilesText}`}`;
|
|
102
|
+
}
|
|
103
|
+
export function apply(ctx, config) {
|
|
104
|
+
const resolved = {
|
|
105
|
+
stateDir: config.stateDir ?? '.t-team',
|
|
106
|
+
memberProvider: config.memberProvider ?? 'spawn',
|
|
107
|
+
memberModel: config.memberModel,
|
|
108
|
+
executionPrompt: config.executionPrompt,
|
|
109
|
+
fallback: config.fallback,
|
|
110
|
+
memberMaxDepth: config.memberMaxDepth ?? 1,
|
|
111
|
+
maxMembers: config.maxMembers ?? 8,
|
|
112
|
+
profiles: config.profiles ?? {},
|
|
113
|
+
};
|
|
114
|
+
// Provider registration is a sibling plugin's effect (`subagent-spawn` /
|
|
115
|
+
// `subagent-fork` rows), which can land after this mount under the Loader's
|
|
116
|
+
// concurrent activation — so capability validation happens at the first
|
|
117
|
+
// member spawn (`spawnMember`), the earliest point the provider list is
|
|
118
|
+
// settled, rather than here.
|
|
119
|
+
const tTeamRuntime = registerTTeamTools(ctx, resolved);
|
|
120
|
+
installTeamCapabilities(ctx, {
|
|
121
|
+
stateDir: resolved.stateDir,
|
|
122
|
+
isPendingMember: tTeamRuntime.isPendingMember,
|
|
123
|
+
order: config.promptSectionOrder,
|
|
124
|
+
// Keep the bounded profile directory available without extra tool calls.
|
|
125
|
+
// installTeamCapabilities snapshots this once; no business state rewrites it.
|
|
126
|
+
captainPrompt: () => usageSectionText(TEAM_TOOL_NAMES.join(', '), formatProfilesForPrompt(config.profiles)),
|
|
127
|
+
});
|
|
128
|
+
// Deterministic activation surfaces: the closed-namespace `/t-team`
|
|
129
|
+
// host command (surfaces in the Web GUI slash menu via the Harness
|
|
130
|
+
// ui-commands client) and the plain-text gesture boundary for surfaces
|
|
131
|
+
// without command adjudication (headless CLI). Both default on; a profile
|
|
132
|
+
// can disable them to keep the natural-language trigger exclusive.
|
|
133
|
+
//
|
|
134
|
+
// `commands` is registered lazily (not a required inject): it ships in the
|
|
135
|
+
// base bundle of every standard profile, but a minimal composition that
|
|
136
|
+
// omits the command registry keeps the plugin fully functional — the fiber
|
|
137
|
+
// never pends on it and simply never gains the slash command.
|
|
138
|
+
if (config.slashCommand ?? true) {
|
|
139
|
+
ctx.inject(['commands'], (commandCtx) => {
|
|
140
|
+
registerTTeamCommand(commandCtx, () => config.profiles ?? {});
|
|
141
|
+
});
|
|
142
|
+
installTTeamGestureBoundary(ctx, () => config.profiles ?? {});
|
|
143
|
+
}
|
|
144
|
+
// The activity panel data/artwork routes need the Web server and the
|
|
145
|
+
// workspace registry, which headless profiles do not mount; under
|
|
146
|
+
// concurrent activation they may also bind after this plugin. Register the
|
|
147
|
+
// routes lazily: try now, then on each service binding event. In a webless
|
|
148
|
+
// profile the plugin stays tool-only and never blocks boot.
|
|
149
|
+
let webRegistered = false;
|
|
150
|
+
const registerWebSurface = () => {
|
|
151
|
+
if (webRegistered)
|
|
152
|
+
return;
|
|
153
|
+
const rawWebServer = (ctx.get(WEB_SERVER_KEYS[0]) ?? ctx.get(WEB_SERVER_KEYS[1]));
|
|
154
|
+
const workspaceRegistry = (ctx.get(WORKSPACE_KEYS[0]) ?? ctx.get(WORKSPACE_KEYS[1]));
|
|
155
|
+
if (rawWebServer === undefined || workspaceRegistry === undefined)
|
|
156
|
+
return;
|
|
157
|
+
const webServer = authenticatedWebRoutes(rawWebServer, () => ctx.get('connection'));
|
|
158
|
+
webRegistered = true;
|
|
159
|
+
// Activity panel data route: the browser floater polls this for team
|
|
160
|
+
// snapshots (disk truth + live subagent activity). Mirrors the Claude
|
|
161
|
+
// Code desktop watcher's server-side snapshot pattern.
|
|
162
|
+
ctx.effect(() => webServer.register({
|
|
163
|
+
kind: 'exact',
|
|
164
|
+
path: '/plugins/t-team/state',
|
|
165
|
+
handler: async (req, res) => {
|
|
166
|
+
const url = new URL(req.url ?? '/', 'http://x');
|
|
167
|
+
const roots = workspaceRegistry.list().map((workspace) => ({
|
|
168
|
+
workspace: workspace.title,
|
|
169
|
+
stateRoot: join(workspace.path, resolved.stateDir),
|
|
170
|
+
}));
|
|
171
|
+
// ?archived=1 serves teams moved to archive/ (post-delete review).
|
|
172
|
+
const snapshots = url.searchParams.get('archived') === '1'
|
|
173
|
+
? await collectArchivedTeamsActivity(ctx, roots)
|
|
174
|
+
: await collectTeamsActivity(ctx, roots);
|
|
175
|
+
const body = JSON.stringify({ teams: snapshots });
|
|
176
|
+
res.writeHead(200, {
|
|
177
|
+
'content-type': 'application/json; charset=utf-8',
|
|
178
|
+
'cache-control': 'no-store',
|
|
179
|
+
});
|
|
180
|
+
res.end(body);
|
|
181
|
+
},
|
|
182
|
+
}), 't-team: activity route');
|
|
183
|
+
ctx.effect(() => webServer.register({
|
|
184
|
+
kind: 'exact',
|
|
185
|
+
path: '/plugins/t-team/halt',
|
|
186
|
+
handler: async (req, res) => {
|
|
187
|
+
if (req.method !== 'POST') {
|
|
188
|
+
res.writeHead(405, { allow: 'POST', 'cache-control': 'no-store' });
|
|
189
|
+
res.end();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
let payload;
|
|
193
|
+
try {
|
|
194
|
+
payload = await readJsonRequest(req);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
res.writeHead(error instanceof RequestBodyError ? error.status : 400, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
198
|
+
res.end(JSON.stringify({ error: error instanceof Error ? error.message : 'invalid request body' }));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const sessionId = typeof payload.sessionId === 'string' ? payload.sessionId.trim() : '';
|
|
202
|
+
const teamId = typeof payload.teamId === 'string' ? payload.teamId.trim() : '';
|
|
203
|
+
if (sessionId === '' || teamId === '') {
|
|
204
|
+
res.writeHead(400, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
205
|
+
res.end(JSON.stringify({ error: 'sessionId and teamId are required' }));
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const captain = ctx.agents.get(sessionId);
|
|
209
|
+
if (captain === undefined) {
|
|
210
|
+
res.writeHead(409, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
211
|
+
res.end(JSON.stringify({ error: 'captain session is not attached' }));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const workspace = captain.session.header.cwd ?? process.cwd();
|
|
215
|
+
const stateRoot = join(workspace, resolved.stateDir);
|
|
216
|
+
const team = await findTeamByCaptain(stateRoot, captain.id);
|
|
217
|
+
if (team === undefined || team.id !== teamId) {
|
|
218
|
+
res.writeHead(404, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
219
|
+
res.end(JSON.stringify({ error: 'team not found for this captain' }));
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
try {
|
|
223
|
+
const result = await haltTeamWork({
|
|
224
|
+
ctx,
|
|
225
|
+
stateRoot,
|
|
226
|
+
teamId,
|
|
227
|
+
captain,
|
|
228
|
+
});
|
|
229
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
230
|
+
res.end(JSON.stringify(result));
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
ctx.logger.warn(`t-team: halt failed for ${teamId}: ${String(error)}`);
|
|
234
|
+
res.writeHead(500, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
235
|
+
res.end(JSON.stringify({ error: 'failed to stop the team' }));
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
}), 't-team: halt route');
|
|
239
|
+
ctx.effect(() => webServer.register({
|
|
240
|
+
kind: 'exact',
|
|
241
|
+
path: '/plugins/t-team/plan',
|
|
242
|
+
handler: async (req, res) => {
|
|
243
|
+
if (req.method !== 'POST') {
|
|
244
|
+
res.writeHead(405, { allow: 'POST', 'cache-control': 'no-store' });
|
|
245
|
+
res.end();
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
let payload;
|
|
249
|
+
try {
|
|
250
|
+
payload = await readJsonRequest(req);
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
res.writeHead(error instanceof RequestBodyError ? error.status : 400, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
254
|
+
res.end(JSON.stringify({ error: error instanceof Error ? error.message : 'invalid request body' }));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const sessionId = typeof payload['sessionId'] === 'string' ? payload['sessionId'].trim() : '';
|
|
258
|
+
const teamId = typeof payload['teamId'] === 'string' ? payload['teamId'].trim() : '';
|
|
259
|
+
const action = typeof payload['action'] === 'string' ? payload['action'] : '';
|
|
260
|
+
if (sessionId === '' || teamId === '' || action === '') {
|
|
261
|
+
res.writeHead(400, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
262
|
+
res.end(JSON.stringify({ error: 'sessionId, teamId, and action are required' }));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const captain = ctx.agents.get(sessionId);
|
|
266
|
+
if (captain === undefined) {
|
|
267
|
+
res.writeHead(409, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
268
|
+
res.end(JSON.stringify({ error: 'captain session is not attached' }));
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const workspace = captain.session.header.cwd ?? process.cwd();
|
|
272
|
+
const stateRoot = join(workspace, resolved.stateDir);
|
|
273
|
+
const team = await findTeamByCaptain(stateRoot, captain.id);
|
|
274
|
+
if (team === undefined || team.id !== teamId) {
|
|
275
|
+
res.writeHead(404, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
276
|
+
res.end(JSON.stringify({ error: 'team not found for this captain' }));
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
if (action === 'approve') {
|
|
281
|
+
const approved = await tTeamRuntime.approveStagedTeam(captain, teamId);
|
|
282
|
+
// The browser receives the HTTP result, so the model needs its own
|
|
283
|
+
// control message. steer wakes an idle captain or joins its next
|
|
284
|
+
// step; the tool approve path already returns to the model itself.
|
|
285
|
+
try {
|
|
286
|
+
captain.steer(createUserMessage({
|
|
287
|
+
content: [{ type: 'text', text: stagedPlanApprovedContext(team.name) }],
|
|
288
|
+
source: { kind: 'plugin', plugin: 't-team' },
|
|
289
|
+
}));
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
// Approval is already committed. Do not report a failed approval
|
|
293
|
+
// and invite a retry that could duplicate the user's action.
|
|
294
|
+
ctx.logger.warn(`t-team: approval notification failed for ${teamId}: ${String(error)}`);
|
|
295
|
+
}
|
|
296
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
297
|
+
res.end(JSON.stringify({ ok: true, phase: 'running', ...approved }));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (action === 'continue') {
|
|
301
|
+
const continued = await tTeamRuntime.continueStagedPlanning(captain, teamId);
|
|
302
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
303
|
+
res.end(JSON.stringify({ ok: true, phase: 'staged', review: 'awaiting_feedback', ...continued }));
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (action === 'discard') {
|
|
307
|
+
const discarded = await tTeamRuntime.discardStagedTeam(captain, teamId);
|
|
308
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
309
|
+
res.end(JSON.stringify({ ok: true, phase: 'archived', ...discarded }));
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const dependencies = Array.isArray(payload['dependencies'])
|
|
313
|
+
? payload['dependencies'].filter((item) => typeof item === 'string')
|
|
314
|
+
: [];
|
|
315
|
+
let mutation;
|
|
316
|
+
if (action === 'update_member') {
|
|
317
|
+
if (typeof payload['memberName'] !== 'string'
|
|
318
|
+
|| typeof payload['provider'] !== 'string'
|
|
319
|
+
|| typeof payload['model'] !== 'string')
|
|
320
|
+
throw new Error('memberName, provider, and model are required');
|
|
321
|
+
mutation = {
|
|
322
|
+
action,
|
|
323
|
+
memberName: payload['memberName'],
|
|
324
|
+
provider: payload['provider'],
|
|
325
|
+
model: payload['model'],
|
|
326
|
+
...typeof payload['role'] === 'string' || payload['role'] === null ? { role: payload['role'] } : {},
|
|
327
|
+
...typeof payload['reasoningEffort'] === 'string' || payload['reasoningEffort'] === null
|
|
328
|
+
? { reasoningEffort: payload['reasoningEffort'] }
|
|
329
|
+
: {},
|
|
330
|
+
...typeof payload['executionPrompt'] === 'string' || payload['executionPrompt'] === null
|
|
331
|
+
? { executionPrompt: payload['executionPrompt'] }
|
|
332
|
+
: {},
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
else if (action === 'update_task') {
|
|
336
|
+
if (typeof payload['taskId'] !== 'string' || typeof payload['subject'] !== 'string') {
|
|
337
|
+
throw new Error('taskId and subject are required');
|
|
338
|
+
}
|
|
339
|
+
mutation = {
|
|
340
|
+
action,
|
|
341
|
+
taskId: payload['taskId'],
|
|
342
|
+
subject: payload['subject'],
|
|
343
|
+
dependencies,
|
|
344
|
+
...typeof payload['description'] === 'string' || payload['description'] === null
|
|
345
|
+
? { description: payload['description'] }
|
|
346
|
+
: {},
|
|
347
|
+
...typeof payload['assignee'] === 'string' || payload['assignee'] === null
|
|
348
|
+
? { assignee: payload['assignee'] }
|
|
349
|
+
: {},
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
else if (action === 'add_task') {
|
|
353
|
+
if (typeof payload['subject'] !== 'string')
|
|
354
|
+
throw new Error('subject is required');
|
|
355
|
+
mutation = {
|
|
356
|
+
action,
|
|
357
|
+
subject: payload['subject'],
|
|
358
|
+
dependencies,
|
|
359
|
+
...typeof payload['description'] === 'string' || payload['description'] === null
|
|
360
|
+
? { description: payload['description'] }
|
|
361
|
+
: {},
|
|
362
|
+
...typeof payload['assignee'] === 'string' || payload['assignee'] === null
|
|
363
|
+
? { assignee: payload['assignee'] }
|
|
364
|
+
: {},
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
else if (action === 'remove_task') {
|
|
368
|
+
if (typeof payload['taskId'] !== 'string')
|
|
369
|
+
throw new Error('taskId is required');
|
|
370
|
+
mutation = { action, taskId: payload['taskId'] };
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
throw new Error(`unknown plan action "${action}"`);
|
|
374
|
+
}
|
|
375
|
+
const updated = await tTeamRuntime.updateStagedPlan(captain, teamId, mutation);
|
|
376
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
377
|
+
res.end(JSON.stringify({ ok: true, phase: updated.phase, members: updated.members.length, tasks: updated.tasks.length }));
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
res.writeHead(409, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
381
|
+
res.end(JSON.stringify({ error: error instanceof Error ? error.message : 'plan operation failed' }));
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
}), 't-team: plan route');
|
|
385
|
+
// Whale mascot artwork: serve the packaged V2 role/action images to the
|
|
386
|
+
// activity panel. An explicit allowlist guards the route (no path
|
|
387
|
+
// traversal); the images ship with the bundle (files: assets/).
|
|
388
|
+
const artDir = fileURLToPath(new URL('../assets/t-team/', import.meta.url));
|
|
389
|
+
const ART_ALLOWLIST = new Set([
|
|
390
|
+
'team-lead-v2.png',
|
|
391
|
+
'member-researcher-v2.png', 'member-engineer-v2.png',
|
|
392
|
+
'member-qa-v2.png', 'member-designer-v2.png',
|
|
393
|
+
'member-security-v2.png', 'member-docs-v2.png',
|
|
394
|
+
'member-data-v2.png', 'member-operator-v2.png',
|
|
395
|
+
'action-working-v2.png', 'action-thinking-v2.png',
|
|
396
|
+
'action-reporting-v2.png', 'action-celebrating-v2.png',
|
|
397
|
+
'action-sleeping-v2.png', 'action-sending-v2.png',
|
|
398
|
+
]);
|
|
399
|
+
ctx.effect(() => webServer.register({
|
|
400
|
+
kind: 'prefix',
|
|
401
|
+
path: '/plugins/t-team/assets',
|
|
402
|
+
handler: async (req, res) => {
|
|
403
|
+
let name;
|
|
404
|
+
try {
|
|
405
|
+
name = decodeURIComponent(new URL(req.url ?? '/', 'http://x').pathname.split('/').pop() ?? '');
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
// Malformed percent-encoding: treat as an unknown asset, not a 400.
|
|
409
|
+
res.writeHead(404);
|
|
410
|
+
res.end();
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
if (!ART_ALLOWLIST.has(name)) {
|
|
414
|
+
res.writeHead(404);
|
|
415
|
+
res.end();
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
try {
|
|
419
|
+
const data = await readFile(join(artDir, name));
|
|
420
|
+
res.writeHead(200, {
|
|
421
|
+
'content-type': 'image/png',
|
|
422
|
+
'cache-control': 'public, max-age=86400',
|
|
423
|
+
});
|
|
424
|
+
res.end(data);
|
|
425
|
+
}
|
|
426
|
+
catch (error) {
|
|
427
|
+
ctx.logger.warn(`t-team: artwork read failed for ${name}: ${String(error)}`);
|
|
428
|
+
res.writeHead(404);
|
|
429
|
+
res.end();
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
}), 't-team: artwork route');
|
|
433
|
+
};
|
|
434
|
+
registerWebSurface();
|
|
435
|
+
ctx.on('internal/service', (name) => {
|
|
436
|
+
if (WEB_SERVER_KEYS.includes(name)
|
|
437
|
+
|| WORKSPACE_KEYS.includes(name)) {
|
|
438
|
+
registerWebSurface();
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
}
|