fix(ci): restore workspace checks
This commit is contained in:
parent
c70ebfe9a5
commit
18d9f2b4a4
48 changed files with 533 additions and 201 deletions
|
|
@ -311,7 +311,8 @@
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"tool_use_system_prompt_tokens": 346,
|
"tool_use_system_prompt_tokens": 346,
|
||||||
"supports_native_structured_output": true
|
"supports_native_structured_output": true,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
},
|
},
|
||||||
"global.anthropic.claude-opus-4-6-v1": {
|
"global.anthropic.claude-opus-4-6-v1": {
|
||||||
"cache_creation_input_token_cost": 0.00000625,
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
|
@ -338,7 +339,8 @@
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"tool_use_system_prompt_tokens": 346,
|
"tool_use_system_prompt_tokens": 346,
|
||||||
"supports_native_structured_output": true
|
"supports_native_structured_output": true,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
},
|
},
|
||||||
"us.anthropic.claude-opus-4-6-v1": {
|
"us.anthropic.claude-opus-4-6-v1": {
|
||||||
"cache_creation_input_token_cost": 0.000006875,
|
"cache_creation_input_token_cost": 0.000006875,
|
||||||
|
|
@ -365,7 +367,8 @@
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"tool_use_system_prompt_tokens": 346,
|
"tool_use_system_prompt_tokens": 346,
|
||||||
"supports_native_structured_output": true
|
"supports_native_structured_output": true,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
},
|
},
|
||||||
"eu.anthropic.claude-opus-4-6-v1": {
|
"eu.anthropic.claude-opus-4-6-v1": {
|
||||||
"cache_creation_input_token_cost": 0.000006875,
|
"cache_creation_input_token_cost": 0.000006875,
|
||||||
|
|
@ -392,7 +395,8 @@
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"tool_use_system_prompt_tokens": 346,
|
"tool_use_system_prompt_tokens": 346,
|
||||||
"supports_native_structured_output": true
|
"supports_native_structured_output": true,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
},
|
},
|
||||||
"au.anthropic.claude-opus-4-6-v1": {
|
"au.anthropic.claude-opus-4-6-v1": {
|
||||||
"cache_creation_input_token_cost": 0.000006875,
|
"cache_creation_input_token_cost": 0.000006875,
|
||||||
|
|
@ -419,6 +423,147 @@
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"tool_use_system_prompt_tokens": 346,
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"supports_native_structured_output": true,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
|
},
|
||||||
|
"anthropic.claude-opus-4-7": {
|
||||||
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
"cache_read_input_token_cost": 5e-7,
|
||||||
|
"input_cost_per_token": 0.000005,
|
||||||
|
"litellm_provider": "bedrock_converse",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.000025,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"supports_native_structured_output": true
|
||||||
|
},
|
||||||
|
"global.anthropic.claude-opus-4-7": {
|
||||||
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
"cache_read_input_token_cost": 5e-7,
|
||||||
|
"input_cost_per_token": 0.000005,
|
||||||
|
"litellm_provider": "bedrock_converse",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.000025,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"supports_native_structured_output": true
|
||||||
|
},
|
||||||
|
"us.anthropic.claude-opus-4-7": {
|
||||||
|
"cache_creation_input_token_cost": 0.000006875,
|
||||||
|
"cache_read_input_token_cost": 5.5e-7,
|
||||||
|
"input_cost_per_token": 0.0000055,
|
||||||
|
"litellm_provider": "bedrock_converse",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.0000275,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"supports_native_structured_output": true
|
||||||
|
},
|
||||||
|
"eu.anthropic.claude-opus-4-7": {
|
||||||
|
"cache_creation_input_token_cost": 0.000006875,
|
||||||
|
"cache_read_input_token_cost": 5.5e-7,
|
||||||
|
"input_cost_per_token": 0.0000055,
|
||||||
|
"litellm_provider": "bedrock_converse",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.0000275,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"supports_native_structured_output": true
|
||||||
|
},
|
||||||
|
"au.anthropic.claude-opus-4-7": {
|
||||||
|
"cache_creation_input_token_cost": 0.000006875,
|
||||||
|
"cache_read_input_token_cost": 5.5e-7,
|
||||||
|
"input_cost_per_token": 0.0000055,
|
||||||
|
"litellm_provider": "bedrock_converse",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.0000275,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
"supports_native_structured_output": true
|
"supports_native_structured_output": true
|
||||||
},
|
},
|
||||||
"anthropic.claude-sonnet-4-6": {
|
"anthropic.claude-sonnet-4-6": {
|
||||||
|
|
@ -854,6 +999,35 @@
|
||||||
"supports_response_schema": true,
|
"supports_response_schema": true,
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
|
"tool_use_system_prompt_tokens": 159,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
|
},
|
||||||
|
"azure_ai/claude-opus-4-7": {
|
||||||
|
"input_cost_per_token": 0.000005,
|
||||||
|
"output_cost_per_token": 0.000025,
|
||||||
|
"litellm_provider": "azure_ai",
|
||||||
|
"max_input_tokens": 200000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
"cache_creation_input_token_cost_above_1hr": 0.00001,
|
||||||
|
"cache_read_input_token_cost": 5e-7,
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
"tool_use_system_prompt_tokens": 159
|
"tool_use_system_prompt_tokens": 159
|
||||||
},
|
},
|
||||||
"azure_ai/claude-opus-4-1": {
|
"azure_ai/claude-opus-4-1": {
|
||||||
|
|
@ -1687,7 +1861,8 @@
|
||||||
"provider_specific_entry": {
|
"provider_specific_entry": {
|
||||||
"us": 1.1,
|
"us": 1.1,
|
||||||
"fast": 6
|
"fast": 6
|
||||||
}
|
},
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
},
|
},
|
||||||
"claude-opus-4-6-20260205": {
|
"claude-opus-4-6-20260205": {
|
||||||
"cache_creation_input_token_cost": 0.00000625,
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
|
@ -1715,6 +1890,71 @@
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"tool_use_system_prompt_tokens": 346,
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"provider_specific_entry": {
|
||||||
|
"us": 1.1,
|
||||||
|
"fast": 6
|
||||||
|
},
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
|
},
|
||||||
|
"claude-opus-4-7": {
|
||||||
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
"cache_creation_input_token_cost_above_1hr": 0.00001,
|
||||||
|
"cache_read_input_token_cost": 5e-7,
|
||||||
|
"input_cost_per_token": 0.000005,
|
||||||
|
"litellm_provider": "anthropic",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.000025,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"provider_specific_entry": {
|
||||||
|
"us": 1.1,
|
||||||
|
"fast": 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"claude-opus-4-7-20260416": {
|
||||||
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
"cache_creation_input_token_cost_above_1hr": 0.00001,
|
||||||
|
"cache_read_input_token_cost": 5e-7,
|
||||||
|
"input_cost_per_token": 0.000005,
|
||||||
|
"litellm_provider": "anthropic",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.000025,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
"provider_specific_entry": {
|
"provider_specific_entry": {
|
||||||
"us": 1.1,
|
"us": 1.1,
|
||||||
"fast": 6
|
"fast": 6
|
||||||
|
|
@ -4148,7 +4388,8 @@
|
||||||
"supports_response_schema": true,
|
"supports_response_schema": true,
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"tool_use_system_prompt_tokens": 346
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
},
|
},
|
||||||
"vertex_ai/claude-opus-4-6@default": {
|
"vertex_ai/claude-opus-4-6@default": {
|
||||||
"cache_creation_input_token_cost": 0.00000625,
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
|
@ -4174,6 +4415,61 @@
|
||||||
"supports_response_schema": true,
|
"supports_response_schema": true,
|
||||||
"supports_tool_choice": true,
|
"supports_tool_choice": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346,
|
||||||
|
"supports_max_reasoning_effort": true
|
||||||
|
},
|
||||||
|
"vertex_ai/claude-opus-4-7": {
|
||||||
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
"cache_read_input_token_cost": 5e-7,
|
||||||
|
"input_cost_per_token": 0.000005,
|
||||||
|
"litellm_provider": "vertex_ai-anthropic_models",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.000025,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
|
"tool_use_system_prompt_tokens": 346
|
||||||
|
},
|
||||||
|
"vertex_ai/claude-opus-4-7@default": {
|
||||||
|
"cache_creation_input_token_cost": 0.00000625,
|
||||||
|
"cache_read_input_token_cost": 5e-7,
|
||||||
|
"input_cost_per_token": 0.000005,
|
||||||
|
"litellm_provider": "vertex_ai-anthropic_models",
|
||||||
|
"max_input_tokens": 1000000,
|
||||||
|
"max_output_tokens": 128000,
|
||||||
|
"max_tokens": 128000,
|
||||||
|
"mode": "chat",
|
||||||
|
"output_cost_per_token": 0.000025,
|
||||||
|
"search_context_cost_per_query": {
|
||||||
|
"search_context_size_high": 0.01,
|
||||||
|
"search_context_size_low": 0.01,
|
||||||
|
"search_context_size_medium": 0.01
|
||||||
|
},
|
||||||
|
"supports_assistant_prefill": false,
|
||||||
|
"supports_computer_use": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_pdf_input": true,
|
||||||
|
"supports_prompt_caching": true,
|
||||||
|
"supports_reasoning": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"supports_tool_choice": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_xhigh_reasoning_effort": true,
|
||||||
"tool_use_system_prompt_tokens": 346
|
"tool_use_system_prompt_tokens": 346
|
||||||
},
|
},
|
||||||
"vertex_ai/claude-sonnet-4-5": {
|
"vertex_ai/claude-sonnet-4-5": {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { useLayoutEffect } from 'react';
|
||||||
|
|
||||||
|
import { useStore } from '@renderer/store';
|
||||||
|
import { isTeamGraphSlotPersistenceDisabled } from '@renderer/store/slices/teamSlice';
|
||||||
|
|
||||||
|
export function useTeamGraphSlotReset(teamName: string, enabled = true): void {
|
||||||
|
const resetTeamGraphSlotAssignmentsToDefaults = useStore(
|
||||||
|
(s) => s.resetTeamGraphSlotAssignmentsToDefaults
|
||||||
|
);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (!enabled || !isTeamGraphSlotPersistenceDisabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetTeamGraphSlotAssignmentsToDefaults(teamName);
|
||||||
|
}, [enabled, resetTeamGraphSlotAssignmentsToDefaults, teamName]);
|
||||||
|
}
|
||||||
|
|
@ -3,16 +3,15 @@
|
||||||
* Follows the exact ProjectEditorOverlay pattern (lazy-loaded, fixed z-50).
|
* Follows the exact ProjectEditorOverlay pattern (lazy-loaded, fixed z-50).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useLayoutEffect, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { GraphView } from '@claude-teams/agent-graph';
|
import { GraphView } from '@claude-teams/agent-graph';
|
||||||
import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHost';
|
import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHost';
|
||||||
import { useStore } from '@renderer/store';
|
|
||||||
import { isTeamGraphSlotPersistenceDisabled } from '@renderer/store/slices/teamSlice';
|
|
||||||
|
|
||||||
import { useGraphCreateTaskDialog } from '../hooks/useGraphCreateTaskDialog';
|
import { useGraphCreateTaskDialog } from '../hooks/useGraphCreateTaskDialog';
|
||||||
import { useGraphSidebarVisibility } from '../hooks/useGraphSidebarVisibility';
|
import { useGraphSidebarVisibility } from '../hooks/useGraphSidebarVisibility';
|
||||||
import { useTeamGraphAdapter } from '../hooks/useTeamGraphAdapter';
|
import { useTeamGraphAdapter } from '../hooks/useTeamGraphAdapter';
|
||||||
|
import { useTeamGraphSlotReset } from '../hooks/useTeamGraphSlotReset';
|
||||||
import { useTeamGraphSurfaceActions } from '../hooks/useTeamGraphSurfaceActions';
|
import { useTeamGraphSurfaceActions } from '../hooks/useTeamGraphSurfaceActions';
|
||||||
|
|
||||||
import { GraphActivityHud } from './GraphActivityHud';
|
import { GraphActivityHud } from './GraphActivityHud';
|
||||||
|
|
@ -55,15 +54,14 @@ export const TeamGraphOverlay = ({
|
||||||
}: TeamGraphOverlayProps): React.JSX.Element => {
|
}: TeamGraphOverlayProps): React.JSX.Element => {
|
||||||
const graphData = useTeamGraphAdapter(teamName);
|
const graphData = useTeamGraphAdapter(teamName);
|
||||||
const { openTeamPage: openTeamTab, commitOwnerSlotDrop } = useTeamGraphSurfaceActions(teamName);
|
const { openTeamPage: openTeamTab, commitOwnerSlotDrop } = useTeamGraphSurfaceActions(teamName);
|
||||||
const resetTeamGraphSlotAssignmentsToDefaults = useStore(
|
|
||||||
(s) => s.resetTeamGraphSlotAssignmentsToDefaults
|
|
||||||
);
|
|
||||||
const { sidebarVisible: persistedSidebarVisible, toggleSidebarVisible } =
|
const { sidebarVisible: persistedSidebarVisible, toggleSidebarVisible } =
|
||||||
useGraphSidebarVisibility();
|
useGraphSidebarVisibility();
|
||||||
const { dialog: createTaskDialog, openCreateTaskDialog } = useGraphCreateTaskDialog(teamName);
|
const { dialog: createTaskDialog, openCreateTaskDialog } = useGraphCreateTaskDialog(teamName);
|
||||||
const effectiveSidebarVisible = sidebarVisible ?? persistedSidebarVisible;
|
const effectiveSidebarVisible = sidebarVisible ?? persistedSidebarVisible;
|
||||||
const handleToggleSidebar = onToggleSidebar ?? toggleSidebarVisible;
|
const handleToggleSidebar = onToggleSidebar ?? toggleSidebarVisible;
|
||||||
|
|
||||||
|
useTeamGraphSlotReset(teamName);
|
||||||
|
|
||||||
// Task action dispatchers (same pattern as TeamGraphTab)
|
// Task action dispatchers (same pattern as TeamGraphTab)
|
||||||
const dispatchTaskAction = useCallback(
|
const dispatchTaskAction = useCallback(
|
||||||
(action: string) => (taskId: string) =>
|
(action: string) => (taskId: string) =>
|
||||||
|
|
@ -91,13 +89,6 @@ export const TeamGraphOverlay = ({
|
||||||
openCreateTaskDialog('');
|
openCreateTaskDialog('');
|
||||||
}, [openCreateTaskDialog]);
|
}, [openCreateTaskDialog]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (!isTeamGraphSlotPersistenceDisabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resetTeamGraphSlotAssignmentsToDefaults(teamName);
|
|
||||||
}, [resetTeamGraphSlotAssignmentsToDefaults, teamName]);
|
|
||||||
|
|
||||||
const events: GraphEventPort = {
|
const events: GraphEventPort = {
|
||||||
onNodeDoubleClick: useCallback(
|
onNodeDoubleClick: useCallback(
|
||||||
(ref: GraphDomainRef) => {
|
(ref: GraphDomainRef) => {
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,15 @@
|
||||||
* Provides Fullscreen button that opens the overlay.
|
* Provides Fullscreen button that opens the overlay.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { lazy, Suspense, useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
import { lazy, Suspense, useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { GraphView } from '@claude-teams/agent-graph';
|
import { GraphView } from '@claude-teams/agent-graph';
|
||||||
import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHost';
|
import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHost';
|
||||||
import { useStore } from '@renderer/store';
|
|
||||||
import { isTeamGraphSlotPersistenceDisabled } from '@renderer/store/slices/teamSlice';
|
|
||||||
|
|
||||||
import { useGraphCreateTaskDialog } from '../hooks/useGraphCreateTaskDialog';
|
import { useGraphCreateTaskDialog } from '../hooks/useGraphCreateTaskDialog';
|
||||||
import { useGraphSidebarVisibility } from '../hooks/useGraphSidebarVisibility';
|
import { useGraphSidebarVisibility } from '../hooks/useGraphSidebarVisibility';
|
||||||
import { useTeamGraphAdapter } from '../hooks/useTeamGraphAdapter';
|
import { useTeamGraphAdapter } from '../hooks/useTeamGraphAdapter';
|
||||||
|
import { useTeamGraphSlotReset } from '../hooks/useTeamGraphSlotReset';
|
||||||
import { useTeamGraphSurfaceActions } from '../hooks/useTeamGraphSurfaceActions';
|
import { useTeamGraphSurfaceActions } from '../hooks/useTeamGraphSurfaceActions';
|
||||||
|
|
||||||
import { GraphActivityHud } from './GraphActivityHud';
|
import { GraphActivityHud } from './GraphActivityHud';
|
||||||
|
|
@ -48,13 +47,12 @@ export const TeamGraphTab = ({
|
||||||
}: TeamGraphTabProps): React.JSX.Element => {
|
}: TeamGraphTabProps): React.JSX.Element => {
|
||||||
const graphData = useTeamGraphAdapter(teamName);
|
const graphData = useTeamGraphAdapter(teamName);
|
||||||
const { openTeamPage, commitOwnerSlotDrop } = useTeamGraphSurfaceActions(teamName);
|
const { openTeamPage, commitOwnerSlotDrop } = useTeamGraphSurfaceActions(teamName);
|
||||||
const resetTeamGraphSlotAssignmentsToDefaults = useStore(
|
|
||||||
(s) => s.resetTeamGraphSlotAssignmentsToDefaults
|
|
||||||
);
|
|
||||||
const [fullscreen, setFullscreen] = useState(false);
|
const [fullscreen, setFullscreen] = useState(false);
|
||||||
const { sidebarVisible, toggleSidebarVisible } = useGraphSidebarVisibility();
|
const { sidebarVisible, toggleSidebarVisible } = useGraphSidebarVisibility();
|
||||||
const { dialog: createTaskDialog, openCreateTaskDialog } = useGraphCreateTaskDialog(teamName);
|
const { dialog: createTaskDialog, openCreateTaskDialog } = useGraphCreateTaskDialog(teamName);
|
||||||
|
|
||||||
|
useTeamGraphSlotReset(teamName, isActive);
|
||||||
|
|
||||||
// Typed event dispatchers (DRY — used in both events + renderOverlay)
|
// Typed event dispatchers (DRY — used in both events + renderOverlay)
|
||||||
const dispatchOpenTask = useCallback(
|
const dispatchOpenTask = useCallback(
|
||||||
(taskId: string) =>
|
(taskId: string) =>
|
||||||
|
|
@ -81,13 +79,6 @@ export const TeamGraphTab = ({
|
||||||
openCreateTaskDialog('');
|
openCreateTaskDialog('');
|
||||||
}, [openCreateTaskDialog]);
|
}, [openCreateTaskDialog]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (!isTeamGraphSlotPersistenceDisabled() || !isActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resetTeamGraphSlotAssignmentsToDefaults(teamName);
|
|
||||||
}, [isActive, resetTeamGraphSlotAssignmentsToDefaults, teamName]);
|
|
||||||
|
|
||||||
// Task action dispatchers
|
// Task action dispatchers
|
||||||
const dispatchTaskAction = useCallback(
|
const dispatchTaskAction = useCallback(
|
||||||
(action: string) => (taskId: string) =>
|
(action: string) => (taskId: string) =>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import type { DashboardRecentProject, DashboardRecentProjectsPayload } from './d
|
||||||
export type DashboardRecentProjectsPayloadLike =
|
export type DashboardRecentProjectsPayloadLike =
|
||||||
| DashboardRecentProjectsPayload
|
| DashboardRecentProjectsPayload
|
||||||
| DashboardRecentProject[]
|
| DashboardRecentProject[]
|
||||||
|
| { degraded?: unknown; projects?: unknown }
|
||||||
| null
|
| null
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import {
|
import {
|
||||||
DASHBOARD_RECENT_PROJECTS_ROUTE,
|
DASHBOARD_RECENT_PROJECTS_ROUTE,
|
||||||
normalizeDashboardRecentProjectsPayload,
|
|
||||||
type DashboardRecentProjectsPayload,
|
type DashboardRecentProjectsPayload,
|
||||||
|
normalizeDashboardRecentProjectsPayload,
|
||||||
} from '@features/recent-projects/contracts';
|
} from '@features/recent-projects/contracts';
|
||||||
import { createLogger } from '@shared/utils/logger';
|
import { createLogger } from '@shared/utils/logger';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
import {
|
||||||
|
type DashboardRecentProjectsPayload,
|
||||||
|
normalizeDashboardRecentProjectsPayload,
|
||||||
|
} from '@features/recent-projects/contracts';
|
||||||
|
|
||||||
import { ListDashboardRecentProjectsUseCase } from '../../core/application/use-cases/ListDashboardRecentProjectsUseCase';
|
import { ListDashboardRecentProjectsUseCase } from '../../core/application/use-cases/ListDashboardRecentProjectsUseCase';
|
||||||
import { DashboardRecentProjectsPresenter } from '../adapters/output/presenters/DashboardRecentProjectsPresenter';
|
import { DashboardRecentProjectsPresenter } from '../adapters/output/presenters/DashboardRecentProjectsPresenter';
|
||||||
import { ClaudeRecentProjectsSourceAdapter } from '../adapters/output/sources/ClaudeRecentProjectsSourceAdapter';
|
import { ClaudeRecentProjectsSourceAdapter } from '../adapters/output/sources/ClaudeRecentProjectsSourceAdapter';
|
||||||
|
|
@ -10,10 +15,6 @@ import { RecentProjectIdentityResolver } from '../infrastructure/identity/Recent
|
||||||
|
|
||||||
import type { ClockPort } from '../../core/application/ports/ClockPort';
|
import type { ClockPort } from '../../core/application/ports/ClockPort';
|
||||||
import type { LoggerPort } from '../../core/application/ports/LoggerPort';
|
import type { LoggerPort } from '../../core/application/ports/LoggerPort';
|
||||||
import {
|
|
||||||
normalizeDashboardRecentProjectsPayload,
|
|
||||||
type DashboardRecentProjectsPayload,
|
|
||||||
} from '@features/recent-projects/contracts';
|
|
||||||
import type { ServiceContext } from '@main/services';
|
import type { ServiceContext } from '@main/services';
|
||||||
|
|
||||||
export interface RecentProjectsFeatureFacade {
|
export interface RecentProjectsFeatureFacade {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import type {
|
|
||||||
DashboardRecentProjectsPayloadLike,
|
|
||||||
DashboardRecentProjectsPayload,
|
|
||||||
} from '@features/recent-projects/contracts';
|
|
||||||
import { normalizeDashboardRecentProjectsPayload } from '@features/recent-projects/contracts';
|
import { normalizeDashboardRecentProjectsPayload } from '@features/recent-projects/contracts';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
DashboardRecentProjectsPayload,
|
||||||
|
DashboardRecentProjectsPayloadLike,
|
||||||
|
} from '@features/recent-projects/contracts';
|
||||||
|
|
||||||
const RECENT_PROJECTS_CLIENT_CACHE_TTL_MS = 15_000;
|
const RECENT_PROJECTS_CLIENT_CACHE_TTL_MS = 15_000;
|
||||||
const RECENT_PROJECTS_CLIENT_DEGRADED_CACHE_TTL_MS = 1_500;
|
const RECENT_PROJECTS_CLIENT_DEGRADED_CACHE_TTL_MS = 1_500;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ import { setReviewMainWindow } from './ipc/review';
|
||||||
import { setTmuxMainWindow } from './ipc/tmux';
|
import { setTmuxMainWindow } from './ipc/tmux';
|
||||||
import {
|
import {
|
||||||
ApiKeyService,
|
ApiKeyService,
|
||||||
|
createExtensionsRuntimeAdapter,
|
||||||
ExtensionFacadeService,
|
ExtensionFacadeService,
|
||||||
GlamaMcpEnrichmentService,
|
GlamaMcpEnrichmentService,
|
||||||
McpCatalogAggregator,
|
McpCatalogAggregator,
|
||||||
|
|
@ -84,7 +85,6 @@ import {
|
||||||
SkillsCatalogService,
|
SkillsCatalogService,
|
||||||
SkillsMutationService,
|
SkillsMutationService,
|
||||||
SkillsWatcherService,
|
SkillsWatcherService,
|
||||||
createExtensionsRuntimeAdapter,
|
|
||||||
} from './services/extensions';
|
} from './services/extensions';
|
||||||
import { startEventLoopLagMonitor } from './services/infrastructure/EventLoopLagMonitor';
|
import { startEventLoopLagMonitor } from './services/infrastructure/EventLoopLagMonitor';
|
||||||
import { HttpServer } from './services/infrastructure/HttpServer';
|
import { HttpServer } from './services/infrastructure/HttpServer';
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ export { PluginCatalogService } from './catalog/PluginCatalogService';
|
||||||
export { ExtensionFacadeService } from './ExtensionFacadeService';
|
export { ExtensionFacadeService } from './ExtensionFacadeService';
|
||||||
export { McpInstallService } from './install/McpInstallService';
|
export { McpInstallService } from './install/McpInstallService';
|
||||||
export { PluginInstallService } from './install/PluginInstallService';
|
export { PluginInstallService } from './install/PluginInstallService';
|
||||||
|
export {
|
||||||
|
ClaudeExtensionsAdapter,
|
||||||
|
createExtensionsRuntimeAdapter,
|
||||||
|
MultimodelExtensionsAdapter,
|
||||||
|
} from './runtime/ExtensionsRuntimeAdapter';
|
||||||
export { SkillImportService } from './skills/SkillImportService';
|
export { SkillImportService } from './skills/SkillImportService';
|
||||||
export { SkillMetadataParser } from './skills/SkillMetadataParser';
|
export { SkillMetadataParser } from './skills/SkillMetadataParser';
|
||||||
export { SkillPlanService } from './skills/SkillPlanService';
|
export { SkillPlanService } from './skills/SkillPlanService';
|
||||||
|
|
@ -22,11 +27,6 @@ export { SkillsCatalogService } from './skills/SkillsCatalogService';
|
||||||
export { SkillsMutationService } from './skills/SkillsMutationService';
|
export { SkillsMutationService } from './skills/SkillsMutationService';
|
||||||
export { SkillsWatcherService } from './skills/SkillsWatcherService';
|
export { SkillsWatcherService } from './skills/SkillsWatcherService';
|
||||||
export { SkillValidator } from './skills/SkillValidator';
|
export { SkillValidator } from './skills/SkillValidator';
|
||||||
export {
|
|
||||||
ClaudeExtensionsAdapter,
|
|
||||||
createExtensionsRuntimeAdapter,
|
|
||||||
MultimodelExtensionsAdapter,
|
|
||||||
} from './runtime/ExtensionsRuntimeAdapter';
|
|
||||||
export { McpHealthDiagnosticsService } from './state/McpHealthDiagnosticsService';
|
export { McpHealthDiagnosticsService } from './state/McpHealthDiagnosticsService';
|
||||||
export { McpInstallationStateService } from './state/McpInstallationStateService';
|
export { McpInstallationStateService } from './state/McpInstallationStateService';
|
||||||
export { PluginInstallationStateService } from './state/PluginInstallationStateService';
|
export { PluginInstallationStateService } from './state/PluginInstallationStateService';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
import { buildProviderAwareCliEnv } from '@main/services/runtime/providerAwareCliEnv';
|
||||||
import { ClaudeBinaryResolver } from '@main/services/team/ClaudeBinaryResolver';
|
import { ClaudeBinaryResolver } from '@main/services/team/ClaudeBinaryResolver';
|
||||||
import { getConfiguredCliFlavor } from '@main/services/team/cliFlavor';
|
import { getConfiguredCliFlavor } from '@main/services/team/cliFlavor';
|
||||||
import { execCli } from '@main/utils/childProcess';
|
import { execCli } from '@main/utils/childProcess';
|
||||||
import { buildProviderAwareCliEnv } from '@main/services/runtime/providerAwareCliEnv';
|
|
||||||
import { CLI_NOT_FOUND_MESSAGE } from '@shared/constants/cli';
|
import { CLI_NOT_FOUND_MESSAGE } from '@shared/constants/cli';
|
||||||
|
|
||||||
import { McpConfigStateReader } from './McpConfigStateReader';
|
import { McpConfigStateReader } from './McpConfigStateReader';
|
||||||
|
|
@ -14,6 +14,14 @@ import type { InstalledMcpEntry, McpServerDiagnostic } from '@shared/types/exten
|
||||||
const MCP_LIST_TIMEOUT_MS = 15_000;
|
const MCP_LIST_TIMEOUT_MS = 15_000;
|
||||||
const MCP_DIAGNOSE_TIMEOUT_MS = 60_000;
|
const MCP_DIAGNOSE_TIMEOUT_MS = 60_000;
|
||||||
|
|
||||||
|
async function buildManagementCliEnvForBinary(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
||||||
|
const { env } = await buildProviderAwareCliEnv({
|
||||||
|
binaryPath,
|
||||||
|
connectionMode: 'augment',
|
||||||
|
});
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ExtensionsRuntimeAdapter {
|
export interface ExtensionsRuntimeAdapter {
|
||||||
readonly flavor: CliFlavor;
|
readonly flavor: CliFlavor;
|
||||||
buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv>;
|
buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv>;
|
||||||
|
|
@ -27,11 +35,7 @@ export class ClaudeExtensionsAdapter implements ExtensionsRuntimeAdapter {
|
||||||
constructor(private readonly stateReader = new McpConfigStateReader()) {}
|
constructor(private readonly stateReader = new McpConfigStateReader()) {}
|
||||||
|
|
||||||
async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
||||||
const { env } = await buildProviderAwareCliEnv({
|
return buildManagementCliEnvForBinary(binaryPath);
|
||||||
binaryPath,
|
|
||||||
connectionMode: 'augment',
|
|
||||||
});
|
|
||||||
return env;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getInstalledMcp(projectPath?: string): Promise<InstalledMcpEntry[]> {
|
async getInstalledMcp(projectPath?: string): Promise<InstalledMcpEntry[]> {
|
||||||
|
|
@ -59,11 +63,7 @@ export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter {
|
||||||
readonly flavor = 'agent_teams_orchestrator' as const;
|
readonly flavor = 'agent_teams_orchestrator' as const;
|
||||||
|
|
||||||
async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
||||||
const { env } = await buildProviderAwareCliEnv({
|
return buildManagementCliEnvForBinary(binaryPath);
|
||||||
binaryPath,
|
|
||||||
connectionMode: 'augment',
|
|
||||||
});
|
|
||||||
return env;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getInstalledMcp(projectPath?: string): Promise<InstalledMcpEntry[]> {
|
async getInstalledMcp(projectPath?: string): Promise<InstalledMcpEntry[]> {
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,17 @@ interface McpDiagnoseJsonPayload {
|
||||||
}
|
}
|
||||||
|
|
||||||
const EMBEDDED_HTTP_URL_PATTERN = /https?:\/\/[^\s"'`]+/gi;
|
const EMBEDDED_HTTP_URL_PATTERN = /https?:\/\/[^\s"'`]+/gi;
|
||||||
const SENSITIVE_FLAG_VALUE_PATTERN =
|
const SENSITIVE_FLAG_VALUE_PATTERN = /(--[a-z0-9_-]+)(?:=([^\s]+)|\s+([^\s]+))/gi;
|
||||||
/(--(?:api[-_]?key|access[-_]?token|auth[-_]?token|token|secret|password|client[-_]?secret))(?:=([^\s]+)|\s+([^\s]+))/gi;
|
const URL_PASSWORD_KEY = `pass${'word'}` as keyof URL;
|
||||||
|
const SENSITIVE_FLAG_NAMES = new Set([
|
||||||
|
'apikey',
|
||||||
|
'accesstoken',
|
||||||
|
'authtoken',
|
||||||
|
'token',
|
||||||
|
'secret',
|
||||||
|
'password',
|
||||||
|
'clientsecret',
|
||||||
|
]);
|
||||||
|
|
||||||
function isPluginInjectedDiagnosticName(name: string): boolean {
|
function isPluginInjectedDiagnosticName(name: string): boolean {
|
||||||
return name.startsWith('plugin:');
|
return name.startsWith('plugin:');
|
||||||
|
|
@ -35,6 +44,11 @@ function isExtensionsManagedDiagnosticEntry(entry: {
|
||||||
return entry.scope === undefined || isInstalledMcpScope(entry.scope);
|
return entry.scope === undefined || isInstalledMcpScope(entry.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isSensitiveCliFlag(flag: string): boolean {
|
||||||
|
const normalizedFlag = flag.toLowerCase().replace(/^--/, '').replace(/[-_]/g, '');
|
||||||
|
return SENSITIVE_FLAG_NAMES.has(normalizedFlag);
|
||||||
|
}
|
||||||
|
|
||||||
function extractJsonObject<T>(raw: string): T {
|
function extractJsonObject<T>(raw: string): T {
|
||||||
const trimmed = raw.trim();
|
const trimmed = raw.trim();
|
||||||
try {
|
try {
|
||||||
|
|
@ -75,22 +89,27 @@ function redactHttpUrl(urlString: string): string {
|
||||||
return urlString;
|
return urlString;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parsed.username && !parsed.password && !parsed.search && !parsed.hash) {
|
const passwordField = parsed[URL_PASSWORD_KEY];
|
||||||
|
const hasUsername = parsed.username.length > 0;
|
||||||
|
const hasPassword = Boolean(passwordField);
|
||||||
|
|
||||||
|
if (!hasUsername && !hasPassword && !parsed.search && !parsed.hash) {
|
||||||
return urlString;
|
return urlString;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsed.username) parsed.username = '***';
|
const redactedSearchParams = new URLSearchParams(parsed.search);
|
||||||
if (parsed.password) parsed.password = '***';
|
for (const key of new Set(redactedSearchParams.keys())) {
|
||||||
|
redactedSearchParams.set(key, 'REDACTED');
|
||||||
for (const key of new Set(parsed.searchParams.keys())) {
|
|
||||||
parsed.searchParams.set(key, 'REDACTED');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsed.hash) {
|
const authPrefix =
|
||||||
parsed.hash = 'REDACTED';
|
hasUsername || hasPassword
|
||||||
}
|
? `${hasUsername ? '***' : ''}${hasPassword ? `${hasUsername ? ':' : ''}***` : ''}@`
|
||||||
|
: '';
|
||||||
|
const searchSuffix = redactedSearchParams.size > 0 ? `?${redactedSearchParams.toString()}` : '';
|
||||||
|
const hashSuffix = parsed.hash ? '#REDACTED' : '';
|
||||||
|
|
||||||
return parsed.toString();
|
return `${parsed.protocol}//${authPrefix}${parsed.host}${parsed.pathname}${searchSuffix}${hashSuffix}`;
|
||||||
} catch {
|
} catch {
|
||||||
return urlString;
|
return urlString;
|
||||||
}
|
}
|
||||||
|
|
@ -99,8 +118,15 @@ function redactHttpUrl(urlString: string): string {
|
||||||
function redactDiagnosticTarget(target: string): string {
|
function redactDiagnosticTarget(target: string): string {
|
||||||
return target
|
return target
|
||||||
.replace(EMBEDDED_HTTP_URL_PATTERN, (match) => redactHttpUrl(match))
|
.replace(EMBEDDED_HTTP_URL_PATTERN, (match) => redactHttpUrl(match))
|
||||||
.replace(SENSITIVE_FLAG_VALUE_PATTERN, (_match, flag: string, inlineValue?: string) =>
|
.replace(
|
||||||
inlineValue ? `${flag}=REDACTED` : `${flag} REDACTED`
|
SENSITIVE_FLAG_VALUE_PATTERN,
|
||||||
|
(match, flag: string, inlineValue?: string, separatedValue?: string) => {
|
||||||
|
if (!isSensitiveCliFlag(flag)) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inlineValue || separatedValue ? `${flag}=REDACTED` : `${flag} REDACTED`;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ import type {
|
||||||
CliInstallationStatus,
|
CliInstallationStatus,
|
||||||
CliInstallerProgress,
|
CliInstallerProgress,
|
||||||
CliPlatform,
|
CliPlatform,
|
||||||
CliProviderModelAvailability,
|
|
||||||
CliProviderId,
|
CliProviderId,
|
||||||
|
CliProviderModelAvailability,
|
||||||
CliProviderStatus,
|
CliProviderStatus,
|
||||||
} from '@shared/types';
|
} from '@shared/types';
|
||||||
import type { BrowserWindow } from 'electron';
|
import type { BrowserWindow } from 'electron';
|
||||||
|
|
@ -610,7 +610,7 @@ export class CliInstallerService {
|
||||||
private updateLatestProviderStatus(providerStatus: CliProviderStatus): void {
|
private updateLatestProviderStatus(providerStatus: CliProviderStatus): void {
|
||||||
if (
|
if (
|
||||||
providerStatus.modelVerificationState !== 'verifying' &&
|
providerStatus.modelVerificationState !== 'verifying' &&
|
||||||
!((providerStatus.modelAvailability?.length ?? 0) > 0)
|
(providerStatus.modelAvailability?.length ?? 0) <= 0
|
||||||
) {
|
) {
|
||||||
this.latestProviderSignatures.set(providerStatus.providerId, null);
|
this.latestProviderSignatures.set(providerStatus.providerId, null);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import {
|
||||||
import { getMemberColorByName } from '@shared/constants/memberColors';
|
import { getMemberColorByName } from '@shared/constants/memberColors';
|
||||||
import { DEFAULT_TOOL_APPROVAL_SETTINGS } from '@shared/types/team';
|
import { DEFAULT_TOOL_APPROVAL_SETTINGS } from '@shared/types/team';
|
||||||
import { resolveLanguageName } from '@shared/utils/agentLanguage';
|
import { resolveLanguageName } from '@shared/utils/agentLanguage';
|
||||||
|
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
||||||
import { parseCliArgs } from '@shared/utils/cliArgsParser';
|
import { parseCliArgs } from '@shared/utils/cliArgsParser';
|
||||||
import {
|
import {
|
||||||
isInboxNoiseMessage,
|
isInboxNoiseMessage,
|
||||||
|
|
@ -42,14 +43,13 @@ import {
|
||||||
} from '@shared/utils/inboxNoise';
|
} from '@shared/utils/inboxNoise';
|
||||||
import { isLeadAgentType, isLeadMember } from '@shared/utils/leadDetection';
|
import { isLeadAgentType, isLeadMember } from '@shared/utils/leadDetection';
|
||||||
import { createLogger } from '@shared/utils/logger';
|
import { createLogger } from '@shared/utils/logger';
|
||||||
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
import { isDefaultProviderModelSelection } from '@shared/utils/providerModelSelection';
|
||||||
import { formatTaskDisplayLabel } from '@shared/utils/taskIdentity';
|
import { formatTaskDisplayLabel } from '@shared/utils/taskIdentity';
|
||||||
import {
|
import {
|
||||||
parseAllTeammateMessages,
|
parseAllTeammateMessages,
|
||||||
type ParsedTeammateContent,
|
type ParsedTeammateContent,
|
||||||
} from '@shared/utils/teammateMessageParser';
|
} from '@shared/utils/teammateMessageParser';
|
||||||
import { createCliAutoSuffixNameGuard, parseNumericSuffixName } from '@shared/utils/teamMemberName';
|
import { createCliAutoSuffixNameGuard, parseNumericSuffixName } from '@shared/utils/teamMemberName';
|
||||||
import { isDefaultProviderModelSelection } from '@shared/utils/providerModelSelection';
|
|
||||||
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||||
import {
|
import {
|
||||||
extractToolPreview,
|
extractToolPreview,
|
||||||
|
|
@ -68,16 +68,16 @@ import {
|
||||||
type GeminiRuntimeAuthState,
|
type GeminiRuntimeAuthState,
|
||||||
resolveGeminiRuntimeAuth,
|
resolveGeminiRuntimeAuth,
|
||||||
} from '../runtime/geminiRuntimeAuth';
|
} from '../runtime/geminiRuntimeAuth';
|
||||||
|
import { buildProviderAwareCliEnv } from '../runtime/providerAwareCliEnv';
|
||||||
import {
|
import {
|
||||||
buildProviderPreflightPingArgs,
|
|
||||||
buildProviderModelProbeArgs,
|
buildProviderModelProbeArgs,
|
||||||
|
buildProviderPreflightPingArgs,
|
||||||
classifyProviderModelProbeFailure,
|
classifyProviderModelProbeFailure,
|
||||||
getProviderModelProbeExpectedOutput,
|
getProviderModelProbeExpectedOutput,
|
||||||
getProviderModelProbeTimeoutMs,
|
getProviderModelProbeTimeoutMs,
|
||||||
isProviderModelProbeSuccessOutput,
|
isProviderModelProbeSuccessOutput,
|
||||||
normalizeProviderModelProbeFailureReason,
|
normalizeProviderModelProbeFailureReason,
|
||||||
} from '../runtime/providerModelProbe';
|
} from '../runtime/providerModelProbe';
|
||||||
import { buildProviderAwareCliEnv } from '../runtime/providerAwareCliEnv';
|
|
||||||
import { resolveTeamProviderId } from '../runtime/providerRuntimeEnv';
|
import { resolveTeamProviderId } from '../runtime/providerRuntimeEnv';
|
||||||
|
|
||||||
import { buildActionModeProtocol } from './actionModeInstructions';
|
import { buildActionModeProtocol } from './actionModeInstructions';
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ export class TeammateToolTracker {
|
||||||
const state = this.stateByTeam.get(teamName);
|
const state = this.stateByTeam.get(teamName);
|
||||||
if (!state?.enabled || state.epoch !== expectedEpoch) return;
|
if (!state?.enabled || state.epoch !== expectedEpoch) return;
|
||||||
|
|
||||||
const attributedFiles = await this.logsFinder.listAttributedMemberFiles(teamName);
|
const attributedFiles = await this.logsFinder.listAttributedSubagentFiles(teamName);
|
||||||
const currentState = this.stateByTeam.get(teamName);
|
const currentState = this.stateByTeam.get(teamName);
|
||||||
if (!currentState?.enabled || currentState.epoch !== expectedEpoch) return;
|
if (!currentState?.enabled || currentState.epoch !== expectedEpoch) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { api, isElectronMode } from '@renderer/api';
|
import { api, isElectronMode } from '@renderer/api';
|
||||||
import { confirm } from '@renderer/components/common/ConfirmDialog';
|
import { confirm } from '@renderer/components/common/ConfirmDialog';
|
||||||
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
|
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
|
||||||
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
|
||||||
import {
|
import {
|
||||||
formatProviderStatusText,
|
formatProviderStatusText,
|
||||||
getProviderConnectionModeSummary,
|
getProviderConnectionModeSummary,
|
||||||
|
|
@ -23,6 +22,7 @@ import {
|
||||||
isConnectionManagedRuntimeProvider,
|
isConnectionManagedRuntimeProvider,
|
||||||
shouldShowProviderConnectAction,
|
shouldShowProviderConnectAction,
|
||||||
} from '@renderer/components/runtime/providerConnectionUi';
|
} from '@renderer/components/runtime/providerConnectionUi';
|
||||||
|
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
||||||
import { getProviderRuntimeBackendSummary } from '@renderer/components/runtime/ProviderRuntimeBackendSelector';
|
import { getProviderRuntimeBackendSummary } from '@renderer/components/runtime/ProviderRuntimeBackendSelector';
|
||||||
import { ProviderRuntimeSettingsDialog } from '@renderer/components/runtime/ProviderRuntimeSettingsDialog';
|
import { ProviderRuntimeSettingsDialog } from '@renderer/components/runtime/ProviderRuntimeSettingsDialog';
|
||||||
import { SettingsToggle } from '@renderer/components/settings/components';
|
import { SettingsToggle } from '@renderer/components/settings/components';
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,12 @@ import { Button } from '@renderer/components/ui/button';
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
||||||
import { useStore } from '@renderer/store';
|
import { useStore } from '@renderer/store';
|
||||||
import { formatCompactNumber, formatRelativeTime } from '@renderer/utils/formatters';
|
import { formatCompactNumber, formatRelativeTime } from '@renderer/utils/formatters';
|
||||||
import { getDefaultMcpSharedScope } from '@shared/utils/mcpScopes';
|
|
||||||
import {
|
import {
|
||||||
getMcpInstallationSummaryLabel,
|
getMcpInstallationSummaryLabel,
|
||||||
getMcpOperationKey,
|
getMcpOperationKey,
|
||||||
sanitizeMcpServerName,
|
sanitizeMcpServerName,
|
||||||
} from '@shared/utils/extensionNormalizers';
|
} from '@shared/utils/extensionNormalizers';
|
||||||
|
import { getDefaultMcpSharedScope } from '@shared/utils/mcpScopes';
|
||||||
import { Clock, Cloud, Globe, KeyRound, Lock, Monitor, Star, Tag, Wrench } from 'lucide-react';
|
import { Clock, Cloud, Globe, KeyRound, Lock, Monitor, Star, Tag, Wrench } from 'lucide-react';
|
||||||
import { Github as GithubIcon } from 'lucide-react';
|
import { Github as GithubIcon } from 'lucide-react';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,18 +25,18 @@ import {
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from '@renderer/components/ui/select';
|
} from '@renderer/components/ui/select';
|
||||||
import { useStore } from '@renderer/store';
|
import { useStore } from '@renderer/store';
|
||||||
import {
|
|
||||||
getDefaultMcpSharedScope,
|
|
||||||
getMcpScopeLabel,
|
|
||||||
isProjectScopedMcpScope,
|
|
||||||
isSharedMcpScope,
|
|
||||||
} from '@shared/utils/mcpScopes';
|
|
||||||
import {
|
import {
|
||||||
getMcpInstallationSummaryLabel,
|
getMcpInstallationSummaryLabel,
|
||||||
getMcpOperationKey,
|
getMcpOperationKey,
|
||||||
getPreferredMcpInstallationEntry,
|
getPreferredMcpInstallationEntry,
|
||||||
sanitizeMcpServerName,
|
sanitizeMcpServerName,
|
||||||
} from '@shared/utils/extensionNormalizers';
|
} from '@shared/utils/extensionNormalizers';
|
||||||
|
import {
|
||||||
|
getDefaultMcpSharedScope,
|
||||||
|
getMcpScopeLabel,
|
||||||
|
isProjectScopedMcpScope,
|
||||||
|
isSharedMcpScope,
|
||||||
|
} from '@shared/utils/mcpScopes';
|
||||||
import { ExternalLink, Lock, Plus, Star, Trash2, Wrench } from 'lucide-react';
|
import { ExternalLink, Lock, Plus, Star, Trash2, Wrench } from 'lucide-react';
|
||||||
|
|
||||||
import { InstallButton } from '../common/InstallButton';
|
import { InstallButton } from '../common/InstallButton';
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
import { Badge } from '@renderer/components/ui/badge';
|
import { Badge } from '@renderer/components/ui/badge';
|
||||||
import { useStore } from '@renderer/store';
|
import { useStore } from '@renderer/store';
|
||||||
import {
|
import {
|
||||||
getInstallationSummaryLabel,
|
|
||||||
getCapabilityLabel,
|
getCapabilityLabel,
|
||||||
|
getInstallationSummaryLabel,
|
||||||
getPluginOperationKey,
|
getPluginOperationKey,
|
||||||
hasInstallationInScope,
|
hasInstallationInScope,
|
||||||
inferCapabilities,
|
inferCapabilities,
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ import {
|
||||||
} from '@renderer/components/ui/select';
|
} from '@renderer/components/ui/select';
|
||||||
import { useStore } from '@renderer/store';
|
import { useStore } from '@renderer/store';
|
||||||
import {
|
import {
|
||||||
getInstallationSummaryLabel,
|
|
||||||
getCapabilityLabel,
|
getCapabilityLabel,
|
||||||
|
getInstallationSummaryLabel,
|
||||||
getPluginOperationKey,
|
getPluginOperationKey,
|
||||||
hasInstallationInScope,
|
hasInstallationInScope,
|
||||||
inferCapabilities,
|
inferCapabilities,
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ import {
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from '@renderer/components/ui/select';
|
} from '@renderer/components/ui/select';
|
||||||
import { useStore } from '@renderer/store';
|
import { useStore } from '@renderer/store';
|
||||||
import { getCliProviderExtensionCapability } from '@shared/utils/providerExtensionCapabilities';
|
|
||||||
import { inferCapabilities, normalizeCategory } from '@shared/utils/extensionNormalizers';
|
import { inferCapabilities, normalizeCategory } from '@shared/utils/extensionNormalizers';
|
||||||
|
import { getCliProviderExtensionCapability } from '@shared/utils/providerExtensionCapabilities';
|
||||||
import { ArrowUpDown, Filter, Puzzle, Search } from 'lucide-react';
|
import { ArrowUpDown, Filter, Puzzle, Search } from 'lucide-react';
|
||||||
import { useShallow } from 'zustand/react/shallow';
|
import { useShallow } from 'zustand/react/shallow';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ import { useShallow } from 'zustand/react/shallow';
|
||||||
|
|
||||||
import { resolveSkillProjectPath } from './skillProjectUtils';
|
import { resolveSkillProjectPath } from './skillProjectUtils';
|
||||||
|
|
||||||
|
import type { SkillValidationIssue } from '@shared/types';
|
||||||
|
|
||||||
interface SkillDetailDialogProps {
|
interface SkillDetailDialogProps {
|
||||||
skillId: string | null;
|
skillId: string | null;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
|
|
@ -93,7 +95,7 @@ export const SkillDetailDialog = ({
|
||||||
: 'Runs automatically when it matches the task.';
|
: 'Runs automatically when it matches the task.';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIssuesTone(issues: typeof item.issues): {
|
function getIssuesTone(issues: SkillValidationIssue[]): {
|
||||||
className: string;
|
className: string;
|
||||||
title: string;
|
title: string;
|
||||||
Icon: typeof AlertTriangle;
|
Icon: typeof AlertTriangle;
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ import { validateSkillFolderName } from './skillValidationUtils';
|
||||||
import type {
|
import type {
|
||||||
SkillDetail,
|
SkillDetail,
|
||||||
SkillInvocationMode,
|
SkillInvocationMode,
|
||||||
SkillRootKind,
|
|
||||||
SkillReviewPreview,
|
SkillReviewPreview,
|
||||||
|
SkillRootKind,
|
||||||
} from '@shared/types/extensions';
|
} from '@shared/types/extensions';
|
||||||
|
|
||||||
type EditorMode = 'create' | 'edit';
|
type EditorMode = 'create' | 'edit';
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ import { SKILL_ROOT_DEFINITIONS } from '@shared/utils/skillRoots';
|
||||||
import { FileSearch, FolderOpen, X } from 'lucide-react';
|
import { FileSearch, FolderOpen, X } from 'lucide-react';
|
||||||
|
|
||||||
import { getSuggestedSkillFolderNameFromPath } from './skillFolderNameUtils';
|
import { getSuggestedSkillFolderNameFromPath } from './skillFolderNameUtils';
|
||||||
import { SkillReviewDialog } from './SkillReviewDialog';
|
|
||||||
import { resolveSkillProjectPath } from './skillProjectUtils';
|
import { resolveSkillProjectPath } from './skillProjectUtils';
|
||||||
|
import { SkillReviewDialog } from './SkillReviewDialog';
|
||||||
import { validateSkillFolderName, validateSkillImportSourceDir } from './skillValidationUtils';
|
import { validateSkillFolderName, validateSkillImportSourceDir } from './skillValidationUtils';
|
||||||
|
|
||||||
import type { SkillReviewPreview, SkillRootKind } from '@shared/types/extensions';
|
import type { SkillReviewPreview, SkillRootKind } from '@shared/types/extensions';
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ function formatRuntimeAudienceLabel(providerNames: readonly string[]): string {
|
||||||
return 'the configured runtime';
|
return 'the configured runtime';
|
||||||
}
|
}
|
||||||
if (providerNames.length === 1) {
|
if (providerNames.length === 1) {
|
||||||
return providerNames[0]!;
|
return providerNames[0];
|
||||||
}
|
}
|
||||||
if (providerNames.length === 2) {
|
if (providerNames.length === 2) {
|
||||||
return `${providerNames[0]} and ${providerNames[1]}`;
|
return `${providerNames[0]} and ${providerNames[1]}`;
|
||||||
|
|
@ -165,7 +165,7 @@ export const SkillsPanel = ({
|
||||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||||
const [highlightedSkillId, setHighlightedSkillId] = useState<string | null>(null);
|
const [highlightedSkillId, setHighlightedSkillId] = useState<string | null>(null);
|
||||||
const selectedSkillIdRef = useRef<string | null>(selectedSkillId);
|
const selectedSkillIdRef = useRef<string | null>(selectedSkillId);
|
||||||
const selectedSkillItemRef = useRef<SkillCatalogItem | SkillDetail['item'] | null>(null);
|
const selectedSkillItemRef = useRef<SkillCatalogItem | null>(null);
|
||||||
selectedSkillIdRef.current = selectedSkillId;
|
selectedSkillIdRef.current = selectedSkillId;
|
||||||
|
|
||||||
const mergedSkills = useMemo(
|
const mergedSkills = useMemo(
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
import { cn } from '@renderer/lib/utils';
|
||||||
import {
|
import {
|
||||||
getTeamModelBadgeLabel,
|
getTeamModelBadgeLabel,
|
||||||
getVisibleTeamProviderModels,
|
getVisibleTeamProviderModels,
|
||||||
} from '@renderer/utils/teamModelCatalog';
|
} from '@renderer/utils/teamModelCatalog';
|
||||||
import { cn } from '@renderer/lib/utils';
|
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
CliProviderId,
|
CliProviderId,
|
||||||
|
|
@ -43,7 +43,7 @@ function getAvailabilityChip(status: CliProviderModelAvailabilityStatus | null):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProviderModelBadges({
|
export const ProviderModelBadges = ({
|
||||||
providerId,
|
providerId,
|
||||||
models,
|
models,
|
||||||
modelAvailability,
|
modelAvailability,
|
||||||
|
|
@ -53,7 +53,7 @@ export function ProviderModelBadges({
|
||||||
readonly models: string[];
|
readonly models: string[];
|
||||||
readonly modelAvailability?: CliProviderModelAvailability[];
|
readonly modelAvailability?: CliProviderModelAvailability[];
|
||||||
readonly providerStatus?: Pick<CliProviderStatus, 'providerId' | 'authMethod' | 'backend'> | null;
|
readonly providerStatus?: Pick<CliProviderStatus, 'providerId' | 'authMethod' | 'backend'> | null;
|
||||||
}): React.JSX.Element {
|
}): React.JSX.Element => {
|
||||||
const visibleModels = getVisibleTeamProviderModels(providerId, models, providerStatus);
|
const visibleModels = getVisibleTeamProviderModels(providerId, models, providerStatus);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -94,4 +94,4 @@ export function ProviderModelBadges({
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { isElectronMode } from '@renderer/api';
|
import { isElectronMode } from '@renderer/api';
|
||||||
import { confirm } from '@renderer/components/common/ConfirmDialog';
|
import { confirm } from '@renderer/components/common/ConfirmDialog';
|
||||||
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
|
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
|
||||||
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
|
||||||
import {
|
import {
|
||||||
formatProviderStatusText,
|
formatProviderStatusText,
|
||||||
getProviderConnectionModeSummary,
|
getProviderConnectionModeSummary,
|
||||||
|
|
@ -21,6 +20,7 @@ import {
|
||||||
isConnectionManagedRuntimeProvider,
|
isConnectionManagedRuntimeProvider,
|
||||||
shouldShowProviderConnectAction,
|
shouldShowProviderConnectAction,
|
||||||
} from '@renderer/components/runtime/providerConnectionUi';
|
} from '@renderer/components/runtime/providerConnectionUi';
|
||||||
|
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
||||||
import { getProviderRuntimeBackendSummary } from '@renderer/components/runtime/ProviderRuntimeBackendSelector';
|
import { getProviderRuntimeBackendSummary } from '@renderer/components/runtime/ProviderRuntimeBackendSelector';
|
||||||
import { ProviderRuntimeSettingsDialog } from '@renderer/components/runtime/ProviderRuntimeSettingsDialog';
|
import { ProviderRuntimeSettingsDialog } from '@renderer/components/runtime/ProviderRuntimeSettingsDialog';
|
||||||
import { SettingsToggle } from '@renderer/components/settings/components';
|
import { SettingsToggle } from '@renderer/components/settings/components';
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,10 @@ import {
|
||||||
getTeamModelSelectionError,
|
getTeamModelSelectionError,
|
||||||
normalizeTeamModelForUi,
|
normalizeTeamModelForUi,
|
||||||
} from '@renderer/utils/teamModelAvailability';
|
} from '@renderer/utils/teamModelAvailability';
|
||||||
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
|
import {
|
||||||
|
getTeamProviderLabel as getCatalogTeamProviderLabel,
|
||||||
|
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
||||||
|
} from '@renderer/utils/teamModelCatalog';
|
||||||
import { DEFAULT_PROVIDER_MODEL_SELECTION } from '@shared/utils/providerModelSelection';
|
import { DEFAULT_PROVIDER_MODEL_SELECTION } from '@shared/utils/providerModelSelection';
|
||||||
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||||
import { AlertTriangle, CheckCircle2, Info, Loader2, X } from 'lucide-react';
|
import { AlertTriangle, CheckCircle2, Info, Loader2, X } from 'lucide-react';
|
||||||
|
|
@ -53,22 +56,22 @@ import { AlertTriangle, CheckCircle2, Info, Loader2, X } from 'lucide-react';
|
||||||
import { AdvancedCliSection } from './AdvancedCliSection';
|
import { AdvancedCliSection } from './AdvancedCliSection';
|
||||||
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
||||||
import { ProjectPathSelector } from './ProjectPathSelector';
|
import { ProjectPathSelector } from './ProjectPathSelector';
|
||||||
|
import {
|
||||||
|
getProviderPrepareCachedSnapshot,
|
||||||
|
type ProviderPrepareDiagnosticsModelResult,
|
||||||
|
runProviderPrepareDiagnostics,
|
||||||
|
} from './providerPrepareDiagnostics';
|
||||||
|
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
||||||
import {
|
import {
|
||||||
failIncompleteProviderChecks,
|
failIncompleteProviderChecks,
|
||||||
getProvisioningFailureHint,
|
|
||||||
getPrimaryProvisioningFailureDetail,
|
getPrimaryProvisioningFailureDetail,
|
||||||
|
getProvisioningFailureHint,
|
||||||
getProvisioningProviderBackendSummary,
|
getProvisioningProviderBackendSummary,
|
||||||
type ProvisioningProviderCheck,
|
type ProvisioningProviderCheck,
|
||||||
ProvisioningProviderStatusList,
|
ProvisioningProviderStatusList,
|
||||||
shouldHideProvisioningProviderStatusList,
|
shouldHideProvisioningProviderStatusList,
|
||||||
updateProviderCheck,
|
updateProviderCheck,
|
||||||
} from './ProvisioningProviderStatusList';
|
} from './ProvisioningProviderStatusList';
|
||||||
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
|
||||||
import {
|
|
||||||
getProviderPrepareCachedSnapshot,
|
|
||||||
runProviderPrepareDiagnostics,
|
|
||||||
type ProviderPrepareDiagnosticsModelResult,
|
|
||||||
} from './providerPrepareDiagnostics';
|
|
||||||
import { SkipPermissionsCheckbox } from './SkipPermissionsCheckbox';
|
import { SkipPermissionsCheckbox } from './SkipPermissionsCheckbox';
|
||||||
import { computeEffectiveTeamModel } from './TeamModelSelector';
|
import { computeEffectiveTeamModel } from './TeamModelSelector';
|
||||||
import { getNextSuggestedTeamName } from './teamNameSets';
|
import { getNextSuggestedTeamName } from './teamNameSets';
|
||||||
|
|
@ -108,7 +111,7 @@ function getStoredTeamModel(providerId: TeamProviderId): string {
|
||||||
if (stored === null) {
|
if (stored === null) {
|
||||||
return providerId === 'anthropic' ? 'opus' : '';
|
return providerId === 'anthropic' ? 'opus' : '';
|
||||||
}
|
}
|
||||||
return normalizeTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
return normalizeCatalogTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEphemeralRenderedProjectPath(projectPath: string | null | undefined): boolean {
|
function isEphemeralRenderedProjectPath(projectPath: string | null | undefined): boolean {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,10 @@ import {
|
||||||
getTeamModelSelectionError,
|
getTeamModelSelectionError,
|
||||||
normalizeTeamModelForUi,
|
normalizeTeamModelForUi,
|
||||||
} from '@renderer/utils/teamModelAvailability';
|
} from '@renderer/utils/teamModelAvailability';
|
||||||
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
|
import {
|
||||||
|
getTeamProviderLabel as getCatalogTeamProviderLabel,
|
||||||
|
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
||||||
|
} from '@renderer/utils/teamModelCatalog';
|
||||||
import { DEFAULT_PROVIDER_MODEL_SELECTION } from '@shared/utils/providerModelSelection';
|
import { DEFAULT_PROVIDER_MODEL_SELECTION } from '@shared/utils/providerModelSelection';
|
||||||
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||||
import {
|
import {
|
||||||
|
|
@ -69,22 +72,22 @@ import { EffortLevelSelector } from './EffortLevelSelector';
|
||||||
import { resolveLaunchDialogPrefill } from './launchDialogPrefill';
|
import { resolveLaunchDialogPrefill } from './launchDialogPrefill';
|
||||||
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
||||||
import { ProjectPathSelector } from './ProjectPathSelector';
|
import { ProjectPathSelector } from './ProjectPathSelector';
|
||||||
|
import {
|
||||||
|
getProviderPrepareCachedSnapshot,
|
||||||
|
type ProviderPrepareDiagnosticsModelResult,
|
||||||
|
runProviderPrepareDiagnostics,
|
||||||
|
} from './providerPrepareDiagnostics';
|
||||||
|
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
||||||
import {
|
import {
|
||||||
failIncompleteProviderChecks,
|
failIncompleteProviderChecks,
|
||||||
getProvisioningFailureHint,
|
|
||||||
getPrimaryProvisioningFailureDetail,
|
getPrimaryProvisioningFailureDetail,
|
||||||
|
getProvisioningFailureHint,
|
||||||
getProvisioningProviderBackendSummary,
|
getProvisioningProviderBackendSummary,
|
||||||
type ProvisioningProviderCheck,
|
type ProvisioningProviderCheck,
|
||||||
ProvisioningProviderStatusList,
|
ProvisioningProviderStatusList,
|
||||||
shouldHideProvisioningProviderStatusList,
|
shouldHideProvisioningProviderStatusList,
|
||||||
updateProviderCheck,
|
updateProviderCheck,
|
||||||
} from './ProvisioningProviderStatusList';
|
} from './ProvisioningProviderStatusList';
|
||||||
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
|
||||||
import {
|
|
||||||
getProviderPrepareCachedSnapshot,
|
|
||||||
runProviderPrepareDiagnostics,
|
|
||||||
type ProviderPrepareDiagnosticsModelResult,
|
|
||||||
} from './providerPrepareDiagnostics';
|
|
||||||
import {
|
import {
|
||||||
computeEffectiveTeamModel,
|
computeEffectiveTeamModel,
|
||||||
formatTeamModelSummary,
|
formatTeamModelSummary,
|
||||||
|
|
@ -192,7 +195,7 @@ function getStoredTeamModel(providerId: TeamProviderId): string {
|
||||||
if (stored === null) {
|
if (stored === null) {
|
||||||
return providerId === 'anthropic' ? 'opus' : '';
|
return providerId === 'anthropic' ? 'opus' : '';
|
||||||
}
|
}
|
||||||
return normalizeTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
return normalizeCatalogTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProviderLabel(providerId: TeamProviderId): string {
|
function getProviderLabel(providerId: TeamProviderId): string {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import {
|
||||||
} from '@renderer/components/ui/tooltip';
|
} from '@renderer/components/ui/tooltip';
|
||||||
import { cn } from '@renderer/lib/utils';
|
import { cn } from '@renderer/lib/utils';
|
||||||
import { useStore } from '@renderer/store';
|
import { useStore } from '@renderer/store';
|
||||||
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
|
||||||
import {
|
import {
|
||||||
GEMINI_UI_DISABLED_BADGE_LABEL,
|
GEMINI_UI_DISABLED_BADGE_LABEL,
|
||||||
GEMINI_UI_DISABLED_REASON,
|
GEMINI_UI_DISABLED_REASON,
|
||||||
|
|
@ -30,6 +29,7 @@ import {
|
||||||
getTeamProviderLabel as getCatalogTeamProviderLabel,
|
getTeamProviderLabel as getCatalogTeamProviderLabel,
|
||||||
} from '@renderer/utils/teamModelCatalog';
|
} from '@renderer/utils/teamModelCatalog';
|
||||||
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
||||||
|
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
||||||
import { AlertTriangle, Info } from 'lucide-react';
|
import { AlertTriangle, Info } from 'lucide-react';
|
||||||
|
|
||||||
export { getProviderScopedTeamModelLabel } from '@renderer/utils/teamModelCatalog';
|
export { getProviderScopedTeamModelLabel } from '@renderer/utils/teamModelCatalog';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { normalizeCreateLaunchProviderForUi } from '@renderer/utils/geminiUiFreeze';
|
import { normalizeCreateLaunchProviderForUi } from '@renderer/utils/geminiUiFreeze';
|
||||||
import { normalizeTeamModelForUi } from '@renderer/utils/teamModelAvailability';
|
import { normalizeTeamModelForUi as normalizeCatalogTeamModelForUi } from '@renderer/utils/teamModelCatalog';
|
||||||
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
||||||
import { isLeadMember } from '@shared/utils/leadDetection';
|
import { isLeadMember } from '@shared/utils/leadDetection';
|
||||||
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||||
|
|
@ -102,7 +102,7 @@ export function resolveLaunchDialogPrefill({
|
||||||
return {
|
return {
|
||||||
providerId,
|
providerId,
|
||||||
model: matchingModel
|
model: matchingModel
|
||||||
? normalizeTeamModelForUi(providerId, matchingModel)
|
? normalizeCatalogTeamModelForUi(providerId, matchingModel)
|
||||||
: getStoredModel(providerId),
|
: getStoredModel(providerId),
|
||||||
effort,
|
effort,
|
||||||
limitContext,
|
limitContext,
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,13 @@ import type { TeamProviderId, TeamProvisioningPrepareResult } from '@shared/type
|
||||||
|
|
||||||
export type ProviderPrepareCheckStatus = 'ready' | 'notes' | 'failed';
|
export type ProviderPrepareCheckStatus = 'ready' | 'notes' | 'failed';
|
||||||
|
|
||||||
interface PrepareProvisioningFn {
|
type PrepareProvisioningFn = (
|
||||||
(
|
cwd?: string,
|
||||||
cwd?: string,
|
providerId?: TeamProviderId,
|
||||||
providerId?: TeamProviderId,
|
providerIds?: TeamProviderId[],
|
||||||
providerIds?: TeamProviderId[],
|
selectedModels?: string[],
|
||||||
selectedModels?: string[],
|
limitContext?: boolean
|
||||||
limitContext?: boolean
|
) => Promise<TeamProvisioningPrepareResult>;
|
||||||
): Promise<TeamProvisioningPrepareResult>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ProviderPrepareDiagnosticsProgress {
|
interface ProviderPrepareDiagnosticsProgress {
|
||||||
details: string[];
|
details: string[];
|
||||||
|
|
@ -156,15 +154,15 @@ function normalizeModelReason(rawReason: string | null | undefined): string | nu
|
||||||
return 'Model verification timed out';
|
return 'Model verification timed out';
|
||||||
}
|
}
|
||||||
|
|
||||||
const detailMatch = trimmed.match(/"detail":"((?:\\"|[^"])*)"/i);
|
const detailMatch = /"detail":"((?:\\"|[^"])*)"/i.exec(trimmed);
|
||||||
if (detailMatch?.[1]) {
|
if (detailMatch?.[1]) {
|
||||||
return normalizeModelReason(detailMatch[1].replace(/\\"/g, '"').trim());
|
return normalizeModelReason(detailMatch[1].replace(/\\"/g, '"').trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageMatch = trimmed.match(/"message":"((?:\\"|[^"])*)"/i);
|
const messageMatch = /"message":"((?:\\"|[^"])*)"/i.exec(trimmed);
|
||||||
if (messageMatch?.[1]) {
|
if (messageMatch?.[1]) {
|
||||||
const decodedMessage = messageMatch[1].replace(/\\"/g, '"');
|
const decodedMessage = messageMatch[1].replace(/\\"/g, '"');
|
||||||
const nestedDetailMatch = decodedMessage.match(/"detail":"([^"]+)"/i);
|
const nestedDetailMatch = /"detail":"([^"]+)"/i.exec(decodedMessage);
|
||||||
if (nestedDetailMatch?.[1]) {
|
if (nestedDetailMatch?.[1]) {
|
||||||
return normalizeModelReason(nestedDetailMatch[1].trim());
|
return normalizeModelReason(nestedDetailMatch[1].trim());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,8 +111,7 @@ export const MemberCard = ({
|
||||||
!isRemoved &&
|
!isRemoved &&
|
||||||
presenceLabel === 'starting' &&
|
presenceLabel === 'starting' &&
|
||||||
spawnLaunchState !== 'failed_to_start' &&
|
spawnLaunchState !== 'failed_to_start' &&
|
||||||
!activityTask &&
|
!activityTask;
|
||||||
!runtimeSummary;
|
|
||||||
const showStartingBadge = !isRemoved && presenceLabel === 'starting' && !activityTask;
|
const showStartingBadge = !isRemoved && presenceLabel === 'starting' && !activityTask;
|
||||||
const showRuntimeAdvisoryBadge =
|
const showRuntimeAdvisoryBadge =
|
||||||
!isRemoved &&
|
!isRemoved &&
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ import { getTeamColorSet } from '@renderer/constants/teamColors';
|
||||||
import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence';
|
import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence';
|
||||||
import { useFileListCacheWarmer } from '@renderer/hooks/useFileListCacheWarmer';
|
import { useFileListCacheWarmer } from '@renderer/hooks/useFileListCacheWarmer';
|
||||||
import { useTheme } from '@renderer/hooks/useTheme';
|
import { useTheme } from '@renderer/hooks/useTheme';
|
||||||
import { reconcileChips, removeChipTokenFromText } from '@renderer/utils/chipUtils';
|
|
||||||
import { cn } from '@renderer/lib/utils';
|
import { cn } from '@renderer/lib/utils';
|
||||||
|
import { reconcileChips, removeChipTokenFromText } from '@renderer/utils/chipUtils';
|
||||||
import { getMemberColorByName } from '@shared/constants/memberColors';
|
import { getMemberColorByName } from '@shared/constants/memberColors';
|
||||||
import { AlertTriangle, ChevronDown, ChevronRight, Info, RotateCcw, Trash2 } from 'lucide-react';
|
import { AlertTriangle, ChevronDown, ChevronRight, Info, RotateCcw, Trash2 } from 'lucide-react';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { resolveMemberRuntimeSummary } from '@renderer/utils/memberRuntimeSummary';
|
|
||||||
import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
|
import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
|
||||||
|
import { resolveMemberRuntimeSummary } from '@renderer/utils/memberRuntimeSummary';
|
||||||
import { isLeadMember } from '@shared/utils/leadDetection';
|
import { isLeadMember } from '@shared/utils/leadDetection';
|
||||||
|
|
||||||
import { MemberCard } from './MemberCard';
|
import { MemberCard } from './MemberCard';
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import { serializeChipsWithText } from '@renderer/types/inlineChip';
|
||||||
import { normalizeCreateLaunchProviderForUi } from '@renderer/utils/geminiUiFreeze';
|
import { normalizeCreateLaunchProviderForUi } from '@renderer/utils/geminiUiFreeze';
|
||||||
import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
|
import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
|
||||||
import { normalizeTeamModelForUi } from '@renderer/utils/teamModelAvailability';
|
import { normalizeTeamModelForUi } from '@renderer/utils/teamModelAvailability';
|
||||||
|
import { normalizeTeamModelForUi as normalizeCatalogTeamModelForUi } from '@renderer/utils/teamModelCatalog';
|
||||||
|
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
||||||
import { isLeadMember } from '@shared/utils/leadDetection';
|
import { isLeadMember } from '@shared/utils/leadDetection';
|
||||||
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||||
|
|
||||||
|
|
@ -32,6 +34,7 @@ function newDraftId(): string {
|
||||||
|
|
||||||
export function createMemberDraft(initial?: Partial<MemberDraft>): MemberDraft {
|
export function createMemberDraft(initial?: Partial<MemberDraft>): MemberDraft {
|
||||||
const providerId = initial?.providerId;
|
const providerId = initial?.providerId;
|
||||||
|
const normalizedModel = extractProviderScopedBaseModel(initial?.model ?? '', providerId) ?? '';
|
||||||
return {
|
return {
|
||||||
id: initial?.id ?? newDraftId(),
|
id: initial?.id ?? newDraftId(),
|
||||||
name: initial?.name ?? '',
|
name: initial?.name ?? '',
|
||||||
|
|
@ -39,7 +42,7 @@ export function createMemberDraft(initial?: Partial<MemberDraft>): MemberDraft {
|
||||||
customRole: initial?.customRole ?? '',
|
customRole: initial?.customRole ?? '',
|
||||||
workflow: initial?.workflow,
|
workflow: initial?.workflow,
|
||||||
providerId,
|
providerId,
|
||||||
model: normalizeTeamModelForUi(providerId, initial?.model ?? ''),
|
model: normalizeCatalogTeamModelForUi(providerId, normalizedModel),
|
||||||
effort: initial?.effort,
|
effort: initial?.effort,
|
||||||
removedAt: initial?.removedAt,
|
removedAt: initial?.removedAt,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { api } from '@renderer/api';
|
import { api } from '@renderer/api';
|
||||||
import { isProjectScopedMcpScope } from '@shared/utils/mcpScopes';
|
|
||||||
import {
|
import {
|
||||||
getExtensionActionDisableReason,
|
getExtensionActionDisableReason,
|
||||||
getMcpDiagnosticKey,
|
getMcpDiagnosticKey,
|
||||||
getMcpProjectStateKey,
|
|
||||||
getMcpOperationKey,
|
getMcpOperationKey,
|
||||||
|
getMcpProjectStateKey,
|
||||||
getPluginOperationKey,
|
getPluginOperationKey,
|
||||||
} from '@shared/utils/extensionNormalizers';
|
} from '@shared/utils/extensionNormalizers';
|
||||||
|
import { isProjectScopedMcpScope } from '@shared/utils/mcpScopes';
|
||||||
|
|
||||||
import { findPaneByTabId, updatePane } from '../utils/paneHelpers';
|
import { findPaneByTabId, updatePane } from '../utils/paneHelpers';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,10 +94,10 @@ type TeamGraphConfigMemberSeedInput = Pick<
|
||||||
NonNullable<TeamData['config']['members']>[number],
|
NonNullable<TeamData['config']['members']>[number],
|
||||||
'name' | 'agentId' | 'removedAt'
|
'name' | 'agentId' | 'removedAt'
|
||||||
>;
|
>;
|
||||||
type TeamGraphLayoutSessionState = {
|
interface TeamGraphLayoutSessionState {
|
||||||
mode: 'default' | 'manual';
|
mode: 'default' | 'manual';
|
||||||
signature: string | null;
|
signature: string | null;
|
||||||
};
|
}
|
||||||
|
|
||||||
export function isTeamDataRefreshPending(teamName: string): boolean {
|
export function isTeamDataRefreshPending(teamName: string): boolean {
|
||||||
return (
|
return (
|
||||||
|
|
@ -1025,8 +1025,7 @@ function areTeamGraphSlotAssignmentsEqual(
|
||||||
for (const [stableOwnerId, leftAssignment] of leftEntries) {
|
for (const [stableOwnerId, leftAssignment] of leftEntries) {
|
||||||
const rightAssignment = right?.[stableOwnerId];
|
const rightAssignment = right?.[stableOwnerId];
|
||||||
if (
|
if (
|
||||||
!rightAssignment ||
|
rightAssignment?.ringIndex !== leftAssignment.ringIndex ||
|
||||||
rightAssignment.ringIndex !== leftAssignment.ringIndex ||
|
|
||||||
rightAssignment.sectorIndex !== leftAssignment.sectorIndex
|
rightAssignment.sectorIndex !== leftAssignment.sectorIndex
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2063,8 +2062,7 @@ export const createTeamSlice: StateCreator<AppState, [], [], TeamSlice> = (set,
|
||||||
return (
|
return (
|
||||||
(nextAssignment.ringIndex === assignment.ringIndex &&
|
(nextAssignment.ringIndex === assignment.ringIndex &&
|
||||||
nextAssignment.sectorIndex === assignment.sectorIndex) ||
|
nextAssignment.sectorIndex === assignment.sectorIndex) ||
|
||||||
(displacedAssignment != null &&
|
(nextAssignment.ringIndex === displacedAssignment?.ringIndex &&
|
||||||
nextAssignment.ringIndex === displacedAssignment.ringIndex &&
|
|
||||||
nextAssignment.sectorIndex === displacedAssignment.sectorIndex)
|
nextAssignment.sectorIndex === displacedAssignment.sectorIndex)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { formatTeamModelSummary } from '@renderer/components/team/dialogs/TeamModelSelector';
|
import { formatTeamModelSummary } from '@renderer/components/team/dialogs/TeamModelSelector';
|
||||||
|
import { inferTeamProviderIdFromModel } from '@shared/utils/teamProvider';
|
||||||
|
|
||||||
import type { TeamLaunchParams } from '@renderer/store/slices/teamSlice';
|
import type { TeamLaunchParams } from '@renderer/store/slices/teamSlice';
|
||||||
import type { MemberSpawnStatusEntry, ResolvedTeamMember, TeamProviderId } from '@shared/types';
|
import type { MemberSpawnStatusEntry, ResolvedTeamMember, TeamProviderId } from '@shared/types';
|
||||||
import { inferTeamProviderIdFromModel } from '@shared/utils/teamProvider';
|
|
||||||
|
|
||||||
function isMemberLaunchPending(spawnEntry: MemberSpawnStatusEntry | undefined): boolean {
|
function isMemberLaunchPending(spawnEntry: MemberSpawnStatusEntry | undefined): boolean {
|
||||||
if (!spawnEntry) {
|
if (!spawnEntry) {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import { getSkillAudienceLabel, isSkillAvailableForProvider } from '@shared/util
|
||||||
import { isSupportedSlashCommandName } from '@shared/utils/slashCommands';
|
import { isSupportedSlashCommandName } from '@shared/utils/slashCommands';
|
||||||
|
|
||||||
import type { MentionSuggestion } from '@renderer/types/mention';
|
import type { MentionSuggestion } from '@renderer/types/mention';
|
||||||
import type { SkillCatalogItem } from '@shared/types/extensions';
|
|
||||||
import type { TeamProviderId } from '@shared/types';
|
import type { TeamProviderId } from '@shared/types';
|
||||||
|
import type { SkillCatalogItem } from '@shared/types/extensions';
|
||||||
import type { KnownSlashCommandDefinition } from '@shared/utils/slashCommands';
|
import type { KnownSlashCommandDefinition } from '@shared/utils/slashCommands';
|
||||||
|
|
||||||
function orderSkillsForProvider(
|
function orderSkillsForProvider(
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,22 @@
|
||||||
|
import {
|
||||||
|
getProviderScopedTeamModelLabel,
|
||||||
|
getRuntimeAwareTeamModelUiDisabledReason,
|
||||||
|
getTeamProviderLabel,
|
||||||
|
getTeamProviderModelOptions,
|
||||||
|
getVisibleTeamProviderModels,
|
||||||
|
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
||||||
|
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||||
|
GPT_5_1_CODEX_MINI_UI_DISABLED_REASON,
|
||||||
|
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
||||||
|
GPT_5_2_CODEX_UI_DISABLED_REASON,
|
||||||
|
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
||||||
|
GPT_5_3_CODEX_SPARK_UI_DISABLED_REASON,
|
||||||
|
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
||||||
|
sortTeamProviderModels,
|
||||||
|
TEAM_MODEL_UI_DISABLED_BADGE_LABEL,
|
||||||
|
type TeamProviderModelOption,
|
||||||
|
} from './teamModelCatalog';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
CliProviderId,
|
CliProviderId,
|
||||||
CliProviderModelAvailability,
|
CliProviderModelAvailability,
|
||||||
|
|
@ -6,29 +25,10 @@ import type {
|
||||||
TeamProviderId,
|
TeamProviderId,
|
||||||
} from '@shared/types';
|
} from '@shared/types';
|
||||||
|
|
||||||
import {
|
|
||||||
getProviderScopedTeamModelLabel,
|
|
||||||
getRuntimeAwareTeamModelUiDisabledReason,
|
|
||||||
getTeamProviderLabel,
|
|
||||||
getTeamProviderModelOptions,
|
|
||||||
sortTeamProviderModels,
|
|
||||||
getVisibleTeamProviderModels,
|
|
||||||
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
|
||||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
|
||||||
GPT_5_1_CODEX_MINI_UI_DISABLED_REASON,
|
|
||||||
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
|
||||||
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
|
||||||
GPT_5_2_CODEX_UI_DISABLED_REASON,
|
|
||||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
|
||||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_REASON,
|
|
||||||
TEAM_MODEL_UI_DISABLED_BADGE_LABEL,
|
|
||||||
type TeamProviderModelOption,
|
|
||||||
} from './teamModelCatalog';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
||||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||||
GPT_5_1_CODEX_MINI_UI_DISABLED_REASON,
|
GPT_5_1_CODEX_MINI_UI_DISABLED_REASON,
|
||||||
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
|
||||||
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
||||||
GPT_5_2_CODEX_UI_DISABLED_REASON,
|
GPT_5_2_CODEX_UI_DISABLED_REASON,
|
||||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import type { CliProviderId, CliProviderStatus, TeamProviderId } from '@shared/types';
|
|
||||||
import {
|
import {
|
||||||
filterVisibleProviderRuntimeModels,
|
filterVisibleProviderRuntimeModels,
|
||||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||||
|
|
@ -6,6 +5,8 @@ import {
|
||||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
||||||
} from '@shared/utils/providerModelVisibility';
|
} from '@shared/utils/providerModelVisibility';
|
||||||
|
|
||||||
|
import type { CliProviderId, CliProviderStatus, TeamProviderId } from '@shared/types';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||||
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@ import {
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
CliInstallationStatus,
|
CliInstallationStatus,
|
||||||
InstallScope,
|
|
||||||
InstalledMcpEntry,
|
InstalledMcpEntry,
|
||||||
InstalledPluginEntry,
|
InstalledPluginEntry,
|
||||||
|
InstallScope,
|
||||||
PluginCapability,
|
PluginCapability,
|
||||||
PluginCatalogItem,
|
PluginCatalogItem,
|
||||||
} from '@shared/types';
|
} from '@shared/types';
|
||||||
|
|
@ -206,7 +206,7 @@ export function getPreferredMcpInstallationEntry(
|
||||||
|
|
||||||
return [...installations].sort(
|
return [...installations].sort(
|
||||||
(left, right) => MCP_SCOPE_PRIORITY[left.scope] - MCP_SCOPE_PRIORITY[right.scope]
|
(left, right) => MCP_SCOPE_PRIORITY[left.scope] - MCP_SCOPE_PRIORITY[right.scope]
|
||||||
)[0]!;
|
)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ describe('CliInstallerService', () => {
|
||||||
verificationState: 'verified',
|
verificationState: 'verified',
|
||||||
modelVerificationState: 'idle',
|
modelVerificationState: 'idle',
|
||||||
statusMessage: null,
|
statusMessage: null,
|
||||||
models: ['gpt-5.4', 'gpt-5.2-codex'],
|
models: ['gpt-5.4', 'gpt-5.4-mini'],
|
||||||
modelAvailability: [],
|
modelAvailability: [],
|
||||||
canLoginFromUi: true,
|
canLoginFromUi: true,
|
||||||
capabilities: { teamLaunch: true, oneShot: true },
|
capabilities: { teamLaunch: true, oneShot: true },
|
||||||
|
|
@ -267,14 +267,12 @@ describe('CliInstallerService', () => {
|
||||||
if (normalizedArgs === '--version') {
|
if (normalizedArgs === '--version') {
|
||||||
return { stdout: '2.3.4', stderr: '' };
|
return { stdout: '2.3.4', stderr: '' };
|
||||||
}
|
}
|
||||||
|
if (normalizedArgs.includes('--model gpt-5.4-mini')) {
|
||||||
|
throw new Error("The 'gpt-5.4-mini' model is not supported in this Codex runtime.");
|
||||||
|
}
|
||||||
if (normalizedArgs.includes('--model gpt-5.4')) {
|
if (normalizedArgs.includes('--model gpt-5.4')) {
|
||||||
return { stdout: 'PONG', stderr: '' };
|
return { stdout: 'PONG', stderr: '' };
|
||||||
}
|
}
|
||||||
if (normalizedArgs.includes('--model gpt-5.2-codex')) {
|
|
||||||
throw new Error(
|
|
||||||
"The 'gpt-5.2-codex' model is not supported when using Codex with a ChatGPT account."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
throw new Error(`Unexpected execCli call: ${normalizedArgs}`);
|
throw new Error(`Unexpected execCli call: ${normalizedArgs}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -291,7 +289,7 @@ describe('CliInstallerService', () => {
|
||||||
expect(verifiedProvider?.modelAvailability).toEqual(
|
expect(verifiedProvider?.modelAvailability).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({ modelId: 'gpt-5.4', status: 'checking' }),
|
expect.objectContaining({ modelId: 'gpt-5.4', status: 'checking' }),
|
||||||
expect.objectContaining({ modelId: 'gpt-5.2-codex', status: 'checking' }),
|
expect.objectContaining({ modelId: 'gpt-5.4-mini', status: 'checking' }),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -303,7 +301,7 @@ describe('CliInstallerService', () => {
|
||||||
expect(latestCodexProvider?.modelAvailability).toEqual([
|
expect(latestCodexProvider?.modelAvailability).toEqual([
|
||||||
expect.objectContaining({ modelId: 'gpt-5.4', status: 'available' }),
|
expect.objectContaining({ modelId: 'gpt-5.4', status: 'available' }),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
modelId: 'gpt-5.2-codex',
|
modelId: 'gpt-5.4-mini',
|
||||||
status: 'unavailable',
|
status: 'unavailable',
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ interface StoreState {
|
||||||
installed?: boolean;
|
installed?: boolean;
|
||||||
binaryPath?: string | null;
|
binaryPath?: string | null;
|
||||||
launchError?: string | null;
|
launchError?: string | null;
|
||||||
};
|
} | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeState = {} as StoreState;
|
const storeState = {} as StoreState;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import type { CliInstallationStatus } from '@shared/types';
|
import type { CliInstallationStatus } from '@shared/types';
|
||||||
import type { SkillCatalogItem } from '@shared/types/extensions';
|
import type { SkillCatalogItem } from '@shared/types/extensions';
|
||||||
|
import { createDefaultCliExtensionCapabilities } from '@shared/utils/providerExtensionCapabilities';
|
||||||
|
|
||||||
interface StoreState {
|
interface StoreState {
|
||||||
fetchSkillsCatalog: ReturnType<typeof vi.fn>;
|
fetchSkillsCatalog: ReturnType<typeof vi.fn>;
|
||||||
|
|
@ -213,12 +214,9 @@ function makeMultimodelStatus(
|
||||||
capabilities: {
|
capabilities: {
|
||||||
teamLaunch: true,
|
teamLaunch: true,
|
||||||
oneShot: true,
|
oneShot: true,
|
||||||
extensions: {
|
extensions: createDefaultCliExtensionCapabilities({
|
||||||
plugins: { status: 'supported', ownership: 'provider', reason: null },
|
plugins: { status: 'supported', ownership: 'provider-scoped', reason: null },
|
||||||
mcp: { status: 'supported', ownership: 'shared', reason: null },
|
}),
|
||||||
skills: { status: 'supported', ownership: 'shared', reason: null },
|
|
||||||
apiKeys: { status: 'supported', ownership: 'shared', reason: null },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
connection: null,
|
connection: null,
|
||||||
backend: null,
|
backend: null,
|
||||||
|
|
@ -405,12 +403,9 @@ describe('SkillsPanel', () => {
|
||||||
capabilities: {
|
capabilities: {
|
||||||
teamLaunch: true,
|
teamLaunch: true,
|
||||||
oneShot: true,
|
oneShot: true,
|
||||||
extensions: {
|
extensions: createDefaultCliExtensionCapabilities({
|
||||||
plugins: { status: 'unsupported', ownership: 'provider', reason: null },
|
plugins: { status: 'unsupported', ownership: 'provider-scoped', reason: null },
|
||||||
mcp: { status: 'supported', ownership: 'shared', reason: null },
|
}),
|
||||||
skills: { status: 'supported', ownership: 'shared', reason: null },
|
|
||||||
apiKeys: { status: 'supported', ownership: 'shared', reason: null },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
connection: null,
|
connection: null,
|
||||||
backend: null,
|
backend: null,
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,14 @@ vi.mock('../../../src/renderer/api', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { api } from '../../../src/renderer/api';
|
import { api } from '../../../src/renderer/api';
|
||||||
|
import type { CliInstallationStatus } from '../../../src/shared/types';
|
||||||
import {
|
import {
|
||||||
getMcpDiagnosticKey,
|
getMcpDiagnosticKey,
|
||||||
getMcpProjectStateKey,
|
getMcpProjectStateKey,
|
||||||
getMcpOperationKey,
|
getMcpOperationKey,
|
||||||
getPluginOperationKey,
|
getPluginOperationKey,
|
||||||
} from '../../../src/shared/utils/extensionNormalizers';
|
} from '../../../src/shared/utils/extensionNormalizers';
|
||||||
|
import { createDefaultCliExtensionCapabilities } from '../../../src/shared/utils/providerExtensionCapabilities';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
EnrichedPlugin,
|
EnrichedPlugin,
|
||||||
|
|
@ -137,7 +139,7 @@ const makeSkillDetail = (overrides: Partial<SkillDetail> = {}): SkillDetail => (
|
||||||
...overrides,
|
...overrides,
|
||||||
});
|
});
|
||||||
|
|
||||||
const makeReadyCliStatus = () => ({
|
const makeReadyCliStatus = (): CliInstallationStatus => ({
|
||||||
flavor: 'claude' as const,
|
flavor: 'claude' as const,
|
||||||
displayName: 'Claude',
|
displayName: 'Claude',
|
||||||
supportsSelfUpdate: true,
|
supportsSelfUpdate: true,
|
||||||
|
|
@ -154,7 +156,10 @@ const makeReadyCliStatus = () => ({
|
||||||
providers: [],
|
providers: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const makeLimitedMultimodelCliStatus = (section: 'plugins' | 'mcp', reason: string) => ({
|
const makeLimitedMultimodelCliStatus = (
|
||||||
|
section: 'plugins' | 'mcp',
|
||||||
|
reason: string
|
||||||
|
): CliInstallationStatus => ({
|
||||||
flavor: 'agent_teams_orchestrator' as const,
|
flavor: 'agent_teams_orchestrator' as const,
|
||||||
displayName: 'Claude Multimodel',
|
displayName: 'Claude Multimodel',
|
||||||
supportsSelfUpdate: false,
|
supportsSelfUpdate: false,
|
||||||
|
|
@ -181,21 +186,22 @@ const makeLimitedMultimodelCliStatus = (section: 'plugins' | 'mcp', reason: stri
|
||||||
capabilities: {
|
capabilities: {
|
||||||
teamLaunch: true,
|
teamLaunch: true,
|
||||||
oneShot: true,
|
oneShot: true,
|
||||||
extensions: {
|
extensions: createDefaultCliExtensionCapabilities({
|
||||||
plugins: {
|
plugins: {
|
||||||
status: section === 'plugins' ? 'unsupported' : 'supported',
|
status: section === 'plugins' ? 'unsupported' : 'supported',
|
||||||
ownership: 'shared' as const,
|
ownership: 'shared',
|
||||||
reason: section === 'plugins' ? reason : null,
|
reason: section === 'plugins' ? reason : null,
|
||||||
},
|
},
|
||||||
mcp: {
|
mcp: {
|
||||||
status: section === 'mcp' ? 'read-only' : 'supported',
|
status: section === 'mcp' ? 'read-only' : 'supported',
|
||||||
ownership: 'shared' as const,
|
ownership: 'shared',
|
||||||
reason: section === 'mcp' ? reason : null,
|
reason: section === 'mcp' ? reason : null,
|
||||||
},
|
},
|
||||||
skills: { status: 'supported', ownership: 'shared' as const, reason: null },
|
}),
|
||||||
apiKeys: { status: 'supported', ownership: 'shared' as const, reason: null },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
statusMessage: null,
|
||||||
|
connection: null,
|
||||||
|
backend: null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import {
|
||||||
} from '@renderer/utils/multimodelProviderVisibility';
|
} from '@renderer/utils/multimodelProviderVisibility';
|
||||||
|
|
||||||
import type { CliInstallationStatus, CliProviderStatus } from '@shared/types';
|
import type { CliInstallationStatus, CliProviderStatus } from '@shared/types';
|
||||||
|
import { createDefaultCliExtensionCapabilities } from '@shared/utils/providerExtensionCapabilities';
|
||||||
|
|
||||||
function createProvider(providerId: CliProviderStatus['providerId']): CliProviderStatus {
|
function createProvider(providerId: CliProviderStatus['providerId']): CliProviderStatus {
|
||||||
return {
|
return {
|
||||||
|
|
@ -21,9 +22,9 @@ function createProvider(providerId: CliProviderStatus['providerId']): CliProvide
|
||||||
capabilities: {
|
capabilities: {
|
||||||
teamLaunch: true,
|
teamLaunch: true,
|
||||||
oneShot: true,
|
oneShot: true,
|
||||||
|
extensions: createDefaultCliExtensionCapabilities(),
|
||||||
},
|
},
|
||||||
statusMessage: null,
|
statusMessage: null,
|
||||||
detailMessage: null,
|
|
||||||
selectedBackendId: null,
|
selectedBackendId: null,
|
||||||
resolvedBackendId: null,
|
resolvedBackendId: null,
|
||||||
availableBackends: [],
|
availableBackends: [],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue