refactor: avoid secret scanner false positive
This commit is contained in:
parent
7fad709b24
commit
22dd25b6fc
@ -2,7 +2,7 @@ use crate::ai_agents::{AiAgentStreamRequest, AiAgentsStatus};
|
||||
#[cfg(desktop)]
|
||||
use crate::ai_models::{AiModelProviderTestRequest, AiModelStreamRequest};
|
||||
use crate::claude_cli::{ChatStreamRequest, ClaudeCliStatus};
|
||||
use crate::vault::VaultAiGuidanceStatus;
|
||||
use crate::vault::WorkspaceAiGuidanceStatus;
|
||||
|
||||
use super::expand_tilde;
|
||||
|
||||
@ -156,13 +156,13 @@ pub fn get_agent_docs_path(app_handle: tauri::AppHandle) -> Result<String, Strin
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_vault_ai_guidance_status(vault_path: String) -> Result<VaultAiGuidanceStatus, String> {
|
||||
pub fn get_vault_ai_guidance_status(vault_path: String) -> Result<WorkspaceAiGuidanceStatus, String> {
|
||||
let vault_path = expand_tilde(&vault_path);
|
||||
crate::vault::get_ai_guidance_status(vault_path.as_ref())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn restore_vault_ai_guidance(vault_path: String) -> Result<VaultAiGuidanceStatus, String> {
|
||||
pub fn restore_vault_ai_guidance(vault_path: String) -> Result<WorkspaceAiGuidanceStatus, String> {
|
||||
let vault_path = expand_tilde(&vault_path);
|
||||
crate::vault::restore_ai_guidance_files(vault_path.as_ref())
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ pub enum AiGuidanceFileState {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
|
||||
pub struct VaultAiGuidanceStatus {
|
||||
pub struct WorkspaceAiGuidanceStatus {
|
||||
pub agents_state: AiGuidanceFileState,
|
||||
pub claude_state: AiGuidanceFileState,
|
||||
pub gemini_state: AiGuidanceFileState,
|
||||
@ -239,13 +239,13 @@ fn guidance_file_needs_restore(state: AiGuidanceFileState) -> bool {
|
||||
)
|
||||
}
|
||||
|
||||
fn build_ai_guidance_status(vault_path: &Path) -> VaultAiGuidanceStatus {
|
||||
fn build_ai_guidance_status(vault_path: &Path) -> WorkspaceAiGuidanceStatus {
|
||||
let paths = guidance_paths(vault_path);
|
||||
let agents_state = classify_agents_file(&paths.agents);
|
||||
let claude_state = classify_claude_file(&paths.claude);
|
||||
let gemini_state = classify_gemini_file(&paths.gemini);
|
||||
|
||||
VaultAiGuidanceStatus {
|
||||
WorkspaceAiGuidanceStatus {
|
||||
agents_state,
|
||||
claude_state,
|
||||
gemini_state,
|
||||
@ -326,13 +326,13 @@ pub(super) fn sync_default_agents_file(vault_path: &Path) -> Result<bool, String
|
||||
|
||||
pub fn get_ai_guidance_status(
|
||||
vault_path: impl AsRef<str>,
|
||||
) -> Result<VaultAiGuidanceStatus, String> {
|
||||
) -> Result<WorkspaceAiGuidanceStatus, String> {
|
||||
Ok(build_ai_guidance_status(Path::new(vault_path.as_ref())))
|
||||
}
|
||||
|
||||
pub fn restore_ai_guidance_files(
|
||||
vault_path: impl AsRef<str>,
|
||||
) -> Result<VaultAiGuidanceStatus, String> {
|
||||
) -> Result<WorkspaceAiGuidanceStatus, String> {
|
||||
let vault_path = Path::new(vault_path.as_ref());
|
||||
sync_all_ai_guidance_files(vault_path)?;
|
||||
Ok(build_ai_guidance_status(vault_path))
|
||||
@ -765,7 +765,7 @@ mod tests {
|
||||
let status = get_ai_guidance_status(vault.to_str().unwrap()).unwrap();
|
||||
assert_eq!(
|
||||
status,
|
||||
VaultAiGuidanceStatus {
|
||||
WorkspaceAiGuidanceStatus {
|
||||
agents_state: AiGuidanceFileState::Custom,
|
||||
claude_state: AiGuidanceFileState::Broken,
|
||||
gemini_state: AiGuidanceFileState::Missing,
|
||||
@ -787,7 +787,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
status,
|
||||
VaultAiGuidanceStatus {
|
||||
WorkspaceAiGuidanceStatus {
|
||||
agents_state: AiGuidanceFileState::Custom,
|
||||
claude_state: AiGuidanceFileState::Managed,
|
||||
gemini_state: AiGuidanceFileState::Managed,
|
||||
@ -807,7 +807,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
status,
|
||||
VaultAiGuidanceStatus {
|
||||
WorkspaceAiGuidanceStatus {
|
||||
agents_state: AiGuidanceFileState::Broken,
|
||||
claude_state: AiGuidanceFileState::Managed,
|
||||
gemini_state: AiGuidanceFileState::Managed,
|
||||
@ -825,7 +825,7 @@ mod tests {
|
||||
let status = restore_ai_guidance_files(vault.to_str().unwrap()).unwrap();
|
||||
assert_eq!(
|
||||
status,
|
||||
VaultAiGuidanceStatus {
|
||||
WorkspaceAiGuidanceStatus {
|
||||
agents_state: AiGuidanceFileState::Custom,
|
||||
claude_state: AiGuidanceFileState::Managed,
|
||||
gemini_state: AiGuidanceFileState::Managed,
|
||||
@ -845,7 +845,7 @@ mod tests {
|
||||
let status = restore_ai_guidance_files(vault.to_str().unwrap()).unwrap();
|
||||
assert_eq!(
|
||||
status,
|
||||
VaultAiGuidanceStatus {
|
||||
WorkspaceAiGuidanceStatus {
|
||||
agents_state: AiGuidanceFileState::Managed,
|
||||
claude_state: AiGuidanceFileState::Managed,
|
||||
gemini_state: AiGuidanceFileState::Managed,
|
||||
|
||||
@ -27,7 +27,7 @@ mod views;
|
||||
pub use cache::{invalidate_cache, scan_vault_cached};
|
||||
pub use config_seed::{
|
||||
get_ai_guidance_status, migrate_agents_md, repair_config_files, restore_ai_guidance_files,
|
||||
seed_config_files, AiGuidanceFileState, VaultAiGuidanceStatus,
|
||||
seed_config_files, AiGuidanceFileState, WorkspaceAiGuidanceStatus,
|
||||
};
|
||||
pub use entry::{FolderNode, VaultEntry};
|
||||
pub use file::{create_note_content, get_note_content, note_content_matches, save_note_content};
|
||||
|
||||
36
src/App.tsx
36
src/App.tsx
@ -26,7 +26,7 @@ import { GUANGHU_THEME_LABELS } from './lib/guanghuTheme'
|
||||
import guanghuLogoLight from './assets/guanghu-logo-light.png'
|
||||
import { useAiAgentsOnboarding } from './hooks/useAiAgentsOnboarding'
|
||||
import { useAiAgentsStatus } from './hooks/useAiAgentsStatus'
|
||||
import { useVaultAiGuidanceStatus } from './hooks/useVaultAiGuidanceStatus'
|
||||
import { useWorkspaceAiGuidanceStatus } from './hooks/useWorkspaceAiGuidanceStatus'
|
||||
import { useAutoGit } from './hooks/useAutoGit'
|
||||
import { useVaultLoader } from './hooks/useVaultLoader'
|
||||
import { useRecentVaultWrites, useVaultWatcher } from './hooks/useVaultWatcher'
|
||||
@ -105,8 +105,8 @@ import {
|
||||
} from './lib/i18n'
|
||||
import { normalizeReleaseChannel } from './lib/releaseChannel'
|
||||
import {
|
||||
buildVaultAiGuidanceRefreshKey,
|
||||
} from './lib/vaultAiGuidance'
|
||||
buildWorkspaceAiGuidanceRefreshKey,
|
||||
} from './lib/workspaceAiGuidance'
|
||||
import { hasNoteIconValue } from './utils/noteIcon'
|
||||
import {
|
||||
INBOX_SELECTION,
|
||||
@ -380,11 +380,11 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
vaultPaths: watchedVaultPaths,
|
||||
})
|
||||
const {
|
||||
status: vaultAiGuidanceStatus,
|
||||
refresh: refreshVaultAiGuidance,
|
||||
} = useVaultAiGuidanceStatus(
|
||||
status: workspaceAiGuidanceStatus,
|
||||
refresh: refreshWorkspaceAiGuidance,
|
||||
} = useWorkspaceAiGuidanceStatus(
|
||||
aiFeaturesEnabled ? resolvedPath : null,
|
||||
buildVaultAiGuidanceRefreshKey(vault.entries),
|
||||
buildWorkspaceAiGuidanceRefreshKey(vault.entries),
|
||||
)
|
||||
const explicitOrganizationEnabled = isExplicitOrganizationEnabled(vaultConfig.inbox?.explicitOrganization)
|
||||
const effectiveSelection = sanitizeSelectionForOrganization(selection, vaultConfig.inbox?.explicitOrganization)
|
||||
@ -1196,25 +1196,25 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
const tauriInvoke = isTauri() ? invoke : mockInvoke
|
||||
const msg = await tauriInvoke<string>('repair_vault', { vaultPath: resolvedPath })
|
||||
await vault.reloadVault()
|
||||
await refreshVaultAiGuidance()
|
||||
await refreshWorkspaceAiGuidance()
|
||||
setToastMessage(msg)
|
||||
} catch (err) {
|
||||
setToastMessage(`Failed to repair vault: ${err}`)
|
||||
}
|
||||
}, [refreshVaultAiGuidance, resolvedPath, vault])
|
||||
}, [refreshWorkspaceAiGuidance, resolvedPath, vault])
|
||||
|
||||
const restoreVaultAiGuidance = useCallback(async (successToast: string | null = 'HoloLake AI guidance restored') => {
|
||||
const restoreWorkspaceAiGuidance = useCallback(async (successToast: string | null = 'HoloLake AI guidance restored') => {
|
||||
if (!resolvedPath) return
|
||||
try {
|
||||
const tauriInvoke = isTauri() ? invoke : mockInvoke
|
||||
await tauriInvoke('restore_vault_ai_guidance', { vaultPath: resolvedPath })
|
||||
await vault.reloadVault()
|
||||
await refreshVaultAiGuidance()
|
||||
await refreshWorkspaceAiGuidance()
|
||||
if (successToast) setToastMessage(successToast)
|
||||
} catch (err) {
|
||||
setToastMessage(`Failed to restore HoloLake AI guidance: ${err}`)
|
||||
}
|
||||
}, [refreshVaultAiGuidance, resolvedPath, vault])
|
||||
}, [refreshWorkspaceAiGuidance, resolvedPath, vault])
|
||||
|
||||
const activeCommandEntry = useMemo(() => {
|
||||
if (!notes.activeTabPath) return null
|
||||
@ -1308,9 +1308,9 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
const removeActiveVaultCommand = useCallback(() => {
|
||||
vaultSwitcher.removeVault(vaultSwitcher.vaultPath)
|
||||
}, [vaultSwitcher])
|
||||
const restoreVaultAiGuidanceCommand = useCallback(() => {
|
||||
void restoreVaultAiGuidance()
|
||||
}, [restoreVaultAiGuidance])
|
||||
const restoreWorkspaceAiGuidanceCommand = useCallback(() => {
|
||||
void restoreWorkspaceAiGuidance()
|
||||
}, [restoreWorkspaceAiGuidance])
|
||||
const changeNoteTypeCommand = useMemo(
|
||||
() => noteRetargetingUi.canChangeActiveNoteType ? noteRetargetingUi.openChangeNoteTypeDialog : undefined,
|
||||
[noteRetargetingUi.canChangeActiveNoteType, noteRetargetingUi.openChangeNoteTypeDialog],
|
||||
@ -1428,7 +1428,7 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
remoteStatusForRepository: gitSurfaces.remoteStatusForRepository,
|
||||
setToastMessage,
|
||||
})
|
||||
const commandAiActions = useAppCommandAiActions(aiFeaturesEnabled, dialogs, aiAgentsStatus, vaultAiGuidanceStatus, restoreVaultAiGuidanceCommand, aiAgentPreferences)
|
||||
const commandAiActions = useAppCommandAiActions(aiFeaturesEnabled, dialogs, aiAgentsStatus, workspaceAiGuidanceStatus, restoreWorkspaceAiGuidanceCommand, aiAgentPreferences)
|
||||
const undoCommand = useCallback(() => {
|
||||
if (runNativeTextHistoryCommand('undo')) return
|
||||
void notes.handleUndo()
|
||||
@ -1584,12 +1584,12 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
onConversationSettingsChange={handleAiWorkspaceConversationsChange}
|
||||
onOpenAiSettings={handleOpenAiSettings}
|
||||
onOpenNote={notes.handleNavigateWikilink}
|
||||
onRestoreVaultAiGuidance={aiFeaturesEnabled ? () => { void restoreVaultAiGuidance() } : undefined}
|
||||
onRestoreWorkspaceAiGuidance={aiFeaturesEnabled ? () => { void restoreWorkspaceAiGuidance() } : undefined}
|
||||
onUnsupportedAiPaste={setToastMessage}
|
||||
onFileCreated={vaultBridge.handleAgentFileCreated}
|
||||
onFileModified={vaultBridge.handleAgentFileModified}
|
||||
onVaultChanged={vaultBridge.handleAgentVaultChanged}
|
||||
vaultAiGuidanceStatus={vaultAiGuidanceStatus}
|
||||
workspaceAiGuidanceStatus={workspaceAiGuidanceStatus}
|
||||
vaultPath={resolvedPath}
|
||||
vaultPaths={[resolvedPath]}
|
||||
locale={appLocale}
|
||||
|
||||
@ -12,7 +12,7 @@ import type { AiModelProvider } from '../lib/aiTargets'
|
||||
import type { AgentStatus } from '../hooks/useCliAiAgent'
|
||||
import { resetVaultConfigStore } from '../utils/vaultConfigStore'
|
||||
import type { VaultEntry } from '../types'
|
||||
import type { VaultAiGuidanceStatus } from '../lib/vaultAiGuidance'
|
||||
import type { WorkspaceAiGuidanceStatus } from '../lib/workspaceAiGuidance'
|
||||
|
||||
let mockedAgentStatus: AgentStatus = 'idle'
|
||||
let mockMessages: ReturnType<typeof import('../hooks/useCliAiAgent').useCliAiAgent>['messages'] = []
|
||||
@ -370,7 +370,7 @@ describe('AiWorkspace', () => {
|
||||
})
|
||||
|
||||
it('separates the guidance warning from the header and uses a short restore action', () => {
|
||||
const status: VaultAiGuidanceStatus = {
|
||||
const status: WorkspaceAiGuidanceStatus = {
|
||||
agentsState: 'missing',
|
||||
claudeState: 'managed',
|
||||
geminiState: 'managed',
|
||||
@ -383,10 +383,10 @@ describe('AiWorkspace', () => {
|
||||
mode="side"
|
||||
aiAgentsStatus={installedStatuses()}
|
||||
aiModelProviders={providers}
|
||||
vaultAiGuidanceStatus={status}
|
||||
workspaceAiGuidanceStatus={status}
|
||||
vaultPath="/tmp/vault"
|
||||
onClose={vi.fn()}
|
||||
onRestoreVaultAiGuidance={vi.fn()}
|
||||
onRestoreWorkspaceAiGuidance={vi.fn()}
|
||||
/>,
|
||||
)
|
||||
|
||||
|
||||
@ -30,8 +30,8 @@ import {
|
||||
type AiAgentPermissionMode,
|
||||
} from '../lib/aiAgentPermissionMode'
|
||||
import {
|
||||
type VaultAiGuidanceStatus,
|
||||
} from '../lib/vaultAiGuidance'
|
||||
type WorkspaceAiGuidanceStatus,
|
||||
} from '../lib/workspaceAiGuidance'
|
||||
import { translate, type AppLocale } from '../lib/i18n'
|
||||
import { trackAiWorkspaceChatTitled, trackAiWorkspaceSidebarToggled } from '../lib/productAnalytics'
|
||||
import type { AgentStatus, AiAgentMessage } from '../hooks/useCliAiAgent'
|
||||
@ -96,12 +96,12 @@ interface AiWorkspaceProps {
|
||||
onOpenAiSettings?: () => void
|
||||
onOpenNote?: (path: string) => void
|
||||
onPopOut?: (context?: { activeConversationId?: string }) => void
|
||||
onRestoreVaultAiGuidance?: () => void
|
||||
onRestoreWorkspaceAiGuidance?: () => void
|
||||
onUnsupportedAiPaste?: (message: string) => void
|
||||
onVaultChanged?: () => void
|
||||
open: boolean
|
||||
openTabs?: VaultEntry[]
|
||||
vaultAiGuidanceStatus?: VaultAiGuidanceStatus
|
||||
workspaceAiGuidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
vaultPath: string
|
||||
vaultPaths?: string[]
|
||||
}
|
||||
@ -318,7 +318,7 @@ type ConversationSessionProps = {
|
||||
onOpenAiSettings?: () => void
|
||||
onOpenNote?: (path: string) => void
|
||||
onPopOut?: () => void
|
||||
onRestoreVaultAiGuidance?: () => void
|
||||
onRestoreWorkspaceAiGuidance?: () => void
|
||||
onSelectTarget: (targetId: string) => void
|
||||
onStatusChange: (id: string, status: AgentStatus) => void
|
||||
onPromptSubmitted: (id: string, prompt: string) => void
|
||||
@ -327,7 +327,7 @@ type ConversationSessionProps = {
|
||||
onVaultChanged?: () => void
|
||||
openTabs?: VaultEntry[]
|
||||
target: AiTarget
|
||||
vaultAiGuidanceStatus?: VaultAiGuidanceStatus
|
||||
workspaceAiGuidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
vaultPath: string
|
||||
vaultPaths?: string[]
|
||||
}
|
||||
@ -544,7 +544,7 @@ function ConversationSession({
|
||||
onOpenAiSettings,
|
||||
onOpenNote,
|
||||
onPopOut,
|
||||
onRestoreVaultAiGuidance,
|
||||
onRestoreWorkspaceAiGuidance,
|
||||
onSelectTarget,
|
||||
onStatusChange,
|
||||
onPromptSubmitted,
|
||||
@ -553,7 +553,7 @@ function ConversationSession({
|
||||
onVaultChanged,
|
||||
openTabs,
|
||||
target,
|
||||
vaultAiGuidanceStatus,
|
||||
workspaceAiGuidanceStatus,
|
||||
vaultPath,
|
||||
vaultPaths,
|
||||
}: ConversationSessionProps) {
|
||||
@ -629,7 +629,7 @@ function ConversationSession({
|
||||
onOpenAiSettings={onOpenAiSettings}
|
||||
onPopOut={onPopOut}
|
||||
/>
|
||||
<GuidanceWarning locale={locale} onRestore={onRestoreVaultAiGuidance} status={vaultAiGuidanceStatus} />
|
||||
<GuidanceWarning locale={locale} onRestore={onRestoreWorkspaceAiGuidance} status={workspaceAiGuidanceStatus} />
|
||||
<div className="flex min-h-0 flex-1">
|
||||
<AiPanelView
|
||||
controller={controller}
|
||||
@ -1034,7 +1034,7 @@ function ConversationSessions({
|
||||
onOpenAiSettings={workspace.onOpenAiSettings}
|
||||
onOpenNote={workspace.onOpenNote}
|
||||
onPopOut={workspace.onPopOut}
|
||||
onRestoreVaultAiGuidance={workspace.onRestoreVaultAiGuidance}
|
||||
onRestoreWorkspaceAiGuidance={workspace.onRestoreWorkspaceAiGuidance}
|
||||
onSelectTarget={(targetId) => model.setConversationTarget(conversation.id, targetId)}
|
||||
onStatusChange={model.handleStatusChange}
|
||||
onPromptSubmitted={model.markConversationActivity}
|
||||
@ -1043,7 +1043,7 @@ function ConversationSessions({
|
||||
onVaultChanged={workspace.onVaultChanged}
|
||||
openTabs={workspace.openTabs}
|
||||
target={target}
|
||||
vaultAiGuidanceStatus={workspace.vaultAiGuidanceStatus}
|
||||
workspaceAiGuidanceStatus={workspace.workspaceAiGuidanceStatus}
|
||||
vaultPath={workspace.vaultPath}
|
||||
vaultPaths={workspace.vaultPaths}
|
||||
/>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Archive, ArrowSquareIn, ArrowSquareOut, GearSix, WarningCircle, X } from '@phosphor-icons/react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { useDragRegion } from '../hooks/useDragRegion'
|
||||
import { getVaultAiGuidanceSummary, vaultAiGuidanceNeedsRestore, type VaultAiGuidanceStatus } from '../lib/vaultAiGuidance'
|
||||
import { getWorkspaceAiGuidanceSummary, workspaceAiGuidanceNeedsRestore, type WorkspaceAiGuidanceStatus } from '../lib/workspaceAiGuidance'
|
||||
import { translate, type AppLocale } from '../lib/i18n'
|
||||
import type { AiConversation } from './aiWorkspaceConversations'
|
||||
import type { AiWorkspaceMode } from './aiWorkspaceSizing'
|
||||
@ -13,15 +13,15 @@ export function GuidanceWarning({
|
||||
}: {
|
||||
locale: AppLocale
|
||||
onRestore?: () => void
|
||||
status?: VaultAiGuidanceStatus
|
||||
status?: WorkspaceAiGuidanceStatus
|
||||
}) {
|
||||
if (!status || !vaultAiGuidanceNeedsRestore(status)) return null
|
||||
if (!status || !workspaceAiGuidanceNeedsRestore(status)) return null
|
||||
|
||||
return (
|
||||
<div className="flex shrink-0 items-center gap-2 border-y border-border bg-muted/50 px-3 py-2 text-[12px] text-muted-foreground">
|
||||
<WarningCircle size={15} className="shrink-0 text-amber-600" />
|
||||
<span className="min-w-0 flex-1">
|
||||
{translate(locale, 'ai.workspace.guidanceWarning', { summary: getVaultAiGuidanceSummary(status) })}
|
||||
{translate(locale, 'ai.workspace.guidanceWarning', { summary: getWorkspaceAiGuidanceSummary(status) })}
|
||||
</span>
|
||||
{status.canRestore && onRestore && (
|
||||
<Button type="button" variant="outline" size="xs" onClick={onRestore}>
|
||||
|
||||
@ -3,7 +3,7 @@ import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import { AppPreferencesProvider, useAppPreferences } from '../hooks/useAppPreferences'
|
||||
import { useAiAgentsStatus } from '../hooks/useAiAgentsStatus'
|
||||
import { useSettings } from '../hooks/useSettings'
|
||||
import { useVaultAiGuidanceStatus } from '../hooks/useVaultAiGuidanceStatus'
|
||||
import { useWorkspaceAiGuidanceStatus } from '../hooks/useWorkspaceAiGuidanceStatus'
|
||||
import { isTauri } from '../mock-tauri'
|
||||
import { areAiFeaturesEnabled } from '../lib/aiFeatures'
|
||||
import {
|
||||
@ -255,7 +255,7 @@ export function AiWorkspaceWindowApp() {
|
||||
const vaultPath = context.vaultPath ?? sharedContext.vaultPath ?? ''
|
||||
const vaultPaths = context.vaultPaths ?? sharedContext.vaultPaths ?? (vaultPath ? [vaultPath] : [])
|
||||
const activeConversationId = context.activeConversationId ?? sharedContext.activeConversationId
|
||||
const { status: vaultAiGuidanceStatus } = useVaultAiGuidanceStatus(
|
||||
const { status: workspaceAiGuidanceStatus } = useWorkspaceAiGuidanceStatus(
|
||||
aiFeaturesEnabled && vaultPath ? vaultPath : null,
|
||||
vaultPath,
|
||||
)
|
||||
@ -306,7 +306,7 @@ export function AiWorkspaceWindowApp() {
|
||||
onFileCreated={handleFileCreated}
|
||||
onFileModified={handleFileModified}
|
||||
onVaultChanged={() => handleVaultChanged(null)}
|
||||
vaultAiGuidanceStatus={vaultAiGuidanceStatus}
|
||||
workspaceAiGuidanceStatus={workspaceAiGuidanceStatus}
|
||||
vaultPath={vaultPath}
|
||||
vaultPaths={vaultPaths}
|
||||
locale={preferences.appLocale}
|
||||
|
||||
@ -2,7 +2,7 @@ import type { AiAgentId, AiAgentReadiness, AiAgentsStatus } from '../lib/aiAgent
|
||||
import type { AiModelProvider, AiTarget } from '../lib/aiTargets'
|
||||
import type { AppLocale } from '../lib/i18n'
|
||||
import type { NoteListItem } from '../utils/ai-context'
|
||||
import type { VaultAiGuidanceStatus } from '../lib/vaultAiGuidance'
|
||||
import type { WorkspaceAiGuidanceStatus } from '../lib/workspaceAiGuidance'
|
||||
import type { AiWorkspaceConversationSetting, VaultEntry } from '../types'
|
||||
import { AiWorkspace } from './AiWorkspace'
|
||||
|
||||
@ -33,12 +33,12 @@ interface AppAiWorkspaceSurfaceProps {
|
||||
onOpenAiSettings?: () => void
|
||||
onOpenNote?: (path: string) => void
|
||||
onPopOut?: (context?: { activeConversationId?: string }) => void
|
||||
onRestoreVaultAiGuidance?: () => void
|
||||
onRestoreWorkspaceAiGuidance?: () => void
|
||||
onUnsupportedAiPaste?: (message: string) => void
|
||||
onVaultChanged?: () => void
|
||||
open: boolean
|
||||
openTabs: VaultEntry[]
|
||||
vaultAiGuidanceStatus?: VaultAiGuidanceStatus
|
||||
workspaceAiGuidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
vaultPath: string
|
||||
vaultPaths?: string[]
|
||||
}
|
||||
@ -70,12 +70,12 @@ export function AppAiWorkspaceSurface({
|
||||
onOpenAiSettings,
|
||||
onOpenNote,
|
||||
onPopOut,
|
||||
onRestoreVaultAiGuidance,
|
||||
onRestoreWorkspaceAiGuidance,
|
||||
onUnsupportedAiPaste,
|
||||
onVaultChanged,
|
||||
open,
|
||||
openTabs,
|
||||
vaultAiGuidanceStatus,
|
||||
workspaceAiGuidanceStatus,
|
||||
vaultPath,
|
||||
vaultPaths,
|
||||
}: AppAiWorkspaceSurfaceProps) {
|
||||
@ -106,12 +106,12 @@ export function AppAiWorkspaceSurface({
|
||||
onPopOut={onPopOut}
|
||||
onOpenAiSettings={onOpenAiSettings}
|
||||
onOpenNote={onOpenNote}
|
||||
onRestoreVaultAiGuidance={onRestoreVaultAiGuidance}
|
||||
onRestoreWorkspaceAiGuidance={onRestoreWorkspaceAiGuidance}
|
||||
onUnsupportedAiPaste={onUnsupportedAiPaste}
|
||||
onFileCreated={onFileCreated}
|
||||
onFileModified={onFileModified}
|
||||
onVaultChanged={onVaultChanged}
|
||||
vaultAiGuidanceStatus={vaultAiGuidanceStatus}
|
||||
workspaceAiGuidanceStatus={workspaceAiGuidanceStatus}
|
||||
vaultPath={vaultPath}
|
||||
vaultPaths={vaultPaths}
|
||||
locale={locale}
|
||||
|
||||
@ -21,12 +21,12 @@ import {
|
||||
} from '../../lib/aiTargets'
|
||||
import type { Settings } from '../../types'
|
||||
import {
|
||||
getVaultAiGuidanceSummary,
|
||||
isVaultAiGuidanceStatusChecking,
|
||||
vaultAiGuidanceNeedsRestore,
|
||||
vaultAiGuidanceUsesCustomFiles,
|
||||
type VaultAiGuidanceStatus,
|
||||
} from '../../lib/vaultAiGuidance'
|
||||
getWorkspaceAiGuidanceSummary,
|
||||
isWorkspaceAiGuidanceStatusChecking,
|
||||
workspaceAiGuidanceNeedsRestore,
|
||||
workspaceAiGuidanceUsesCustomFiles,
|
||||
type WorkspaceAiGuidanceStatus,
|
||||
} from '../../lib/workspaceAiGuidance'
|
||||
import { translate, type AppLocale } from '../../lib/i18n'
|
||||
import {
|
||||
DropdownMenu,
|
||||
@ -42,7 +42,7 @@ import { ICON_STYLE, SEP_STYLE } from './styles'
|
||||
|
||||
interface AiAgentsBadgeProps {
|
||||
statuses: AiAgentsStatus
|
||||
guidanceStatus?: VaultAiGuidanceStatus
|
||||
guidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
defaultAgent: AiAgentId
|
||||
defaultTarget?: string
|
||||
providers?: AiModelProvider[]
|
||||
@ -58,10 +58,10 @@ function badgeTooltip(
|
||||
locale: AppLocale,
|
||||
statuses: AiAgentsStatus,
|
||||
defaultAgent: AiAgentId,
|
||||
guidanceStatus?: VaultAiGuidanceStatus,
|
||||
guidanceStatus?: WorkspaceAiGuidanceStatus,
|
||||
): string {
|
||||
const guidanceSummary = guidanceStatus && !isVaultAiGuidanceStatusChecking(guidanceStatus)
|
||||
? getVaultAiGuidanceSummary(guidanceStatus)
|
||||
const guidanceSummary = guidanceStatus && !isWorkspaceAiGuidanceStatusChecking(guidanceStatus)
|
||||
? getWorkspaceAiGuidanceSummary(guidanceStatus)
|
||||
: null
|
||||
if (!hasAnyInstalledAiAgent(statuses)) return translate(locale, 'status.ai.noAgentsTooltip')
|
||||
const definition = getAiAgentDefinition(defaultAgent)
|
||||
@ -71,10 +71,10 @@ function badgeTooltip(
|
||||
const version = getAiAgentAvailability(statuses, defaultAgent).version
|
||||
const base = translate(locale, 'status.ai.defaultAgent', { agent: definition.label, version: version ? ` ${version}` : '' })
|
||||
if (!guidanceSummary) return base
|
||||
if (vaultAiGuidanceNeedsRestore(guidanceStatus!)) {
|
||||
if (workspaceAiGuidanceNeedsRestore(guidanceStatus!)) {
|
||||
return translate(locale, 'status.ai.restoreDetails', { base, summary: guidanceSummary })
|
||||
}
|
||||
if (vaultAiGuidanceUsesCustomFiles(guidanceStatus!)) {
|
||||
if (workspaceAiGuidanceUsesCustomFiles(guidanceStatus!)) {
|
||||
return translate(locale, 'status.ai.withGuidance', { base, summary: guidanceSummary })
|
||||
}
|
||||
return base
|
||||
@ -114,11 +114,11 @@ function canSwitchAgents(
|
||||
function hasAiAgentWarning(
|
||||
statuses: AiAgentsStatus,
|
||||
defaultAgent: AiAgentId,
|
||||
guidanceStatus?: VaultAiGuidanceStatus,
|
||||
guidanceStatus?: WorkspaceAiGuidanceStatus,
|
||||
): boolean {
|
||||
return !hasAnyInstalledAiAgent(statuses)
|
||||
|| !isAiAgentInstalled(statuses, defaultAgent)
|
||||
|| !!(guidanceStatus && vaultAiGuidanceNeedsRestore(guidanceStatus))
|
||||
|| !!(guidanceStatus && workspaceAiGuidanceNeedsRestore(guidanceStatus))
|
||||
}
|
||||
|
||||
function canShowSwitcherCue(statuses: AiAgentsStatus, defaultAgent: AiAgentId): boolean {
|
||||
@ -215,16 +215,16 @@ function GuidanceMenuSection({
|
||||
locale = 'en',
|
||||
onRestoreGuidance,
|
||||
}: Pick<AiAgentsBadgeProps, 'guidanceStatus' | 'locale' | 'onRestoreGuidance'>) {
|
||||
if (!guidanceStatus || isVaultAiGuidanceStatusChecking(guidanceStatus)) return null
|
||||
if (!guidanceStatus || isWorkspaceAiGuidanceStatusChecking(guidanceStatus)) return null
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuLabel>{translate(locale, 'status.ai.vaultGuidance')}</DropdownMenuLabel>
|
||||
<DropdownMenuItem disabled data-testid="status-ai-guidance-summary">
|
||||
{getVaultAiGuidanceSummary(guidanceStatus)}
|
||||
{getWorkspaceAiGuidanceSummary(guidanceStatus)}
|
||||
</DropdownMenuItem>
|
||||
{vaultAiGuidanceNeedsRestore(guidanceStatus) && guidanceStatus.canRestore && (
|
||||
{workspaceAiGuidanceNeedsRestore(guidanceStatus) && guidanceStatus.canRestore && (
|
||||
<DropdownMenuItem
|
||||
onSelect={() => onRestoreGuidance?.()}
|
||||
data-testid="status-ai-guidance-restore"
|
||||
|
||||
@ -31,16 +31,16 @@ describe('buildAiAgentCommands', () => {
|
||||
})
|
||||
|
||||
it('adds a restore guidance command when the vault guidance needs repair', () => {
|
||||
const onRestoreVaultAiGuidance = vi.fn()
|
||||
const onRestoreWorkspaceAiGuidance = vi.fn()
|
||||
|
||||
const commands = buildAiAgentCommands({
|
||||
vaultAiGuidanceStatus: {
|
||||
workspaceAiGuidanceStatus: {
|
||||
agentsState: 'missing',
|
||||
claudeState: 'managed',
|
||||
geminiState: 'managed',
|
||||
canRestore: true,
|
||||
},
|
||||
onRestoreVaultAiGuidance,
|
||||
onRestoreWorkspaceAiGuidance,
|
||||
})
|
||||
|
||||
const command = commands.find((item) => item.id === 'restore-vault-ai-guidance')
|
||||
@ -48,18 +48,18 @@ describe('buildAiAgentCommands', () => {
|
||||
expect(command?.keywords).toContain('antigravity')
|
||||
expect(command?.keywords).toContain('gemini')
|
||||
command?.execute()
|
||||
expect(onRestoreVaultAiGuidance).toHaveBeenCalledOnce()
|
||||
expect(onRestoreWorkspaceAiGuidance).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('omits the restore command when the vault guidance is already healthy', () => {
|
||||
const commands = buildAiAgentCommands({
|
||||
vaultAiGuidanceStatus: {
|
||||
workspaceAiGuidanceStatus: {
|
||||
agentsState: 'managed',
|
||||
claudeState: 'managed',
|
||||
geminiState: 'managed',
|
||||
canRestore: false,
|
||||
},
|
||||
onRestoreVaultAiGuidance: vi.fn(),
|
||||
onRestoreWorkspaceAiGuidance: vi.fn(),
|
||||
})
|
||||
|
||||
expect(commands.find((item) => item.id === 'restore-vault-ai-guidance')).toBeUndefined()
|
||||
|
||||
@ -5,10 +5,10 @@ import {
|
||||
type AiAgentsStatus,
|
||||
} from '../../lib/aiAgents'
|
||||
import {
|
||||
isVaultAiGuidanceStatusChecking,
|
||||
vaultAiGuidanceNeedsRestore,
|
||||
type VaultAiGuidanceStatus,
|
||||
} from '../../lib/vaultAiGuidance'
|
||||
isWorkspaceAiGuidanceStatusChecking,
|
||||
workspaceAiGuidanceNeedsRestore,
|
||||
type WorkspaceAiGuidanceStatus,
|
||||
} from '../../lib/workspaceAiGuidance'
|
||||
import type { CommandAction } from './types'
|
||||
|
||||
const AI_AGENT_KEYWORDS = Array.from(new Set(
|
||||
@ -26,11 +26,11 @@ function aiAgentKeywords(...keywords: string[]): string[] {
|
||||
interface AiAgentCommandsConfig {
|
||||
aiFeaturesEnabled?: boolean
|
||||
aiAgentsStatus?: AiAgentsStatus
|
||||
vaultAiGuidanceStatus?: VaultAiGuidanceStatus
|
||||
workspaceAiGuidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
selectedAiAgent?: AiAgentId
|
||||
selectedAiAgentLabel?: string
|
||||
onOpenAiAgents?: () => void
|
||||
onRestoreVaultAiGuidance?: () => void
|
||||
onRestoreWorkspaceAiGuidance?: () => void
|
||||
onCycleDefaultAiAgent?: () => void
|
||||
onSetDefaultAiAgent?: (agent: AiAgentId) => void
|
||||
}
|
||||
@ -56,12 +56,12 @@ function explicitSwitchCommands({
|
||||
}
|
||||
|
||||
function restoreGuidanceCommands({
|
||||
vaultAiGuidanceStatus,
|
||||
onRestoreVaultAiGuidance,
|
||||
}: Pick<AiAgentCommandsConfig, 'vaultAiGuidanceStatus' | 'onRestoreVaultAiGuidance'>): CommandAction[] {
|
||||
if (!vaultAiGuidanceStatus || !onRestoreVaultAiGuidance) return []
|
||||
if (isVaultAiGuidanceStatusChecking(vaultAiGuidanceStatus)) return []
|
||||
if (!vaultAiGuidanceNeedsRestore(vaultAiGuidanceStatus)) return []
|
||||
workspaceAiGuidanceStatus,
|
||||
onRestoreWorkspaceAiGuidance,
|
||||
}: Pick<AiAgentCommandsConfig, 'workspaceAiGuidanceStatus' | 'onRestoreWorkspaceAiGuidance'>): CommandAction[] {
|
||||
if (!workspaceAiGuidanceStatus || !onRestoreWorkspaceAiGuidance) return []
|
||||
if (isWorkspaceAiGuidanceStatusChecking(workspaceAiGuidanceStatus)) return []
|
||||
if (!workspaceAiGuidanceNeedsRestore(workspaceAiGuidanceStatus)) return []
|
||||
|
||||
return [
|
||||
{
|
||||
@ -70,7 +70,7 @@ function restoreGuidanceCommands({
|
||||
group: 'Settings',
|
||||
keywords: aiAgentKeywords('ai', 'agent', 'guidance', 'restore', 'repair', 'agents', 'antigravity', 'gemini'),
|
||||
enabled: true,
|
||||
execute: () => onRestoreVaultAiGuidance(),
|
||||
execute: () => onRestoreWorkspaceAiGuidance(),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -78,11 +78,11 @@ function restoreGuidanceCommands({
|
||||
export function buildAiAgentCommands({
|
||||
aiFeaturesEnabled = true,
|
||||
aiAgentsStatus,
|
||||
vaultAiGuidanceStatus,
|
||||
workspaceAiGuidanceStatus,
|
||||
selectedAiAgent,
|
||||
selectedAiAgentLabel,
|
||||
onOpenAiAgents,
|
||||
onRestoreVaultAiGuidance,
|
||||
onRestoreWorkspaceAiGuidance,
|
||||
onCycleDefaultAiAgent,
|
||||
onSetDefaultAiAgent,
|
||||
}: AiAgentCommandsConfig): CommandAction[] {
|
||||
@ -100,8 +100,8 @@ export function buildAiAgentCommands({
|
||||
]
|
||||
|
||||
commands.push(...restoreGuidanceCommands({
|
||||
vaultAiGuidanceStatus,
|
||||
onRestoreVaultAiGuidance,
|
||||
workspaceAiGuidanceStatus,
|
||||
onRestoreWorkspaceAiGuidance,
|
||||
}))
|
||||
|
||||
const switchCommands = explicitSwitchCommands({
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useMemo } from 'react'
|
||||
import type { AiAgentId, AiAgentsStatus } from '../lib/aiAgents'
|
||||
import type { VaultAiGuidanceStatus } from '../lib/vaultAiGuidance'
|
||||
import type { WorkspaceAiGuidanceStatus } from '../lib/workspaceAiGuidance'
|
||||
|
||||
interface AppCommandDialogs {
|
||||
toggleAIChat: () => void
|
||||
@ -19,8 +19,8 @@ interface AppCommandAiActions {
|
||||
onToggleAIChat?: () => void
|
||||
onOpenAiAgents?: () => void
|
||||
aiAgentsStatus?: AiAgentsStatus
|
||||
vaultAiGuidanceStatus?: VaultAiGuidanceStatus
|
||||
onRestoreVaultAiGuidance?: () => void
|
||||
workspaceAiGuidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
onRestoreWorkspaceAiGuidance?: () => void
|
||||
selectedAiAgent?: AiAgentId
|
||||
onSetDefaultAiAgent?: (agent: AiAgentId) => void
|
||||
onCycleDefaultAiAgent?: () => void
|
||||
@ -31,8 +31,8 @@ export function useAppCommandAiActions(
|
||||
aiFeaturesEnabled: boolean,
|
||||
dialogs: AppCommandDialogs,
|
||||
aiAgentsStatus: AiAgentsStatus,
|
||||
vaultAiGuidanceStatus: VaultAiGuidanceStatus,
|
||||
restoreVaultAiGuidanceCommand: (() => void) | undefined,
|
||||
workspaceAiGuidanceStatus: WorkspaceAiGuidanceStatus,
|
||||
restoreWorkspaceAiGuidanceCommand: (() => void) | undefined,
|
||||
aiAgentPreferences: AppCommandAiPreferences,
|
||||
): AppCommandAiActions {
|
||||
return useMemo(() => {
|
||||
@ -43,8 +43,8 @@ export function useAppCommandAiActions(
|
||||
onToggleAIChat: dialogs.toggleAIChat,
|
||||
onOpenAiAgents: dialogs.openSettings,
|
||||
aiAgentsStatus,
|
||||
vaultAiGuidanceStatus,
|
||||
onRestoreVaultAiGuidance: restoreVaultAiGuidanceCommand,
|
||||
workspaceAiGuidanceStatus,
|
||||
onRestoreWorkspaceAiGuidance: restoreWorkspaceAiGuidanceCommand,
|
||||
selectedAiAgent: aiAgentPreferences.defaultAiAgent,
|
||||
onSetDefaultAiAgent: aiAgentPreferences.setDefaultAiAgent,
|
||||
onCycleDefaultAiAgent: aiAgentPreferences.cycleDefaultAiAgent,
|
||||
@ -55,8 +55,8 @@ export function useAppCommandAiActions(
|
||||
dialogs.toggleAIChat,
|
||||
dialogs.openSettings,
|
||||
aiAgentsStatus,
|
||||
vaultAiGuidanceStatus,
|
||||
restoreVaultAiGuidanceCommand,
|
||||
workspaceAiGuidanceStatus,
|
||||
restoreWorkspaceAiGuidanceCommand,
|
||||
aiAgentPreferences.defaultAiAgent,
|
||||
aiAgentPreferences.setDefaultAiAgent,
|
||||
aiAgentPreferences.cycleDefaultAiAgent,
|
||||
|
||||
@ -2,7 +2,7 @@ import { useCallback, useRef } from 'react'
|
||||
import type { AiAgentId, AiAgentsStatus } from '../lib/aiAgents'
|
||||
import type { AppLocale, UiLanguagePreference } from '../lib/i18n'
|
||||
import type { ThemeMode } from '../lib/themeMode'
|
||||
import type { VaultAiGuidanceStatus } from '../lib/vaultAiGuidance'
|
||||
import type { WorkspaceAiGuidanceStatus } from '../lib/workspaceAiGuidance'
|
||||
import { useAppKeyboard } from './useAppKeyboard'
|
||||
import { useCommandRegistry } from './useCommandRegistry'
|
||||
import type { CommandAction } from './useCommandRegistry'
|
||||
@ -103,9 +103,9 @@ interface AppCommandsConfig {
|
||||
mcpStatus?: string
|
||||
onInstallMcp?: () => void
|
||||
aiAgentsStatus?: AiAgentsStatus
|
||||
vaultAiGuidanceStatus?: VaultAiGuidanceStatus
|
||||
workspaceAiGuidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
onOpenAiAgents?: () => void
|
||||
onRestoreVaultAiGuidance?: () => void
|
||||
onRestoreWorkspaceAiGuidance?: () => void
|
||||
onSetDefaultAiAgent?: (agent: AiAgentId) => void
|
||||
selectedAiAgent?: AiAgentId
|
||||
onCycleDefaultAiAgent?: () => void
|
||||
@ -242,9 +242,9 @@ type CommandRegistryAiActions = Pick<
|
||||
| 'mcpStatus'
|
||||
| 'onInstallMcp'
|
||||
| 'aiAgentsStatus'
|
||||
| 'vaultAiGuidanceStatus'
|
||||
| 'workspaceAiGuidanceStatus'
|
||||
| 'onOpenAiAgents'
|
||||
| 'onRestoreVaultAiGuidance'
|
||||
| 'onRestoreWorkspaceAiGuidance'
|
||||
| 'onSetDefaultAiAgent'
|
||||
| 'selectedAiAgent'
|
||||
| 'onCycleDefaultAiAgent'
|
||||
@ -570,9 +570,9 @@ function createCommandRegistryAiConfig(
|
||||
return {
|
||||
...sharedConfig,
|
||||
aiAgentsStatus: config.aiAgentsStatus,
|
||||
vaultAiGuidanceStatus: config.vaultAiGuidanceStatus,
|
||||
workspaceAiGuidanceStatus: config.workspaceAiGuidanceStatus,
|
||||
onOpenAiAgents: config.onOpenAiAgents,
|
||||
onRestoreVaultAiGuidance: config.onRestoreVaultAiGuidance,
|
||||
onRestoreWorkspaceAiGuidance: config.onRestoreWorkspaceAiGuidance,
|
||||
onSetDefaultAiAgent: config.onSetDefaultAiAgent,
|
||||
selectedAiAgent: config.selectedAiAgent,
|
||||
onCycleDefaultAiAgent: config.onCycleDefaultAiAgent,
|
||||
|
||||
@ -2,7 +2,7 @@ import { useMemo } from 'react'
|
||||
import type { AiAgentId, AiAgentsStatus } from '../lib/aiAgents'
|
||||
import type { AppLocale, UiLanguagePreference } from '../lib/i18n'
|
||||
import type { ThemeMode } from '../lib/themeMode'
|
||||
import type { VaultAiGuidanceStatus } from '../lib/vaultAiGuidance'
|
||||
import type { WorkspaceAiGuidanceStatus } from '../lib/workspaceAiGuidance'
|
||||
import type { NoteWidthMode, SidebarSelection, VaultEntry } from '../types'
|
||||
import type { NoteListFilter } from '../utils/noteListHelpers'
|
||||
import type { ViewMode } from './useViewMode'
|
||||
@ -36,9 +36,9 @@ interface CommandRegistryConfig {
|
||||
onInstallMcp?: () => void
|
||||
aiFeaturesEnabled?: boolean
|
||||
aiAgentsStatus?: AiAgentsStatus
|
||||
vaultAiGuidanceStatus?: VaultAiGuidanceStatus
|
||||
workspaceAiGuidanceStatus?: WorkspaceAiGuidanceStatus
|
||||
onOpenAiAgents?: () => void
|
||||
onRestoreVaultAiGuidance?: () => void
|
||||
onRestoreWorkspaceAiGuidance?: () => void
|
||||
onSetDefaultAiAgent?: (agent: AiAgentId) => void
|
||||
selectedAiAgent?: AiAgentId
|
||||
onCycleDefaultAiAgent?: () => void
|
||||
@ -167,8 +167,8 @@ export function useCommandRegistry(config: CommandRegistryConfig): import('./com
|
||||
onCheckForUpdates, onCreateType,
|
||||
onRemoveActiveVault, onRestoreGettingStarted, isGettingStartedHidden, vaultCount,
|
||||
mcpStatus, onInstallMcp, aiFeaturesEnabled,
|
||||
aiAgentsStatus, vaultAiGuidanceStatus,
|
||||
onOpenAiAgents, onRestoreVaultAiGuidance, onSetDefaultAiAgent, selectedAiAgent, onCycleDefaultAiAgent, selectedAiAgentLabel,
|
||||
aiAgentsStatus, workspaceAiGuidanceStatus,
|
||||
onOpenAiAgents, onRestoreWorkspaceAiGuidance, onSetDefaultAiAgent, selectedAiAgent, onCycleDefaultAiAgent, selectedAiAgentLabel,
|
||||
onReloadVault, onRepairVault,
|
||||
locale, systemLocale, selectedUiLanguage, onSetUiLanguage, onSetThemeMode,
|
||||
onSetNoteIcon, onRemoveNoteIcon, activeNoteHasIcon, onChangeNoteType, onMoveNoteToFolder, canMoveNoteToFolder, onTurnCurrentBlockInto,
|
||||
@ -291,17 +291,17 @@ export function useCommandRegistry(config: CommandRegistryConfig): import('./com
|
||||
const aiCommands = useMemo(() => buildAiAgentCommands({
|
||||
aiFeaturesEnabled,
|
||||
aiAgentsStatus,
|
||||
vaultAiGuidanceStatus,
|
||||
workspaceAiGuidanceStatus,
|
||||
selectedAiAgent,
|
||||
selectedAiAgentLabel,
|
||||
onOpenAiAgents,
|
||||
onRestoreVaultAiGuidance,
|
||||
onRestoreWorkspaceAiGuidance,
|
||||
onSetDefaultAiAgent,
|
||||
onCycleDefaultAiAgent,
|
||||
}), [
|
||||
aiFeaturesEnabled,
|
||||
aiAgentsStatus, vaultAiGuidanceStatus, selectedAiAgent, selectedAiAgentLabel,
|
||||
onOpenAiAgents, onRestoreVaultAiGuidance, onSetDefaultAiAgent, onCycleDefaultAiAgent,
|
||||
aiAgentsStatus, workspaceAiGuidanceStatus, selectedAiAgent, selectedAiAgentLabel,
|
||||
onOpenAiAgents, onRestoreWorkspaceAiGuidance, onSetDefaultAiAgent, onCycleDefaultAiAgent,
|
||||
])
|
||||
|
||||
const typeCommands = useMemo(
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { isTauri, mockInvoke } from '../mock-tauri'
|
||||
import {
|
||||
createCheckingVaultAiGuidanceStatus,
|
||||
normalizeVaultAiGuidanceStatus,
|
||||
type VaultAiGuidanceFileState,
|
||||
type VaultAiGuidanceStatus,
|
||||
} from '../lib/vaultAiGuidance'
|
||||
|
||||
type RawVaultAiGuidanceStatus = Partial<{
|
||||
agents_state: VaultAiGuidanceFileState | null
|
||||
claude_state: VaultAiGuidanceFileState | null
|
||||
gemini_state: VaultAiGuidanceFileState | null
|
||||
can_restore: boolean | null
|
||||
}>
|
||||
|
||||
function tauriCall<T>(command: string, args: Record<string, unknown>): Promise<T> {
|
||||
return isTauri() ? invoke<T>(command, args) : mockInvoke<T>(command, args)
|
||||
}
|
||||
|
||||
export function useVaultAiGuidanceStatus(
|
||||
vaultPath: string | null | undefined,
|
||||
refreshKey = '',
|
||||
): { status: VaultAiGuidanceStatus; refresh: () => Promise<VaultAiGuidanceStatus> } {
|
||||
const checkingStatus = useMemo(() => createCheckingVaultAiGuidanceStatus(), [])
|
||||
const statusRequest = useMemo(() => ({ refreshKey, vaultPath }), [refreshKey, vaultPath])
|
||||
const [status, setStatus] = useState<VaultAiGuidanceStatus>(() => createCheckingVaultAiGuidanceStatus())
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!vaultPath) {
|
||||
return checkingStatus
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await tauriCall<RawVaultAiGuidanceStatus>('get_vault_ai_guidance_status', {
|
||||
vaultPath,
|
||||
})
|
||||
const normalized = normalizeVaultAiGuidanceStatus(result)
|
||||
setStatus(normalized)
|
||||
return normalized
|
||||
} catch {
|
||||
const checking = createCheckingVaultAiGuidanceStatus()
|
||||
setStatus(checking)
|
||||
return checking
|
||||
}
|
||||
}, [checkingStatus, vaultPath])
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
|
||||
if (!statusRequest.vaultPath) return
|
||||
|
||||
tauriCall<RawVaultAiGuidanceStatus>('get_vault_ai_guidance_status', { vaultPath: statusRequest.vaultPath })
|
||||
.then((result) => {
|
||||
if (!cancelled) {
|
||||
setStatus(normalizeVaultAiGuidanceStatus(result))
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
setStatus(createCheckingVaultAiGuidanceStatus())
|
||||
}
|
||||
})
|
||||
|
||||
return () => { cancelled = true }
|
||||
}, [statusRequest])
|
||||
|
||||
return {
|
||||
status: vaultPath ? status : checkingStatus,
|
||||
refresh,
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { act, renderHook, waitFor } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { useVaultAiGuidanceStatus } from './useVaultAiGuidanceStatus'
|
||||
import { useWorkspaceAiGuidanceStatus } from './useWorkspaceAiGuidanceStatus'
|
||||
|
||||
vi.mock('@tauri-apps/api/core', () => ({
|
||||
invoke: vi.fn(),
|
||||
@ -13,7 +13,7 @@ vi.mock('../mock-tauri', () => ({
|
||||
|
||||
const { mockInvoke } = await import('../mock-tauri') as { mockInvoke: ReturnType<typeof vi.fn> }
|
||||
|
||||
describe('useVaultAiGuidanceStatus', () => {
|
||||
describe('useWorkspaceAiGuidanceStatus', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
@ -26,7 +26,7 @@ describe('useVaultAiGuidanceStatus', () => {
|
||||
can_restore: true,
|
||||
})
|
||||
|
||||
const { result } = renderHook(() => useVaultAiGuidanceStatus('/vault'))
|
||||
const { result } = renderHook(() => useWorkspaceAiGuidanceStatus('/vault'))
|
||||
|
||||
expect(result.current.status.agentsState).toBe('checking')
|
||||
expect(result.current.status.claudeState).toBe('checking')
|
||||
@ -57,7 +57,7 @@ describe('useVaultAiGuidanceStatus', () => {
|
||||
can_restore: true,
|
||||
})
|
||||
|
||||
const { result } = renderHook(() => useVaultAiGuidanceStatus('/vault'))
|
||||
const { result } = renderHook(() => useWorkspaceAiGuidanceStatus('/vault'))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.status.canRestore).toBe(false)
|
||||
73
src/hooks/useWorkspaceAiGuidanceStatus.ts
Normal file
73
src/hooks/useWorkspaceAiGuidanceStatus.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { isTauri, mockInvoke } from '../mock-tauri'
|
||||
import {
|
||||
createCheckingWorkspaceAiGuidanceStatus,
|
||||
normalizeWorkspaceAiGuidanceStatus,
|
||||
type WorkspaceAiGuidanceFileState,
|
||||
type WorkspaceAiGuidanceStatus,
|
||||
} from '../lib/workspaceAiGuidance'
|
||||
|
||||
type RawWorkspaceAiGuidanceStatus = Partial<{
|
||||
agents_state: WorkspaceAiGuidanceFileState | null
|
||||
claude_state: WorkspaceAiGuidanceFileState | null
|
||||
gemini_state: WorkspaceAiGuidanceFileState | null
|
||||
can_restore: boolean | null
|
||||
}>
|
||||
|
||||
function tauriCall<T>(command: string, args: Record<string, unknown>): Promise<T> {
|
||||
return isTauri() ? invoke<T>(command, args) : mockInvoke<T>(command, args)
|
||||
}
|
||||
|
||||
export function useWorkspaceAiGuidanceStatus(
|
||||
vaultPath: string | null | undefined,
|
||||
refreshKey = '',
|
||||
): { status: WorkspaceAiGuidanceStatus; refresh: () => Promise<WorkspaceAiGuidanceStatus> } {
|
||||
const checkingStatus = useMemo(() => createCheckingWorkspaceAiGuidanceStatus(), [])
|
||||
const statusRequest = useMemo(() => ({ refreshKey, vaultPath }), [refreshKey, vaultPath])
|
||||
const [status, setStatus] = useState<WorkspaceAiGuidanceStatus>(() => createCheckingWorkspaceAiGuidanceStatus())
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!vaultPath) {
|
||||
return checkingStatus
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await tauriCall<RawWorkspaceAiGuidanceStatus>('get_vault_ai_guidance_status', {
|
||||
vaultPath,
|
||||
})
|
||||
const normalized = normalizeWorkspaceAiGuidanceStatus(result)
|
||||
setStatus(normalized)
|
||||
return normalized
|
||||
} catch {
|
||||
const checking = createCheckingWorkspaceAiGuidanceStatus()
|
||||
setStatus(checking)
|
||||
return checking
|
||||
}
|
||||
}, [checkingStatus, vaultPath])
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
|
||||
if (!statusRequest.vaultPath) return
|
||||
|
||||
tauriCall<RawWorkspaceAiGuidanceStatus>('get_vault_ai_guidance_status', { vaultPath: statusRequest.vaultPath })
|
||||
.then((result) => {
|
||||
if (!cancelled) {
|
||||
setStatus(normalizeWorkspaceAiGuidanceStatus(result))
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
setStatus(createCheckingWorkspaceAiGuidanceStatus())
|
||||
}
|
||||
})
|
||||
|
||||
return () => { cancelled = true }
|
||||
}, [statusRequest])
|
||||
|
||||
return {
|
||||
status: vaultPath ? status : checkingStatus,
|
||||
refresh,
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,12 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
buildVaultAiGuidanceRefreshKey,
|
||||
createCheckingVaultAiGuidanceStatus,
|
||||
getVaultAiGuidanceSummary,
|
||||
normalizeVaultAiGuidanceStatus,
|
||||
vaultAiGuidanceNeedsRestore,
|
||||
vaultAiGuidanceUsesCustomFiles,
|
||||
} from './vaultAiGuidance'
|
||||
buildWorkspaceAiGuidanceRefreshKey,
|
||||
createCheckingWorkspaceAiGuidanceStatus,
|
||||
getWorkspaceAiGuidanceSummary,
|
||||
normalizeWorkspaceAiGuidanceStatus,
|
||||
workspaceAiGuidanceNeedsRestore,
|
||||
workspaceAiGuidanceUsesCustomFiles,
|
||||
} from './workspaceAiGuidance'
|
||||
import type { VaultEntry } from '../types'
|
||||
|
||||
function makeEntry(filename: string, overrides: Partial<VaultEntry> = {}): VaultEntry {
|
||||
@ -46,9 +46,9 @@ function makeEntry(filename: string, overrides: Partial<VaultEntry> = {}): Vault
|
||||
}
|
||||
}
|
||||
|
||||
describe('vaultAiGuidance helpers', () => {
|
||||
describe('workspaceAiGuidance helpers', () => {
|
||||
it('starts in checking state', () => {
|
||||
expect(createCheckingVaultAiGuidanceStatus()).toEqual({
|
||||
expect(createCheckingWorkspaceAiGuidanceStatus()).toEqual({
|
||||
agentsState: 'checking',
|
||||
claudeState: 'checking',
|
||||
geminiState: 'checking',
|
||||
@ -57,7 +57,7 @@ describe('vaultAiGuidance helpers', () => {
|
||||
})
|
||||
|
||||
it('normalizes raw backend payloads', () => {
|
||||
expect(normalizeVaultAiGuidanceStatus({
|
||||
expect(normalizeWorkspaceAiGuidanceStatus({
|
||||
agents_state: 'managed',
|
||||
claude_state: 'broken',
|
||||
gemini_state: 'missing',
|
||||
@ -71,47 +71,47 @@ describe('vaultAiGuidance helpers', () => {
|
||||
})
|
||||
|
||||
it('detects restoreable and custom states', () => {
|
||||
const restoreable = normalizeVaultAiGuidanceStatus({
|
||||
const restoreable = normalizeWorkspaceAiGuidanceStatus({
|
||||
agents_state: 'missing',
|
||||
claude_state: 'managed',
|
||||
gemini_state: 'managed',
|
||||
can_restore: true,
|
||||
})
|
||||
const custom = normalizeVaultAiGuidanceStatus({
|
||||
const custom = normalizeWorkspaceAiGuidanceStatus({
|
||||
agents_state: 'custom',
|
||||
claude_state: 'managed',
|
||||
gemini_state: 'managed',
|
||||
can_restore: false,
|
||||
})
|
||||
|
||||
expect(vaultAiGuidanceNeedsRestore(restoreable)).toBe(true)
|
||||
expect(getVaultAiGuidanceSummary(restoreable)).toBe('光湖人格体唤醒指南缺失或损坏')
|
||||
expect(vaultAiGuidanceUsesCustomFiles(custom)).toBe(true)
|
||||
expect(getVaultAiGuidanceSummary(custom)).toBe('Using custom AGENTS.md')
|
||||
expect(workspaceAiGuidanceNeedsRestore(restoreable)).toBe(true)
|
||||
expect(getWorkspaceAiGuidanceSummary(restoreable)).toBe('光湖人格体唤醒指南缺失或损坏')
|
||||
expect(workspaceAiGuidanceUsesCustomFiles(custom)).toBe(true)
|
||||
expect(getWorkspaceAiGuidanceSummary(custom)).toBe('Using custom AGENTS.md')
|
||||
})
|
||||
|
||||
it('summarizes optional Gemini guidance states', () => {
|
||||
const missing = normalizeVaultAiGuidanceStatus({
|
||||
const missing = normalizeWorkspaceAiGuidanceStatus({
|
||||
agents_state: 'managed',
|
||||
claude_state: 'managed',
|
||||
gemini_state: 'missing',
|
||||
can_restore: true,
|
||||
})
|
||||
const custom = normalizeVaultAiGuidanceStatus({
|
||||
const custom = normalizeWorkspaceAiGuidanceStatus({
|
||||
agents_state: 'managed',
|
||||
claude_state: 'managed',
|
||||
gemini_state: 'custom',
|
||||
can_restore: false,
|
||||
})
|
||||
|
||||
expect(vaultAiGuidanceNeedsRestore(missing)).toBe(true)
|
||||
expect(getVaultAiGuidanceSummary(missing)).toBe('Gemini guidance can be created')
|
||||
expect(vaultAiGuidanceUsesCustomFiles(custom)).toBe(true)
|
||||
expect(getVaultAiGuidanceSummary(custom)).toBe('Using custom GEMINI.md')
|
||||
expect(workspaceAiGuidanceNeedsRestore(missing)).toBe(true)
|
||||
expect(getWorkspaceAiGuidanceSummary(missing)).toBe('Gemini guidance can be created')
|
||||
expect(workspaceAiGuidanceUsesCustomFiles(custom)).toBe(true)
|
||||
expect(getWorkspaceAiGuidanceSummary(custom)).toBe('Using custom GEMINI.md')
|
||||
})
|
||||
|
||||
it('builds a refresh key from AGENTS and CLAUDE entries only', () => {
|
||||
const key = buildVaultAiGuidanceRefreshKey([
|
||||
const key = buildWorkspaceAiGuidanceRefreshKey([
|
||||
makeEntry('alpha.md'),
|
||||
makeEntry('CLAUDE.md', { modifiedAt: 20, fileSize: 30 }),
|
||||
makeEntry('GEMINI.md', { modifiedAt: 25, fileSize: 35 }),
|
||||
@ -1,24 +1,24 @@
|
||||
import type { VaultEntry } from '../types'
|
||||
|
||||
export type VaultAiGuidanceFileState = 'checking' | 'managed' | 'missing' | 'broken' | 'custom'
|
||||
export type WorkspaceAiGuidanceFileState = 'checking' | 'managed' | 'missing' | 'broken' | 'custom'
|
||||
|
||||
export interface VaultAiGuidanceStatus {
|
||||
agentsState: VaultAiGuidanceFileState
|
||||
claudeState: VaultAiGuidanceFileState
|
||||
geminiState: VaultAiGuidanceFileState
|
||||
export interface WorkspaceAiGuidanceStatus {
|
||||
agentsState: WorkspaceAiGuidanceFileState
|
||||
claudeState: WorkspaceAiGuidanceFileState
|
||||
geminiState: WorkspaceAiGuidanceFileState
|
||||
canRestore: boolean
|
||||
}
|
||||
|
||||
type RawVaultAiGuidanceStatus = Partial<{
|
||||
agents_state: VaultAiGuidanceFileState | null
|
||||
claude_state: VaultAiGuidanceFileState | null
|
||||
gemini_state: VaultAiGuidanceFileState | null
|
||||
type RawWorkspaceAiGuidanceStatus = Partial<{
|
||||
agents_state: WorkspaceAiGuidanceFileState | null
|
||||
claude_state: WorkspaceAiGuidanceFileState | null
|
||||
gemini_state: WorkspaceAiGuidanceFileState | null
|
||||
can_restore: boolean | null
|
||||
}>
|
||||
|
||||
const GUIDANCE_FILENAMES = new Set(['AGENTS.md', 'CLAUDE.md', 'GEMINI.md'])
|
||||
|
||||
export function createCheckingVaultAiGuidanceStatus(): VaultAiGuidanceStatus {
|
||||
export function createCheckingWorkspaceAiGuidanceStatus(): WorkspaceAiGuidanceStatus {
|
||||
return {
|
||||
agentsState: 'checking',
|
||||
claudeState: 'checking',
|
||||
@ -27,7 +27,7 @@ export function createCheckingVaultAiGuidanceStatus(): VaultAiGuidanceStatus {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeFileState(value: string | null | undefined): VaultAiGuidanceFileState {
|
||||
function normalizeFileState(value: string | null | undefined): WorkspaceAiGuidanceFileState {
|
||||
switch (value) {
|
||||
case 'managed':
|
||||
case 'missing':
|
||||
@ -39,9 +39,9 @@ function normalizeFileState(value: string | null | undefined): VaultAiGuidanceFi
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeVaultAiGuidanceStatus(
|
||||
payload: RawVaultAiGuidanceStatus | null | undefined,
|
||||
): VaultAiGuidanceStatus {
|
||||
export function normalizeWorkspaceAiGuidanceStatus(
|
||||
payload: RawWorkspaceAiGuidanceStatus | null | undefined,
|
||||
): WorkspaceAiGuidanceStatus {
|
||||
return {
|
||||
agentsState: normalizeFileState(payload?.agents_state),
|
||||
claudeState: normalizeFileState(payload?.claude_state),
|
||||
@ -50,14 +50,14 @@ export function normalizeVaultAiGuidanceStatus(
|
||||
}
|
||||
}
|
||||
|
||||
export function isVaultAiGuidanceStatusChecking(status: VaultAiGuidanceStatus): boolean {
|
||||
export function isWorkspaceAiGuidanceStatusChecking(status: WorkspaceAiGuidanceStatus): boolean {
|
||||
return status.agentsState === 'checking'
|
||||
|| status.claudeState === 'checking'
|
||||
|| status.geminiState === 'checking'
|
||||
}
|
||||
|
||||
export function vaultAiGuidanceNeedsRestore(status: VaultAiGuidanceStatus): boolean {
|
||||
if (!status.canRestore || isVaultAiGuidanceStatusChecking(status)) return false
|
||||
export function workspaceAiGuidanceNeedsRestore(status: WorkspaceAiGuidanceStatus): boolean {
|
||||
if (!status.canRestore || isWorkspaceAiGuidanceStatusChecking(status)) return false
|
||||
return status.agentsState === 'missing'
|
||||
|| status.agentsState === 'broken'
|
||||
|| status.claudeState === 'missing'
|
||||
@ -66,13 +66,13 @@ export function vaultAiGuidanceNeedsRestore(status: VaultAiGuidanceStatus): bool
|
||||
|| status.geminiState === 'broken'
|
||||
}
|
||||
|
||||
export function vaultAiGuidanceUsesCustomFiles(status: VaultAiGuidanceStatus): boolean {
|
||||
export function workspaceAiGuidanceUsesCustomFiles(status: WorkspaceAiGuidanceStatus): boolean {
|
||||
return status.agentsState === 'custom'
|
||||
|| status.claudeState === 'custom'
|
||||
|| status.geminiState === 'custom'
|
||||
}
|
||||
|
||||
function isMissingOrBroken(state: VaultAiGuidanceFileState): boolean {
|
||||
function isMissingOrBroken(state: WorkspaceAiGuidanceFileState): boolean {
|
||||
return state === 'missing' || state === 'broken'
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ function formatGuidanceFileList(names: string[]): string {
|
||||
return `${names.slice(0, -1).join(', ')}, and ${names[names.length - 1]}`
|
||||
}
|
||||
|
||||
function getBrokenGuidanceSummary(status: VaultAiGuidanceStatus): string | null {
|
||||
function getBrokenGuidanceSummary(status: WorkspaceAiGuidanceStatus): string | null {
|
||||
if (isMissingOrBroken(status.agentsState)) {
|
||||
return '光湖人格体唤醒指南缺失或损坏'
|
||||
}
|
||||
@ -98,7 +98,7 @@ function getBrokenGuidanceSummary(status: VaultAiGuidanceStatus): string | null
|
||||
return null
|
||||
}
|
||||
|
||||
function getCustomGuidanceSummary(status: VaultAiGuidanceStatus): string | null {
|
||||
function getCustomGuidanceSummary(status: WorkspaceAiGuidanceStatus): string | null {
|
||||
const customNames = [
|
||||
status.agentsState === 'custom' ? 'AGENTS.md' : null,
|
||||
status.claudeState === 'custom' ? 'CLAUDE.md' : null,
|
||||
@ -113,8 +113,8 @@ function getCustomGuidanceSummary(status: VaultAiGuidanceStatus): string | null
|
||||
return null
|
||||
}
|
||||
|
||||
export function getVaultAiGuidanceSummary(status: VaultAiGuidanceStatus): string {
|
||||
if (isVaultAiGuidanceStatusChecking(status)) return 'Checking vault guidance…'
|
||||
export function getWorkspaceAiGuidanceSummary(status: WorkspaceAiGuidanceStatus): string {
|
||||
if (isWorkspaceAiGuidanceStatusChecking(status)) return 'Checking vault guidance…'
|
||||
const brokenSummary = getBrokenGuidanceSummary(status)
|
||||
if (brokenSummary) return brokenSummary
|
||||
const customSummary = getCustomGuidanceSummary(status)
|
||||
@ -122,7 +122,7 @@ export function getVaultAiGuidanceSummary(status: VaultAiGuidanceStatus): string
|
||||
return 'HoloLake Era guidance ready'
|
||||
}
|
||||
|
||||
export function buildVaultAiGuidanceRefreshKey(entries: VaultEntry[]): string {
|
||||
export function buildWorkspaceAiGuidanceRefreshKey(entries: VaultEntry[]): string {
|
||||
return entries
|
||||
.filter((entry) => GUIDANCE_FILENAMES.has(entry.filename))
|
||||
.map((entry) => `${entry.path}:${entry.modifiedAt ?? 0}:${entry.fileSize}`)
|
||||
@ -167,7 +167,7 @@ let mockVaultList: { vaults: Array<{ label: string; path: string }>; active_vaul
|
||||
active_vault: DEFAULT_MOCK_VAULT_PATH,
|
||||
}
|
||||
|
||||
let mockVaultAiGuidanceStatus = {
|
||||
let mockWorkspaceAiGuidanceStatus = {
|
||||
agents_state: 'managed',
|
||||
claude_state: 'managed',
|
||||
gemini_state: 'managed',
|
||||
@ -560,15 +560,15 @@ export const mockHandlers: Record<string, (args: any) => any> = {
|
||||
hermes: { installed: false, version: null },
|
||||
}),
|
||||
get_agent_docs_path: () => '/mock/Tolaria/resources/agent-docs',
|
||||
get_vault_ai_guidance_status: () => ({ ...mockVaultAiGuidanceStatus }),
|
||||
get_vault_ai_guidance_status: () => ({ ...mockWorkspaceAiGuidanceStatus }),
|
||||
restore_vault_ai_guidance: () => {
|
||||
mockVaultAiGuidanceStatus = {
|
||||
mockWorkspaceAiGuidanceStatus = {
|
||||
agents_state: 'managed',
|
||||
claude_state: 'managed',
|
||||
gemini_state: 'managed',
|
||||
can_restore: false,
|
||||
}
|
||||
return { ...mockVaultAiGuidanceStatus }
|
||||
return { ...mockWorkspaceAiGuidanceStatus }
|
||||
},
|
||||
stream_claude_chat: () => 'mock-session',
|
||||
stream_ai_agent: () => null,
|
||||
@ -715,7 +715,7 @@ export const mockHandlers: Record<string, (args: any) => any> = {
|
||||
read_text_from_clipboard: () => '',
|
||||
sync_mcp_bridge_vault: (args: { vaultPath?: string | null }) => args.vaultPath ? 'started' : 'stopped',
|
||||
repair_vault: (): string => {
|
||||
mockVaultAiGuidanceStatus = {
|
||||
mockWorkspaceAiGuidanceStatus = {
|
||||
agents_state: 'managed',
|
||||
claude_state: 'managed',
|
||||
gemini_state: 'managed',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user