New files: - project-state.types.ts: all per-project state interfaces - project-state.svelte.ts: unified per-project state with version counter - app-state.svelte.ts: root facade re-exporting all stores as appState.* Rewired components (no more local $state): - ProjectCard: reads via appState.agent.* and appState.project.tab.* - TerminalTabs: state in appState.project.terminals.* - FileBrowser: state in appState.project.files.* - CommsTab: state in appState.project.comms.* - TaskBoardTab: state in appState.project.tasks.* All follow Rule 57 (no $derived with new objects) and Rule 58 (state tree architecture, components are pure renderers).
190 lines
7.2 KiB
TypeScript
190 lines
7.2 KiB
TypeScript
/**
|
|
* Root state tree — unified API surface for all application state.
|
|
*
|
|
* Components import `appState` and access sub-domains:
|
|
* appState.ui.getSettingsOpen()
|
|
* appState.project.getState(id)
|
|
* appState.project.terminals.addTab(id)
|
|
*
|
|
* This file is a pure re-export facade. No new state lives here.
|
|
*/
|
|
|
|
// ── UI store ──────────────────────────────────────────────────────────────
|
|
|
|
import {
|
|
getSettingsOpen, setSettingsOpen, toggleSettings,
|
|
getSettingsCategory, setSettingsCategory, openSettingsCategory,
|
|
getPaletteOpen, setPaletteOpen, togglePalette,
|
|
getSearchOpen, setSearchOpen, toggleSearch,
|
|
getNotifDrawerOpen, setNotifDrawerOpen, toggleNotifDrawer,
|
|
getShowWizard, setShowWizard, toggleWizard,
|
|
getProjectToDelete, setProjectToDelete,
|
|
getShowAddGroup, setShowAddGroup, toggleAddGroup,
|
|
getNewGroupName, setNewGroupName, resetAddGroupForm,
|
|
} from './ui-store.svelte.ts';
|
|
|
|
// ── Workspace store ───────────────────────────────────────────────────────
|
|
|
|
import {
|
|
getProjects, setProjects, getGroups, setGroups,
|
|
getActiveGroupId, setActiveGroup,
|
|
getFilteredProjects, getTotalCostDerived, getTotalTokensDerived,
|
|
getMountedGroupIds, getActiveGroup as getActiveGroupObj,
|
|
addProject, addProjectFromWizard, deleteProject,
|
|
cloneCountForProject, handleClone,
|
|
addGroup, loadGroupsFromDb, loadProjectsFromDb, trackAllProjects,
|
|
getTotalCost, getTotalTokens,
|
|
} from './workspace-store.svelte.ts';
|
|
|
|
// ── Agent store ───────────────────────────────────────────────────────────
|
|
|
|
import {
|
|
startAgent, stopAgent, sendPrompt,
|
|
getSession, hasSession, clearSession,
|
|
loadLastSession, purgeSession, purgeProjectSessions,
|
|
setAgentToastFn, setRetentionConfig, loadRetentionConfig,
|
|
type AgentSession, type AgentMessage, type AgentStatus,
|
|
} from './agent-store.svelte.ts';
|
|
|
|
// ── Project state (per-project tree) ──────────────────────────────────────
|
|
|
|
import {
|
|
getProjectState,
|
|
getActiveTab, isTabActivated, setActiveTab,
|
|
addTerminalTab, closeTerminalTab, activateTerminalTab, toggleTerminalExpanded,
|
|
setFileState, setFileMulti, nextFileRequestToken, getFileRequestToken,
|
|
setCommsState, setCommsMulti,
|
|
setTaskState, setTaskMulti, nextTaskPollToken, getTaskPollToken,
|
|
removeProject as removeProjectState,
|
|
} from './project-state.svelte.ts';
|
|
|
|
// ── Health store ──────────────────────────────────────────────────────────
|
|
|
|
import {
|
|
trackProject, recordActivity, recordToolDone,
|
|
recordTokenSnapshot, setProjectStatus,
|
|
getProjectHealth, getAttentionQueue, getHealthAggregates,
|
|
getActiveTools, getToolHistogram,
|
|
untrackProject, stopHealthTick,
|
|
} from './health-store.svelte.ts';
|
|
|
|
// ── Notifications store ───────────────────────────────────────────────────
|
|
|
|
import {
|
|
getNotifications, getNotifCount,
|
|
addNotification, removeNotification, clearAll as clearNotifications,
|
|
} from './notifications-store.svelte.ts';
|
|
|
|
// ── Blink store ───────────────────────────────────────────────────────────
|
|
|
|
import {
|
|
getBlinkVisible, startBlink, stopBlink,
|
|
} from './blink-store.svelte.ts';
|
|
|
|
// ── Theme store ───────────────────────────────────────────────────────────
|
|
|
|
import { themeStore } from './theme-store.svelte.ts';
|
|
|
|
// ── i18n ──────────────────────────────────────────────────────────────────
|
|
|
|
import { t, setLocale, getLocale, getDir } from './i18n.svelte.ts';
|
|
|
|
// ── Unified API ───────────────────────────────────────────────────────────
|
|
|
|
export const appState = {
|
|
ui: {
|
|
getSettingsOpen, setSettingsOpen, toggleSettings,
|
|
getSettingsCategory, setSettingsCategory, openSettingsCategory,
|
|
getPaletteOpen, setPaletteOpen, togglePalette,
|
|
getSearchOpen, setSearchOpen, toggleSearch,
|
|
getNotifDrawerOpen, setNotifDrawerOpen, toggleNotifDrawer,
|
|
getShowWizard, setShowWizard, toggleWizard,
|
|
getProjectToDelete, setProjectToDelete,
|
|
getShowAddGroup, setShowAddGroup, toggleAddGroup,
|
|
getNewGroupName, setNewGroupName, resetAddGroupForm,
|
|
},
|
|
|
|
workspace: {
|
|
getProjects, setProjects, getGroups, setGroups,
|
|
getActiveGroupId, setActiveGroup,
|
|
getFilteredProjects, getTotalCostDerived, getTotalTokensDerived,
|
|
getMountedGroupIds, getActiveGroup: getActiveGroupObj,
|
|
addProject, addProjectFromWizard, deleteProject,
|
|
cloneCountForProject, handleClone,
|
|
addGroup, loadGroupsFromDb, loadProjectsFromDb, trackAllProjects,
|
|
getTotalCost, getTotalTokens,
|
|
},
|
|
|
|
agent: {
|
|
startAgent, stopAgent, sendPrompt,
|
|
getSession, hasSession, clearSession,
|
|
loadLastSession, purgeSession, purgeProjectSessions,
|
|
setToastFn: setAgentToastFn,
|
|
setRetentionConfig, loadRetentionConfig,
|
|
},
|
|
|
|
project: {
|
|
getState: getProjectState,
|
|
removeState: removeProjectState,
|
|
|
|
tab: {
|
|
getActiveTab, isTabActivated, setActiveTab,
|
|
},
|
|
|
|
terminals: {
|
|
addTab: addTerminalTab,
|
|
closeTab: closeTerminalTab,
|
|
activateTab: activateTerminalTab,
|
|
toggleExpanded: toggleTerminalExpanded,
|
|
},
|
|
|
|
files: {
|
|
setState: setFileState,
|
|
setMulti: setFileMulti,
|
|
nextRequestToken: nextFileRequestToken,
|
|
getRequestToken: getFileRequestToken,
|
|
},
|
|
|
|
comms: {
|
|
setState: setCommsState,
|
|
setMulti: setCommsMulti,
|
|
},
|
|
|
|
tasks: {
|
|
setState: setTaskState,
|
|
setMulti: setTaskMulti,
|
|
nextPollToken: nextTaskPollToken,
|
|
getPollToken: getTaskPollToken,
|
|
},
|
|
},
|
|
|
|
health: {
|
|
trackProject, recordActivity, recordToolDone,
|
|
recordTokenSnapshot, setProjectStatus,
|
|
getProjectHealth, getAttentionQueue, getHealthAggregates,
|
|
getActiveTools, getToolHistogram,
|
|
untrackProject, stopHealthTick,
|
|
},
|
|
|
|
notifications: {
|
|
getAll: getNotifications, getCount: getNotifCount,
|
|
add: addNotification, remove: removeNotification, clear: clearNotifications,
|
|
},
|
|
|
|
blink: {
|
|
getVisible: getBlinkVisible, start: startBlink, stop: stopBlink,
|
|
},
|
|
|
|
theme: themeStore,
|
|
|
|
i18n: { t, setLocale, getLocale, getDir },
|
|
} as const;
|
|
|
|
// Re-export types for convenience
|
|
export type { AgentSession, AgentMessage, AgentStatus };
|
|
export type {
|
|
ProjectState, TermTab, TerminalState, FileState,
|
|
CommsState, TaskState, TabState, DirEntry,
|
|
Channel, ChannelMessage, CommsAgent, DM, ChannelMember, Task,
|
|
ProjectTab,
|
|
} from './project-state.types.ts';
|