Showing preview only (4,297K chars total). Download the full file or copy to clipboard to get everything.
Repository: loocor/codmate
Branch: main
Commit: 2091c39609db
Files: 472
Total size: 4.0 MB
Directory structure:
gitextract_0tk3_bnf/
├── .gitignore
├── .vscode/
│ └── launch.json
├── AGENTS.md
├── CodMateApp.swift
├── Ghostty-header.h
├── LICENSE
├── Makefile
├── NOTICE
├── Package.resolved
├── Package.swift
├── PrivacyInfo.xcprivacy
├── README.md
├── THIRD-PARTY-NOTICES.md
├── Tests/
│ └── CodMateTests/
│ ├── ClaudeHooksAdapterTests.swift
│ ├── CodexHooksAdapterTests.swift
│ ├── GeminiHooksAdapterTests.swift
│ ├── HooksStoreTests.swift
│ ├── UpdateServiceTests.swift
│ ├── UpdateSupportTests.swift
│ ├── UpdateViewModelTests.swift
│ └── WizardResponseParserTests.swift
├── assets/
│ ├── Assets.xcassets/
│ │ ├── AntigravityIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── ChatGPTIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── ClaudeIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── DeepSeekIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── GeminiIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── KimiIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── MCPMateLogo.imageset/
│ │ │ └── Contents.json
│ │ ├── MiniMaxIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── OpenRouterIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── QwenIcon.imageset/
│ │ │ └── Contents.json
│ │ └── ZaiIcon.imageset/
│ │ └── Contents.json
│ ├── CodMate-Notify.entitlements
│ ├── CodMate.entitlements
│ └── Info.plist
├── docs/
│ ├── feature-inventory.md
│ ├── icon.icon/
│ │ └── icon.json
│ └── projects.md
├── ghostty/
│ ├── Package.swift
│ ├── Resources/
│ │ └── themes/
│ │ ├── Apple Classic
│ │ ├── Apple System Colors
│ │ ├── Apple System Colors Light
│ │ ├── Atom
│ │ ├── Atom One Dark
│ │ ├── Atom One Light
│ │ ├── Dracula
│ │ ├── Dracula+
│ │ ├── Farmhouse Dark
│ │ ├── Farmhouse Light
│ │ ├── Flexoki Dark
│ │ ├── Flexoki Light
│ │ ├── GitHub
│ │ ├── GitHub Dark
│ │ ├── GitHub Dark Colorblind
│ │ ├── GitHub Dark Default
│ │ ├── GitHub Dark Dimmed
│ │ ├── GitHub Dark High Contrast
│ │ ├── GitHub Light Colorblind
│ │ ├── GitHub Light Default
│ │ ├── GitHub Light High Contrast
│ │ ├── GitLab Dark
│ │ ├── GitLab Dark Grey
│ │ ├── GitLab Light
│ │ ├── Iceberg Dark
│ │ ├── Iceberg Light
│ │ ├── Material
│ │ ├── Material Dark
│ │ ├── Material Darker
│ │ ├── Material Design Colors
│ │ ├── Material Ocean
│ │ ├── Melange Dark
│ │ ├── Melange Light
│ │ ├── Monokai Pro
│ │ ├── Monokai Pro Light
│ │ ├── Monokai Pro Light Sun
│ │ ├── Monokai Pro Machine
│ │ ├── Monokai Pro Octagon
│ │ ├── Monokai Pro Ristretto
│ │ ├── Monokai Pro Spectrum
│ │ ├── Monokai Remastered
│ │ ├── Neobones Dark
│ │ ├── Neobones Light
│ │ ├── Nvim Dark
│ │ ├── Nvim Light
│ │ ├── One Double Dark
│ │ ├── One Double Light
│ │ ├── One Half Dark
│ │ ├── One Half Light
│ │ ├── Pencil Dark
│ │ ├── Pencil Light
│ │ ├── Raycast Dark
│ │ ├── Raycast Light
│ │ ├── Selenized Dark
│ │ ├── Selenized Light
│ │ ├── Seoulbones Dark
│ │ ├── Seoulbones Light
│ │ ├── Tinacious Design Dark
│ │ ├── Tinacious Design Light
│ │ ├── TokyoNight
│ │ ├── TokyoNight Day
│ │ ├── TokyoNight Moon
│ │ ├── TokyoNight Night
│ │ ├── TokyoNight Storm
│ │ ├── Tomorrow
│ │ ├── Tomorrow Night
│ │ ├── Tomorrow Night Blue
│ │ ├── Tomorrow Night Bright
│ │ ├── Tomorrow Night Burns
│ │ ├── Tomorrow Night Eighties
│ │ ├── Xcode Dark
│ │ ├── Xcode Dark hc
│ │ ├── Xcode Light
│ │ ├── Xcode Light hc
│ │ ├── Zenbones Dark
│ │ ├── Zenbones Light
│ │ ├── Zenwritten Dark
│ │ ├── Zenwritten Light
│ │ ├── iTerm2 Solarized Dark
│ │ ├── iTerm2 Solarized Light
│ │ ├── iTerm2 Tango Dark
│ │ └── iTerm2 Tango Light
│ ├── Sources/
│ │ ├── CGhostty/
│ │ │ └── module.modulemap
│ │ └── GhosttyKit/
│ │ ├── Clipboard.swift
│ │ ├── Ghostty.Action.swift
│ │ ├── Ghostty.App.swift
│ │ ├── Ghostty.Input.swift
│ │ ├── Ghostty.Key.swift
│ │ ├── Ghostty.KeyEvent.swift
│ │ ├── Ghostty.Mods.swift
│ │ ├── Ghostty.MouseEvent.swift
│ │ ├── Ghostty.Surface.swift
│ │ ├── GhosttyIMEHandler.swift
│ │ ├── GhosttyInputHandler.swift
│ │ ├── GhosttyProgressState.swift
│ │ ├── GhosttyRenderingSetup.swift
│ │ ├── GhosttyTerminalView.swift
│ │ ├── GhosttyThemeLoader.swift
│ │ ├── TerminalScrollView.swift
│ │ └── TerminalTextCleaner.swift
│ └── Vendor/
│ ├── VERSION
│ └── include/
│ ├── ghostty/
│ │ ├── vt/
│ │ │ ├── allocator.h
│ │ │ ├── color.h
│ │ │ ├── key/
│ │ │ │ ├── encoder.h
│ │ │ │ └── event.h
│ │ │ ├── key.h
│ │ │ ├── osc.h
│ │ │ ├── paste.h
│ │ │ ├── result.h
│ │ │ ├── sgr.h
│ │ │ └── wasm.h
│ │ └── vt.h
│ ├── ghostty.h
│ └── module.modulemap
├── models/
│ ├── ActivityChartData.swift
│ ├── AllOverviewViewModel.swift
│ ├── CLIPathVM.swift
│ ├── ClaudeCodeVM.swift
│ ├── ClaudeUsageStatus.swift
│ ├── CodexUsageStatus.swift
│ ├── CodexVM.swift
│ ├── CommandRecord.swift
│ ├── CommandsViewModel.swift
│ ├── ConversationTurn.swift
│ ├── DateDimension.swift
│ ├── DialecticsVM.swift
│ ├── EditorApp.swift
│ ├── EnvironmentContextInfo.swift
│ ├── ExecutionPolicy.swift
│ ├── ExtensionsImportModels.swift
│ ├── ExtensionsSettingsTab.swift
│ ├── ExternalTerminalProfile.swift
│ ├── GeminiUsageStatus.swift
│ ├── GeminiVM.swift
│ ├── GitChangesViewModel.swift
│ ├── GitGraphViewModel.swift
│ ├── GitReviewTree.swift
│ ├── GlobalSearchModels.swift
│ ├── GlobalSearchViewModel.swift
│ ├── HookCommandVariableCatalog.swift
│ ├── HookEventCatalog.swift
│ ├── HookSyncWarning.swift
│ ├── Hooks.swift
│ ├── HooksViewModel.swift
│ ├── InternalSkill.swift
│ ├── LocalAuthProvider.swift
│ ├── MCPServer.swift
│ ├── MCPServersViewModel.swift
│ ├── OverviewAggregate.swift
│ ├── PathTree.swift
│ ├── Project.swift
│ ├── ProjectExtensionsModels.swift
│ ├── ProjectExtensionsViewModel.swift
│ ├── ProjectOverviewViewModel.swift
│ ├── ProjectWorkspaceMode.swift
│ ├── ProjectWorkspaceViewModel+Generation.swift
│ ├── ProjectWorkspaceViewModel.swift
│ ├── RefreshRequest.swift
│ ├── ReviewPanelState.swift
│ ├── SessionEvent.swift
│ ├── SessionLaunchProvider.swift
│ ├── SessionListViewModel+Commands.swift
│ ├── SessionListViewModel+Editor.swift
│ ├── SessionListViewModel+Intents.swift
│ ├── SessionListViewModel+Notes.swift
│ ├── SessionListViewModel+Projects.swift
│ ├── SessionListViewModel+SearchSupport.swift
│ ├── SessionListViewModel.swift
│ ├── SessionLoadScope.swift
│ ├── SessionNavigation.swift
│ ├── SessionPathConfig.swift
│ ├── SessionSource+CaseIterable.swift
│ ├── SessionSummary.swift
│ ├── SettingCategory.swift
│ ├── SidebarState.swift
│ ├── SkillsLibraryViewModel.swift
│ ├── SkillsModels.swift
│ ├── StatusBarLogEntry.swift
│ ├── StatusBarVisibility.swift
│ ├── SystemMenuVisibility.swift
│ ├── Task.swift
│ ├── TerminalCursorStyleOption.swift
│ ├── TimelineEvent.swift
│ ├── UnifiedProviderCatalog.swift
│ ├── UnifiedProviderID.swift
│ ├── UpdateViewModel.swift
│ ├── UsageProviderSnapshot.swift
│ ├── WarpTitleBuilder.swift
│ ├── WizardConversationViewModel.swift
│ ├── WizardGuard.swift
│ └── WizardModels.swift
├── notify/
│ └── NotifyMain.swift
├── payload/
│ ├── commands/
│ │ └── index.json
│ ├── hook-events.json
│ ├── hook-variables.json
│ ├── internal-skills/
│ │ ├── commands-wizard/
│ │ │ ├── SKILL.md
│ │ │ ├── prompt.md
│ │ │ └── schema.json
│ │ ├── hooks-wizard/
│ │ │ ├── SKILL.md
│ │ │ ├── prompt.md
│ │ │ └── schema.json
│ │ ├── index.json
│ │ ├── mcp-wizard/
│ │ │ ├── SKILL.md
│ │ │ ├── prompt.md
│ │ │ └── schema.json
│ │ └── skills-wizard/
│ │ ├── SKILL.md
│ │ ├── prompt.md
│ │ └── schema.json
│ ├── knowledge/
│ │ └── wizard-docs.json
│ ├── prompts/
│ │ ├── commit-message.md
│ │ ├── task-title-and-description.md
│ │ ├── task-title-only.md
│ │ └── title-and-comment.md
│ ├── providers.json
│ └── terminals.json
├── scripts/
│ ├── BUILD.md
│ ├── build-libghostty-local.sh
│ ├── create-app-bundle.sh
│ ├── gen-third-party-notices.py
│ ├── macos-build-notarized-dmg.sh
│ └── test-commands-sync.sh
├── services/
│ ├── AppLogger.swift
│ ├── AuthorizationHub.swift
│ ├── BrowserCookies/
│ │ ├── ChromeCookieImporter.swift
│ │ ├── CookieRecord.swift
│ │ ├── DataReader.swift
│ │ └── SafariCookieImporter.swift
│ ├── CLIProxyBridge.swift
│ ├── CLIProxyService.swift
│ ├── ClaudeSessionParser.swift
│ ├── ClaudeSessionProvider.swift
│ ├── ClaudeSettingsService.swift
│ ├── ClaudeUsageAPIClient.swift
│ ├── ClaudeUsageAnalyzer.swift
│ ├── ClaudeWebAPIClient.swift
│ ├── CodexAppServerProbeService.swift
│ ├── CodexConfigService.swift
│ ├── CodexFeaturesService.swift
│ ├── CodexOAuthUsageFetcher.swift
│ ├── CommandsImportService.swift
│ ├── CommandsStore.swift
│ ├── CommandsSyncService.swift
│ ├── ContextTreeshaker.swift
│ ├── DirectoryMonitor.swift
│ ├── DockOpenCoordinator.swift
│ ├── EmbeddedNotifySniffer.swift
│ ├── ExternalTerminalProfileStore.swift
│ ├── ExternalURLRouter.swift
│ ├── GeminiSessionParser.swift
│ ├── GeminiSessionProvider.swift
│ ├── GeminiSettingsService.swift
│ ├── GeminiUsageAPIClient.swift
│ ├── GhosttySessionManager.swift
│ ├── GitService.swift
│ ├── GlobalSearchService.swift
│ ├── HooksImportService.swift
│ ├── HooksStore.swift
│ ├── HooksSyncService.swift
│ ├── InternalSkillRunner.swift
│ ├── InternalSkillsRegistry.swift
│ ├── LLMHTTPService.swift
│ ├── LaunchAtLoginService.swift
│ ├── LocalServerBuiltInProvider.swift
│ ├── MCPImportService.swift
│ ├── MCPQuickTestService.swift
│ ├── MCPServersStore.swift
│ ├── MainWindowCoordinator.swift
│ ├── MenuBarController.swift
│ ├── PathTreeStore.swift
│ ├── PresetPromptsStore.swift
│ ├── ProjectExtensionsApplier.swift
│ ├── ProjectExtensionsStore.swift
│ ├── ProjectsStore.swift
│ ├── ProvidersRegistryService.swift
│ ├── RemoteSessionMirror.swift
│ ├── RemoteSessionProvider+Adapter.swift
│ ├── RemoteSessionProvider.swift
│ ├── RepoContentSearchService.swift
│ ├── RipgrepDiskCache.swift
│ ├── RipgrepRunner.swift
│ ├── SSHConfigResolver.swift
│ ├── SandboxPermissionsManager.swift
│ ├── SecurityScopedBookmarks.swift
│ ├── SessionActions+Commands.swift
│ ├── SessionActions+Config.swift
│ ├── SessionActions+FileActions.swift
│ ├── SessionActions+Terminal.swift
│ ├── SessionActions.swift
│ ├── SessionActivityTracker.swift
│ ├── SessionCacheStore.swift
│ ├── SessionCommandGenerator.swift
│ ├── SessionEnrichmentService.swift
│ ├── SessionIndexSQLiteStore.swift
│ ├── SessionIndexer.swift
│ ├── SessionNotesStore.swift
│ ├── SessionPreferencesStore.swift
│ ├── SessionProvider.swift
│ ├── SessionRipgrepStore.swift
│ ├── SessionTimelineLoader.swift
│ ├── SessionsDiagnosticsService.swift
│ ├── SkillsImportService.swift
│ ├── SkillsStore.swift
│ ├── SkillsSyncService.swift
│ ├── StatusBarLogStore.swift
│ ├── SystemNotifier.swift
│ ├── TasksStore.swift
│ ├── TimelineAttachmentDecoder.swift
│ ├── TimelineAttachmentOpener.swift
│ ├── UniImportMCPNormalizer.swift
│ ├── UpdateService.swift
│ ├── WindowStateStore.swift
│ ├── WizardDocsService.swift
│ └── WizardResponseParser.swift
├── utils/
│ ├── AppAvailability.swift
│ ├── AppDistribution.swift
│ ├── AppSandbox.swift
│ ├── CLIEnvironment.swift
│ ├── EmbeddedSessionNotification.swift
│ ├── FilenameSanitizer.swift
│ ├── FlexibleDecoders.swift
│ ├── InternalWizardPaths.swift
│ ├── MarkdownExportBuilder.swift
│ ├── ModelNameSanitizer.swift
│ ├── ProviderIconResource.swift
│ ├── ProviderIconThemeHelper.swift
│ ├── SessionPathFilter.swift
│ ├── SessionSummaryMaterialBuilder.swift
│ ├── ShellCommandRunner.swift
│ ├── TagView.swift
│ ├── TerminalFontResolver.swift
│ ├── TimelineEventClassifier.swift
│ ├── TokenFormatter.swift
│ ├── UpdateSupport.swift
│ ├── WarpTitlePrompt.swift
│ └── WindowConfigurator.swift
└── views/
├── APIKeyProviderIconView.swift
├── AboutViews.swift
├── AdvancedPathPane.swift
├── AdvancedSettingsView.swift
├── AttributedTextView.swift
├── AutoAssignSheet.swift
├── CLIProxyAdvancedPane.swift
├── CalendarMonthView.swift
├── ClaudeCodeSettingsView.swift
├── ClaudeModelMappingSheet.swift
├── CodexSettingsView.swift
├── CommandsSettingsView.swift
├── Content/
│ ├── AllOverviewView.swift
│ ├── ContentView+Detail.swift
│ ├── ContentView+DetailActionBar.swift
│ ├── ContentView+Helpers.swift
│ ├── ContentView+MainDetail.swift
│ ├── ContentView+Modifiers.swift
│ ├── ContentView+Search.swift
│ ├── ContentView+Sidebar.swift
│ ├── ContentView.swift
│ └── StatusBarOverlayView.swift
├── Controls/
│ ├── CollapseExpandButtonGroup.swift
│ ├── FontPickerButton.swift
│ ├── RainbowSpinnerView.swift
│ └── TableSpacingRemover.swift
├── ConversationTimelineView.swift
├── DiagnosticsViews.swift
├── DialecticsPane.swift
├── EditSessionMetaView.swift
├── EditorMenuHelpers.swift
├── EmbeddedTerminalView.swift
├── EquatableContainers.swift
├── ExtensionsImportSheets.swift
├── ExtensionsSettingsView.swift
├── ExternalTerminalMenuHelpers.swift
├── GeminiSettingsView.swift
├── GitChanges/
│ ├── GitChangesPanel+Browser.swift
│ ├── GitChangesPanel+Detail.swift
│ ├── GitChangesPanel+DiffTree.swift
│ ├── GitChangesPanel+Graph.swift
│ ├── GitChangesPanel+Header.swift
│ ├── GitChangesPanel+Helpers.swift
│ ├── GitChangesPanel+LeftPane.swift
│ ├── GitChangesPanel+Lifecycle.swift
│ ├── GitChangesPanel+Menus.swift
│ └── GitChangesPanel.swift
├── GitReviewSettingsView.swift
├── HookEditSheet.swift
├── HooksSettingsView.swift
├── LiveFileSizeText.swift
├── LocalAuthProviderIconView.swift
├── MCPServerTargetToggle.swift
├── MCPServersSettingsView.swift
├── ModelListEditorSheet.swift
├── NewTaskSheet.swift
├── OverviewActivityChart.swift
├── OverviewCard.swift
├── PathTreeView.swift
├── ProjectAgentsView.swift
├── ProjectOverviewView.swift
├── ProjectSpecificOverviewContainerView.swift
├── ProjectsListView.swift
├── ProviderEditorView.swift
├── ProviderIconView.swift
├── ProvidersSettingsView.swift
├── RecentSessionsListView.swift
├── RemoteHostsSettingsView.swift
├── SandboxApprovalEditor.swift
├── SandboxPermissionsView.swift
├── Search/
│ ├── GlobalSearchPanel.swift
│ └── ToolbarSearchField.swift
├── SessionDetailView.swift
├── SessionListColumnView.swift
├── SessionListRowView.swift
├── SessionNavigationView.swift
├── SessionPathGroup.swift
├── SessionPathRow.swift
├── SessionsPathPane.swift
├── SettingsCompatibility.swift
├── SettingsTabContent.swift
├── SettingsView.swift
├── SimpleProviderPicker.swift
├── Skills/
│ └── SkillPackageExplorerView.swift
├── SkillsSettingsView.swift
├── SplitControls.swift
├── TaskListView.swift
├── TripleUsageDonutView.swift
├── UnavailableStateView.swift
├── UnifiedProviderPickerView.swift
├── UsageStatusControl.swift
└── Wizard/
├── CommandWizardSheet.swift
├── HookWizardSheet.swift
├── MCPWizardSheet.swift
├── SkillWizardSheet.swift
└── WizardConversationView.swift
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.build/
.swiftpm/
.DS_Store
artifacts/
build/
build-mas/
logs/
.xcuserstate
._*
CodMate.app
# Xcode per-user state and caches
**/xcuserdata/**
**/*.xcuserstate
**/*.xcbkptlist
CodMate.xcodeproj/project.xcworkspace/xcuserdata/
codmate.xcodeproj/project.xcworkspace/xcuserdata/
CodMate.xcodeproj/xcuserdata/
codmate.xcodeproj/xcuserdata/
# Vendored or local packages to exclude
SwiftTerm/
dist/
.env
.comate
.serena
# Project-level AI assistant configs (generated at runtime)
.claude/
.codex/
.gemini/
# Sisyphus (agent) workspace
.sisyphus/
# Local build artifacts
libghostty.a
================================================
FILE: .vscode/launch.json
================================================
{
"configurations": [
{
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:CodMate}",
"name": "Debug CodMate",
"program": "${workspaceFolder:CodMate}/.build/debug/CodMate",
"preLaunchTask": "swift: Build Debug CodMate"
},
{
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:CodMate}",
"name": "Release CodMate",
"program": "${workspaceFolder:CodMate}/.build/release/CodMate",
"preLaunchTask": "swift: Build Release CodMate"
}
]
}
================================================
FILE: AGENTS.md
================================================
CodMate – AGENTS Guidelines
Purpose
- This document tells AI/code agents how to work inside the CodMate repository (macOS desktop GUI for Codex session management).
- Scope: applies to the entire repo. Prefer macOS SwiftUI/AppKit APIs; avoid iOS‑only placements or components.
Architecture
- App type: macOS SwiftUI app (min macOS 13.5). SwiftPM-only build (no Xcode project).
- Layering (MVVM):
- Models: pure data structures (SessionSummary, SessionEvent, DateDimension, SessionLoadScope, …)
- Services: IO and side effects (SessionIndexer, SessionCacheStore, SessionActions, SessionTimelineLoader, LLMClient)
- ViewModels: async orchestration, filtering, state (SessionListViewModel)
- Views: SwiftUI views only (no business logic)
UI Rules (macOS specific)
- Use macOS SwiftUI and AppKit bridges; do NOT use iOS‑only placements such as `.navigationBarTrailing`.
- Settings uses macOS 15's new TabView API (`Tab("…", systemImage: "…")`) when available; provide a macOS 13.5/14 fallback with `tabItem` + `tag`. Container padding is unified (horizontal 16pt, top 16pt).
- Tab content uniformly uses `SettingsTabContent` container (top-aligned, overall 8pt padding) to ensure consistent layout and spacing across pages.
- Notifications is a top-level Settings page between Terminal and Providers; sections are Common, Codex, Claude Code, and Gemini CLI. Common toggles commit message, title/comment, and copy New/Resume command notifications.
- Providers has been separated from the Codex tab into a top-level Settings page: Settings › Providers manages API key providers, OAuth providers, and Codex/Claude bindings; Settings › Codex only retains Runtime/Privacy/Raw Config (notifications live in Settings › Notifications).
- OAuth providers (Codex/Claude/Gemini/Antigravity/Qwen) are added from the Providers “Add” menu and appear under an OAuth list section with login status and info actions.
- CLI Proxy API status, reroute, and public access live under Providers as shared capabilities; deep diagnostics and installation details live under Settings › Advanced › CLI Proxy API.
- Built-in providers are auto-loaded from an app-bundled `payload/providers.json` (managedByCodMate=true). This avoids hardcoding and lets users simply provide API keys; base URLs/models come pre-filled. The list merges bundled entries with `~/.codmate/providers.json` (user overrides win).
- Schema note: use a single provider-level `envKey` (preferred) for both Codex and Claude Code connectors. Connector-level `envKey` remains tolerated for backward compatibility but is considered deprecated and will be ignored at save time to avoid duplication.
- Extensions page (aligned with Providers style):
- Settings › Extensions replaces the old MCP Server page (icon: puzzlepiece.extension).
- Tab 1: MCP Servers (existing list/editor/Uni‑Import UI kept as-is inside the tab); add an Import button to scan Home MCP configs into CodMate.
- Tab 2: Skills (left list + right details split; Add menu supports folder/zip/URL; auto‑sync on changes); add an Import button to scan Home skills into CodMate.
- Commands tab includes Add and Import buttons (Import scans Home command folders into CodMate).
- Import sheets show a vertical list; each row has a right‑aligned strategy control (Skip/Overwrite/Rename) and a context menu “Open in…” to review source files.
- MCP Servers tab keeps: enable toggle on left, edit on right, fixed "Add" button, Uni‑Import preview and confirmation.
- Advanced capabilities (MCPMate download and instructions) remain as a footer/section in MCP Servers tab.
- Search: prefer a toolbar `SearchField` in macOS, not `.searchable` when exact placement (far right) matters.
- Toolbars: place refresh as the last ToolbarItem to pin it at the far right. Keep destructive actions in the detail pane, not in the main toolbar. Command+R and the refresh button also invalidate and recompute global sidebar statistics (projects/path tree and calendar day counts) to reflect new sessions immediately.
- Menu Bar (status item): keep it lightweight with status + quick actions. Show provider/model/sandbox/approval, New/Resume/Search/Open, Recent Projects/Sessions (max 5), Usage summary, Provider switch, Settings/Quit; avoid destructive actions.
- Sidebar (left):
- Top (fixed): "All Sessions" row showing total count and selection state.
- Middle (scrollable): path tree built from `cwd` counts. Rows are compact: default min row height 18, small control size, reduced insets. Single-click selects/expands; double-click applies filter (enter the directory).
- Projects mode mirrors the compact list style; Cmd-click toggles multi-selection so users can filter sessions by several projects simultaneously (descendants remain included).
- Bottom (fixed): calendar month view (240pt height) with per-day counts (created/last-updated switch). Always pinned to the bottom with 8pt spacing above. Supports multi-select via Command-click to toggle multiple days; plain click selects a single day (click the same day to clear).
- Only the middle path tree scrolls; top "All Sessions" and bottom calendar remain fixed.
- Sidebar width: min 220pt, max 25% of window width, ideal 260pt.
- Content (middle):
- Default scope loads “today” only for speed.
- Sorting picker is left‑aligned with list content.
- Each row shows: title, timestamps/duration, snippet, and compact metrics (user/assistant/tool/reasoning).
- Status bar (bottom console):
- Docked console bar spans the right-side area (list + detail); sidebar stays full height.
- Resizable via a drag handle; single-line header collapses/expands to multi-line log history.
- Auto mode collapses when idle (no interaction); View menu supports Always Show/Hide.
- Detail (right):
- Sticky action bar at top: Resume, Reveal in Finder, Delete, Export Markdown.
- Add “New” button next to Resume to start a fresh Codex session using the current session’s working directory and model.
- When an embedded terminal is running, show a “Prompts” button beside the folder (Reveal in Finder) icon. Clicking opens a searchable popover of preset command texts; selecting one inserts it into the embedded terminal input (does not auto-execute). User presses Return to run.
- Project-level Extensions are configured in **Edit Project**: tabs are General, Profile, MCP Servers, Skills (auto‑sync; Gemini project-level toggles disabled). MCP Servers/Skills tabs include Import buttons that scan the project directory. Edit Project window should be resizable.
- Review mode: the list.bullet.rectangle button toggles a full-area Review view (third mode, alongside Conversation and Internal Terminal). In Review mode the detail area is fully occupied by a Git Changes surface. It:
- Auto-detects the Git repo at the session’s working directory (uses `/usr/bin/env git` and a robust PATH).
- Lists changed files with stage/unstage toggles and shows a unified diff or a raw file preview (updates on save). Preview is text-only in phase 1.
- Provides a commit box. In full-area mode it uses a multi-line editor with more space.
- Repository authorization is on-demand: when opening Review, the app resolves the repository root (the folder containing `.git`) and, if needed, prompts the user with an NSOpenPanel to authorize that folder via a security-scoped bookmark. The Settings page no longer lists authorized repositories; authorization and revoke are managed inline in the Review header.
- “Task Instructions” uses a DisclosureGroup; load lazily when expanded.
- Conversation timeline uses LazyVStack; differentiate user/assistant/tool/info bubbles.
- Timeline & Markdown visibility: Settings › General provides per-surface checkboxes to choose which message types are shown in the conversation timeline and included when exporting Markdown. Defaults: Timeline shows User, Assistant, Reasoning, and Code Edit; Tool Invocation, Token Usage, and Other Info are off by default. Markdown includes only User and Assistant. Environment Context and Turn Context are surfaced in dedicated sections and not configurable; Task Instructions remain in the detail DisclosureGroup; Ghost Snapshot is ignored. Code edits are surfaced as their own message type (extracted from tool calls) and have a separate toggle.
- Turn Context is surfaced in the Environment Context card and is not exposed as a separate toggle or timeline item.
- Context menu in list rows adds: “Generate Title & 100-char Summary” to run LLM on-demand for the selected session.
- Embedded Terminal: One live shell per session when resumed in-app; switching sessions in the middle list switches the attached terminal. The shell keeps running when you navigate away. “Return to history” closes the running shell for the focused session.
- Prompt picker: When embedded terminal is running, a Prompts button opens a searchable list. Prompts are merged from per-project `.codmate/prompts.json` (if present) and `~/.codmate/prompts.json` (user), de-duplicated by command, then layered with a few built‑ins. Items accept either `{ "label": "…", "command": "…" }` or a plain string (used for both). Selection inserts into the terminal input without executing. The header wrench button opens the preferred file (project if exists, else user). Typing a new command shows “Add …” to create a prompt in the preferred file. Deleting a built‑in prompt records it in a hidden list (`prompts-hidden.json` at project if project prompts exist, else at user), which suppresses that built‑in in the UI.
- Terminal shortcuts: (none for now). Clearing via shortcut is not implemented.
Performance Contract
- Fast path indexing: memory‑mapped reads; parse first ~400 lines + read tail ~64KB to correct `lastUpdatedAt`.
- Background enrichment: full parse in a constrained task group; batch UI updates (≈10 items per flush).
- Full‑text search: chunked stream scan (128 KB), case‑insensitive; avoid `lowercased()` on whole file.
- Disk cache: `~/Library/Caches/CodMate/sessionIndex-v1.json` keyed by path+mtime; prefer cache hits before parsing.
- Sidebar statistics (calendar/tree) must be global and computed independently of the current list scope to keep navigation usable.
- Embedded terminals: keep shells alive when not visible; only render the selected session’s terminal. Users explicitly close shells via “Return to history” to release resources.
Coding Guidelines
- Concurrency: use `actor` for services managing shared caches; UI updates on MainActor only.
- Cancellation: cancel previous tasks on new search/scope changes. Name tasks (`fulltextTask`, `enrichmentTask`) and guard `Task.isCancelled` in loops.
- File IO: prefer `Data(mappedIfSafe:)` or `FileHandle.read(upToCount:)`; never load huge files into Strings.
- Error handling: surface user‑visible errors through `ViewModel.errorMessage` and macOS system notifications/alerts; do not crash the UI.
- Testability: keep parsers and small helpers pure; avoid `Process()`/AppKit in ViewModel.
- Provider Icon Theme Handling:
- Use `ProviderIconThemeHelper` (in `utils/ProviderIconThemeHelper.swift`) for consistent dark/light mode icon adaptation.
- Icons that are black or dark-colored (ChatGPTIcon/Codex, KimiIcon, ZaiIcon, OpenRouterIcon) must be inverted in dark mode for visibility.
- For SwiftUI views: use `.providerIconTheme(iconName:)` modifier or `ProviderIconDarkModeModifier` directly.
- For AppKit menus: use `ProviderIconThemeHelper.menuImage(named:)` which automatically handles resizing and dark mode inversion.
- Do NOT manually check dark mode and invert icons; always use the helper to ensure consistency across the app.
CLI Integration (codex)
- Prefer invoking via `/usr/bin/env codex` (or `claude`) so resolution happens on system `PATH`.
- Allow optional user-specified command path overrides; use the override when valid, otherwise fall back to PATH resolution.
- New/Resume command strings must use the bare CLI name unless the user explicitly set a CLI Command Path override; only then emit an absolute path.
- Always set `PATH` to include `/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin` before launching for robustness.
- `resume` runs with `currentDirectoryURL` = original session `cwd` when it exists (fallback: log file directory).
- New command options exposed in Settings › Command:
- Sandbox policy (`-s/--sandbox`): `read-only`, `workspace-write`, `danger-full-access`.
- Approval policy (`-a/--ask-for-approval`): `untrusted`, `on-failure`, `on-request`, `never`.
- `--full-auto` convenience alias (maps to `-a on-failure` + `--sandbox workspace-write`).
- `--dangerously-bypass-approvals-and-sandbox` (overrides other flags; only for externally sandboxed envs).
- UI adds a "Copy real command" button in the detail action bar when the embedded terminal is active; this copies the exact `codex resume <id>` invocation including flags.
- Provide a “New” command (detail toolbar) that launches `codex` in the session’s working directory while preserving the configured sandbox/approval defaults and `SessionSummary.model`.
Codex Settings
- Settings › Codex only manages Codex CLI runtime-related configuration (Model & Reasoning, Sandbox & Approvals, Notifications, Privacy, Raw Config).
- Providers page is independent: Settings › Providers (cross-application shared, for Codex and Claude Code selection/configuration, including OAuth).
- Provider selection uses the unified provider picker (same list as Git Review), backed by CLI Proxy API when chosen; Auto keeps CLI defaults.
- Provider tab includes a separate Model List setting under Active Provider with an editor to add/remove model IDs per provider (empty = default list).
- Notifications: TUI notifications toggle; system notifications bridge via the bundled Swift `codmate-notify` helper (installed to `~/Library/Application Support/CodMate/bin/`).
- Privacy: expose `shell_environment_policy`, reasoning visibility, OTEL exporter; do not surface history persistence in phase 1.
- Projects auto‑create a same‑id Profile on creation; renaming a project synchronizes the profile name. Conflict prompts are required.
Claude Settings
- Settings › Claude splits into Provider, Runtime, Notifications, and Raw Config tabs.
- Provider selection uses the unified provider picker (same list as Git Review), backed by CLI Proxy API when chosen; Auto keeps CLI defaults.
- Provider tab includes a Model List setting with Default/Opus/Sonnet/Haiku mappings (edited via the mapping sheet); mappings write to Claude env keys in `~/.claude/settings.json`.
- Notifications tab mirrors Codex UX: single toggle to install/remove macOS notification hooks, health indicator, and self-test button.
- Hooks write to `~/.claude/settings.json` under `hooks.Notification` and `hooks.Stop`, pointing to `/usr/bin/open -g "codmate://notify?source=claude&event=…&title64=…&body64=…"`.
- Always request Home directory access through `AuthorizationHub` before mutating the hooks file when sandboxed.
Gemini Settings
- Settings › Gemini adds a Provider tab with the unified provider picker (same list as Git Review); Gemini CLI model selection remains in the Model tab.
- Provider tab includes a Model List setting for CLI Proxy providers; the Model tab remains the source of truth for Gemini CLI model selection.
Session Metadata (Rename/Comment)
- Users can rename any session and attach a short comment.
- Trigger: click the title at the top-left of the detail pane to open the editor.
- Persistence: stored per file under `~/.codmate/notes/<sessionId-sanitized>.json`. A first-run migration copies entries from the legacy Application Support JSON and migrates from the legacy `~/.codex/notes` directory when present.
- Display: the name replaces the ID in the detail header and list; the comment is used as the row snippet when present.
About Surface
- Settings › About shows app version, build timestamp (derived from the app executable’s modification date), and project URL.
- Settings › About includes update checking/downloading for non-App Store builds and guides manual install.
- “About CodMate” menu item should open Settings pre-selecting the About tab.
- Include an “Open Source Licenses” entry that displays `THIRD-PARTY-NOTICES.md` (bundled if present; falls back to repository URL if missing).
Diagnostics
- Settings › General adds “Diagnose Data Directories” to probe Sessions (`~/.codex/sessions`, `.jsonl`), Notes (`~/.codmate/notes`, `.json`), and Projects (`~/.codmate/projects`, `.json`) — existence, counts, sample files, and enumerator errors.
- Also probes Claude Code sessions (`~/.claude/projects`, `.jsonl`) for presence and counts.
- When the current root has 0 sessions but the default has files, the UI suggests switching to the default path.
- Users can “Save Report…” to export a JSON diagnostics file for troubleshooting.
File/Folder Layout
- assets/ – Assets + Info.plist
- CodMateApp.swift – App entry point
- models/ – data types
- services/ – IO, indexing, cache, codex actions
- utils/ – helpers
- views/ – SwiftUI views only
- payload/ – bundled presets (providers/terminals)
- notify/ – Swift command-line helper (codmate-notify)
- SwiftTerm/ – embedded terminal dependency (local package)
- .github/workflows/ – CI + release pipelines
- scripts/ – build/packaging scripts
- docs/ – design notes and investigation docs
Advanced Page
- Settings › Advanced (between MCP Server and About) uses a TabView with Path, CLI Proxy API, and Dialectics tabs.
- Path tab:
- File paths (Projects/Notes) and CLI command path overrides (codex/claude/gemini)
- CLI environment snapshot (auto-detected paths + PATH)
- CLI Proxy API tab:
- Binary location + install/reinstall
- Config/Auth/Logs paths (reveal in Finder)
- Dialectics tab aggregates diagnostics:
- Codex sessions root probe (current vs default), counts and sample files, enumerator errors
- Claude sessions directory probe (default path), counts and samples
- Notes and Projects directories probes (current vs default), counts and sample files
- Does not mutate config automatically; changes only happen via explicit user actions
Build & Run
- SwiftPM is the source of truth. Use `swift build` to validate compile.
- Build the app bundle with `make app` or `BASE_VERSION=1.2.3 ./scripts/create-app-bundle.sh`.
- Build a DMG with `make dmg` or `BASE_VERSION=1.2.3 ./scripts/macos-build-notarized-dmg.sh`.
Commit Conventions
Follow conventional commits pattern:
- `feat:` - New feature
- `fix:` - Bug fix
- `docs:` - Documentation change
- `style:` - Formatting, missing semicolons, etc.
- `refactor:` - Code change that neither fixes a bug nor adds a feature
- `perf:` - Performance improvement
- `test:` - Adding or updating tests
- `chore:` - Changes to build process or auxiliary tools
> Tip: Before writing your commit message, first try to summarize the main theme and motivation of your staged changes (the "why" and "core focus"). This helps ensure your commit message highlights the real intent and impact of the change, making the subject and body more focused and valuable. For AI-assisted commit generation, always let the AI attempt this summary step first.
Commit Subject Focus Principles
- The commit subject (title) should concisely highlight the "core focus" or the most important substantive change of the commit.
- Avoid generic descriptions like "update docs" or "fix bug"; the title should make the main purpose and impact of the change clear at a glance.
- If the change involves bilingual documentation, syncing with code implementation, or architectural adjustments, make this explicit in the title.
- Recommended format: "what was done + why/for what". For example:
- `docs: sync EN/CN README and align config docs with codebase`
- `feat: support multi-suit config management for flexible scenarios`
- `fix: resolve SSE connection issue in bridge module`
Example:
```
Feature: Expand MCP API documentation with detailed instance and system management
Where:
- Updated README.md files across the API, handlers, models, and routes directories to include comprehensive details on new instance and system management functionalities.
- Added specific sections for MCP handlers, models, and routes to clarify the operations available for managing servers and instances.
Why:
- To enhance the clarity and usability of the API documentation, ensuring users can easily understand and utilize the new features.
What:
- Documented new API endpoints for instance management, including listing, retrieving, and managing instance health.
- Provided detailed descriptions of the handlers and models associated with MCP server and instance management.
- Updated routing information to reflect the new structure and capabilities of the API.
Issues:
- This documentation update supports ongoing development and user engagement by providing clear guidance on the API's capabilities.
```
PR / Change Policy for Agents
- Keep changes minimal and focused; do not refactor broadly without need.
- Maintain macOS compliance first; avoid iOS‑only modifiers/placements.
- When changing UI structure, update this AGENTS.md and the in‑app Settings if applicable.
- Validate performance: measure large session trees; ensure first paint is fast and enrichment is incremental.
Known Pitfalls
- `.searchable` may hijack the trailing toolbar slot on macOS; use `SearchField` in a `ToolbarItem` to control placement.
- OutlineGroup row height is affected by control size and insets; tighten with `.environment(\.defaultMinListRowHeight, 18)` and `.listRowInsets(...)` inside the row content.
- Swift KeyPath escaping when patching: do not double-escape the leading backslash in typed key paths. Always write single-backslash literals like `\ProvidersVM.codexBaseURL` in Swift sources. The apply_patch tool takes plain text; extra escaping (e.g., `\\ProvidersVM...`) will compile-fail and break symbol discovery across files.
- Prefer dot-shorthand KeyPaths in Swift (clearer, avoids escaping pitfalls): use `\.codexBaseURL` instead of `\ProvidersVM.codexBaseURL` when the generic context already constrains the base type (e.g., `ReferenceWritableKeyPath<ProvidersVM, String>`). This makes patches safer and reduces chances of accidental extra backslashes.
- String interpolation gotcha: do not escape quotes inside `\( ... )`. Write `Text("Codex: \(dict["codex"] ?? "")")`, not `Text("Codex: \(dict[\"codex\"] ?? \"\")")`. Escaping quotes inside interpolation confuses the outer string literal and can cause “Unterminated string literal”.
- SwiftUI view extensions live in separate files; properties that those extensions need must be internal (default) or `fileprivate`. Marking them `private` will make the extension fail to build (“is inaccessible due to 'private'”).
- Toolbar popovers must manage their own `@State` visibility. Binding `isPresented` directly to a view model flag tied to focus/search states causes the popover to close immediately when other columns steal focus or the toolbar re-renders.
================================================
FILE: CodMateApp.swift
================================================
import SwiftUI
import GhosttyKit
#if os(macOS)
import AppKit
#endif
@main
struct CodMateApp: App {
#if os(macOS)
@NSApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
#endif
@StateObject private var listViewModel: SessionListViewModel
@StateObject private var preferences: SessionPreferencesStore
@State private var settingsSelection: SettingCategory = .general
@State private var extensionsTabSelection: ExtensionsSettingsTab = .commands
@Environment(\.openWindow) private var openWindow
init() {
let prefs = SessionPreferencesStore()
let listVM = SessionListViewModel(preferences: prefs)
_preferences = StateObject(wrappedValue: prefs)
_listViewModel = StateObject(wrappedValue: listVM)
// Prepare user notifications early so banners can show while app is active
SystemNotifier.shared.bootstrap()
// Setup menu bar before windows appear
#if os(macOS)
MenuBarController.shared.configure(viewModel: listVM, preferences: prefs)
#endif
// In App Sandbox, restore security-scoped access to user-selected directories
SecurityScopedBookmarks.shared.restoreAndStartAccess()
// Restore all dynamic bookmarks (e.g., repository directories for Git Review)
SecurityScopedBookmarks.shared.restoreAllDynamicBookmarks()
// Restore and check sandbox permissions for critical directories
Task { @MainActor in
SandboxPermissionsManager.shared.restoreAccess()
}
// Sync launch at login state with system
Task { @MainActor in
LaunchAtLoginService.shared.syncWithPreferences(prefs)
}
// Daily update check (non-App Store builds only)
Task {
_ = await UpdateService.shared.checkIfNeeded(trigger: .appLaunch)
}
// Log startup info to Status Bar
Task { @MainActor in
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown"
AppLogger.shared.info("CodMate v\(version) started", source: "App")
}
}
var bodyCommands: some Commands {
Group {
CommandGroup(replacing: .appInfo) {
Button("About CodMate") { presentSettings(for: .about) }
}
CommandGroup(replacing: .appSettings) {
Button("Settings…") { presentSettings(for: .general) }
.keyboardShortcut(",", modifiers: [.command])
}
CommandGroup(after: .appSettings) {
Button("Global Search…") {
NotificationCenter.default.post(name: .codMateFocusGlobalSearch, object: nil)
}
.keyboardShortcut("f", modifiers: [.command])
}
// Integrate actions into the system View menu
CommandGroup(after: .sidebar) {
Button(action: {
NotificationCenter.default.post(
name: .codMateRefreshRequested,
object: nil,
userInfo: RefreshRequest.userInfo(for: .context)
)
}) {
Label("Refresh", systemImage: "arrow.clockwise")
}
.keyboardShortcut("r", modifiers: [.command])
Button(action: {
NotificationCenter.default.post(
name: .codMateRefreshRequested,
object: nil,
userInfo: RefreshRequest.userInfo(for: .global)
)
}) {
Label("Full Refresh", systemImage: "arrow.triangle.2.circlepath")
}
.keyboardShortcut("r", modifiers: [.command, .option])
Button(action: {
NotificationCenter.default.post(name: .codMateToggleSidebar, object: nil)
}) {
Label("Toggle Sidebar", systemImage: "sidebar.left")
}
.keyboardShortcut("1", modifiers: [.command])
Button(action: {
NotificationCenter.default.post(name: .codMateToggleList, object: nil)
}) {
Label("Toggle Session List", systemImage: "sidebar.leading")
}
.keyboardShortcut("2", modifiers: [.command])
Divider()
Button(action: {
withAnimation {
if preferences.statusBarVisibility == .hidden {
preferences.statusBarVisibility = .auto
} else {
preferences.statusBarVisibility = .hidden
}
}
}) {
if preferences.statusBarVisibility == .hidden {
Label("Show Status Bar", systemImage: "rectangle.bottomthird.inset.filled")
} else {
Label("Hide Status Bar", systemImage: "rectangle.bottomthird.inset.filled")
}
}
.keyboardShortcut("3", modifiers: [.command])
}
// Override Cmd+Q to use smart quit behavior
CommandGroup(replacing: .appTermination) {
Button("Quit CodMate") {
MenuBarController.shared.handleQuit()
}
.keyboardShortcut("q", modifiers: [.command])
}
}
}
var body: some Scene {
// Use Window instead of WindowGroup to enforce single instance
Window("CodMate", id: "main") {
ContentView(viewModel: listViewModel)
.frame(minWidth: 880, minHeight: 600)
.onReceive(NotificationCenter.default.publisher(for: .codMateOpenSettings)) { note in
let raw = note.userInfo?["category"] as? String
if let raw, let cat = SettingCategory(rawValue: raw) {
settingsSelection = cat
if cat == .mcpServer,
let tab = note.userInfo?["extensionsTab"] as? String,
let parsed = ExtensionsSettingsTab(rawValue: tab) {
extensionsTabSelection = parsed
}
} else {
settingsSelection = .general
}
if !bringWindow(identifier: "CodMateSettingsWindow") {
openWindow(id: "settings")
}
}
.onReceive(NotificationCenter.default.publisher(for: .codMateOpenMainWindow)) { _ in
// Window is singleton, so openWindow is idempotent
if !bringWindow(identifier: "CodMateMainWindow") {
openWindow(id: "main")
}
}
}
.defaultSize(width: 1200, height: 780)
.windowToolbarStyle(.unified) // Prevent toolbar KVO issues with Window singleton
.handlesExternalEvents(matching: []) // Prevent URL scheme from triggering new window creation
.commands { bodyCommands }
#if os(macOS)
Window("Settings", id: "settings") {
SettingsWindowContainer(
preferences: preferences,
listViewModel: listViewModel,
selection: $settingsSelection,
extensionsTab: $extensionsTabSelection
)
}
.defaultSize(width: 800, height: 640)
.windowStyle(.titleBar)
.windowToolbarStyle(.automatic)
.windowResizability(.contentMinSize)
.handlesExternalEvents(matching: []) // Prevent URL scheme from triggering new window creation
#endif
}
private func presentSettings(for category: SettingCategory) {
settingsSelection = category
if category == .mcpServer {
extensionsTabSelection = .mcp
}
#if os(macOS)
NSApplication.shared.activate(ignoringOtherApps: true)
#endif
if !bringWindow(identifier: "CodMateSettingsWindow") {
openWindow(id: "settings")
}
}
private func bringWindow(identifier: String) -> Bool {
#if os(macOS)
let id = NSUserInterfaceItemIdentifier(identifier)
if let window = NSApplication.shared.windows.first(where: { $0.identifier == id }) {
window.makeKeyAndOrderFront(nil)
return true
}
#endif
return false
}
}
private struct SettingsWindowContainer: View {
let preferences: SessionPreferencesStore
let listViewModel: SessionListViewModel
@Binding var selection: SettingCategory
@Binding var extensionsTab: ExtensionsSettingsTab
var body: some View {
SettingsView(preferences: preferences, selection: $selection, extensionsTab: $extensionsTab)
.environmentObject(listViewModel)
}
}
#if os(macOS)
@MainActor
final class AppDelegate: NSObject, NSApplicationDelegate {
private var suppressNextReopenActivation = false
private var suppressResetTask: Task<Void, Never>? = nil
func applicationDidFinishLaunching(_ notification: Notification) {
// Set activation policy based on saved preference
// Default to .visible (show Dock icon) unless user explicitly chose "Menu Bar Only"
let defaults = UserDefaults.standard
let rawVisibility = defaults.string(forKey: "codmate.systemMenu.visibility") ?? "visible"
let visibility = SystemMenuVisibility(rawValue: rawVisibility) ?? .visible
switch visibility {
case .menuOnly:
// Menu bar only mode - hide Dock icon
NSApp.setActivationPolicy(.accessory)
case .hidden, .visible:
// Show Dock icon so user can access the app
NSApp.setActivationPolicy(.regular)
}
// Start CLI Proxy Service if available
Task { @MainActor in
if CLIProxyService.shared.isBinaryInstalled {
do {
try await CLIProxyService.shared.start()
AppLogger.shared.info("CLIProxyAPI started successfully", source: "AppDelegate")
} catch {
// Get detailed logs from the service
let serviceLogs = CLIProxyService.shared.logs
let recentLogs = serviceLogs.split(separator: "\n").suffix(10).joined(separator: "\n")
AppLogger.shared.error("Failed to start CLIProxyAPI: \(error.localizedDescription)", source: "AppDelegate")
if !recentLogs.isEmpty {
AppLogger.shared.error("Recent service logs:\n\(recentLogs)", source: "AppDelegate")
}
CLIProxyService.shared.lastError = error.localizedDescription
}
} else {
AppLogger.shared.warning("CLIProxyAPI binary not installed, service will not start", source: "AppDelegate")
}
}
}
func application(_ application: NSApplication, open urls: [URL]) {
print("🔗 [AppDelegate] Received URLs: \(urls)")
print("🪟 [AppDelegate] Current windows count: \(application.windows.count)")
print("🪟 [AppDelegate] Visible windows: \(application.windows.filter { $0.isVisible }.count)")
let fileURLs = urls.filter { $0.isFileURL }
let nonFileURLs = urls.filter { !$0.isFileURL }
if let directoryURL = firstDirectoryURL(in: fileURLs) {
handleDockFolderDrop(directoryURL)
}
if nonFileURLs.contains(where: { $0.scheme?.lowercased() == "codmate" && ($0.host ?? "").lowercased() == "notify" }) {
suppressNextReopenActivation = true
suppressResetTask?.cancel()
suppressResetTask = Task { @MainActor [weak self] in
try? await Task.sleep(nanoseconds: 1_000_000_000)
self?.suppressNextReopenActivation = false
}
}
if !nonFileURLs.isEmpty {
ExternalURLRouter.handle(nonFileURLs)
}
}
func application(_ sender: NSApplication, openFile filename: String) -> Bool {
handleDockFileOpenPaths([filename])
}
func application(_ sender: NSApplication, openFiles filenames: [String]) {
let handled = handleDockFileOpenPaths(filenames)
sender.reply(toOpenOrPrint: handled ? .success : .failure)
}
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool)
-> Bool
{
print("🔄 [AppDelegate] applicationShouldHandleReopen called, hasVisibleWindows: \(flag)")
if suppressNextReopenActivation {
suppressNextReopenActivation = false
return true
}
// Delegate to MenuBarController for unified window activation logic
// This ensures consistent behavior between Dock clicks and menu bar actions
MenuBarController.shared.handleDockIconClick()
// Always return true to prevent the system from creating new windows
// This is particularly important for notification forwarding triggered by URL scheme (codmate://)
return true
}
func applicationWillTerminate(_ notification: Notification) {
// Stop CLI Proxy Service
CLIProxyService.shared.stop()
// Clean up Ghostty sessions
// Note: Ghostty manages its own cleanup via deinit
// No explicit session termination needed here
}
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
// Ghostty sessions will be cleaned up automatically
// No need for confirmation dialog
return .terminateNow
}
private func firstDirectoryURL(in urls: [URL]) -> URL? {
for url in urls {
guard url.isFileURL else { continue }
var isDirectory: ObjCBool = false
if FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory),
isDirectory.boolValue {
return url.standardizedFileURL
}
}
return nil
}
@MainActor
@discardableResult
private func handleDockFileOpenPaths(_ paths: [String]) -> Bool {
let urls = paths.map { URL(fileURLWithPath: $0) }
guard let directoryURL = firstDirectoryURL(in: urls) else { return false }
handleDockFolderDrop(directoryURL)
return true
}
@MainActor
private func handleDockFolderDrop(_ url: URL) {
let directory = url.path
let name = url.lastPathComponent
guard !directory.isEmpty else { return }
MenuBarController.shared.handleDockIconClick()
NotificationCenter.default.post(name: .codMateOpenMainWindow, object: nil)
Task {
await waitForMainWindow()
DockOpenCoordinator.shared.enqueueNewProject(directory: directory, name: name)
}
}
@MainActor
private func waitForMainWindow() async {
if MainWindowCoordinator.shared.hasAttachedWindow { return }
for _ in 0..<20 {
try? await Task.sleep(nanoseconds: 100_000_000)
if MainWindowCoordinator.shared.hasAttachedWindow { return }
}
}
}
#endif
================================================
FILE: Ghostty-header.h
================================================
//
// Ghostty-header.h
// CodMate
//
// Bridging header to expose Ghostty C API to Swift
//
#ifndef Ghostty_header_h
#define Ghostty_header_h
// Import the main Ghostty C API
// Note: ghostty.h already includes all necessary definitions
// Do NOT include ghostty/vt.h as it causes duplicate enum definitions
// NOTE: This file is excluded from Package.swift and may not be in use.
// The correct path is now ghostty/Vendor/include/ghostty.h
#import "ghostty/Vendor/include/ghostty.h"
#endif /* Ghostty_header_h */
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2025 Loocor
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: Makefile
================================================
.PHONY: help build release test app dmg zip clean run debug debug-logs debug-app debug-file notices
APP_NAME := CodMate
VER ?= 0.1.0
BUILD_NUMBER_STRATEGY ?= date
APP_DIR ?= build/CodMate.app
OUTPUT_DIR ?= artifacts/release
# Default arch for local builds
ARCH_NATIVE := $(shell uname -m)
ARCH ?= $(ARCH_NATIVE)
help: ## Show this help message
@echo "CodMate - macOS SwiftPM App"
@echo ""
@echo "Available targets:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'
build: ## SwiftPM debug build
@swift build
release: ## SwiftPM release build
@swift build -c release
test: ## Run SwiftPM tests (if any)
@swift test
notices: ## Update THIRD-PARTY-NOTICES.md
@python3 scripts/gen-third-party-notices.py
app: ## Build CodMate.app (ARCH=arm64|x86_64|"arm64 x86_64")
@if [ -z "$(VER)" ]; then echo "error: VER is required (e.g., VER=1.2.3)"; exit 1; fi
@VER=$(VER) BUILD_NUMBER_STRATEGY=$(BUILD_NUMBER_STRATEGY) \
ARCH_MATRIX="$(ARCH)" APP_DIR=$(APP_DIR) \
./scripts/create-app-bundle.sh
run: ## Build and launch CodMate.app (native arch, inferred version)
@VER_RUN=$${VER:-$$(git describe --tags --abbrev=0 2>/dev/null || echo 0.0.0)}; \
ARCH_NATIVE=$$(uname -m); \
VER="$$VER_RUN" BUILD_NUMBER_STRATEGY=$(BUILD_NUMBER_STRATEGY) \
ARCH_MATRIX="$$ARCH_NATIVE" APP_DIR=$(APP_DIR) STRIP=0 SWIFT_CONFIG=debug \
SIGN_ADHOC=1 \
./scripts/create-app-bundle.sh; \
open "$(APP_DIR)"
debug: ## Build and run with terminal output (prints to stdout/stderr)
@echo "Building CodMate.app for debug..."
@VER_RUN=$${VER:-$$(git describe --tags --abbrev=0 2>/dev/null || echo 0.0.0)}; \
ARCH_NATIVE=$$(uname -m); \
VER="$$VER_RUN" BUILD_NUMBER_STRATEGY=$(BUILD_NUMBER_STRATEGY) \
ARCH_MATRIX="$$ARCH_NATIVE" APP_DIR=$(APP_DIR) STRIP=0 SWIFT_CONFIG=debug \
SIGN_ADHOC=1 \
./scripts/create-app-bundle.sh
@echo ""
@echo "Starting CodMate with terminal output..."
@echo "Press Ctrl+C to stop"
@echo "========================================"
@"$(APP_DIR)/Contents/MacOS/CodMate"
debug-app: ## Build, launch app in background, and stream logs in foreground
@echo "Building and launching CodMate.app..."
@VER_RUN=$${VER:-$$(git describe --tags --abbrev=0 2>/dev/null || echo 0.0.0)}; \
ARCH_NATIVE=$$(uname -m); \
VER="$$VER_RUN" BUILD_NUMBER_STRATEGY=$(BUILD_NUMBER_STRATEGY) \
ARCH_MATRIX="$$ARCH_NATIVE" APP_DIR=$(APP_DIR) STRIP=0 SWIFT_CONFIG=debug \
SIGN_ADHOC=1 \
./scripts/create-app-bundle.sh
@open "$(APP_DIR)"
@sleep 1
@echo ""
@echo "Streaming logs from CodMate (Ctrl+C to stop)..."
@echo "========================================"
@log stream --predicate 'processImagePath CONTAINS "CodMate"' --style compact
debug-logs: ## Stream live logs from running CodMate app (use with 'make run' in another terminal)
@echo "Streaming logs from CodMate (Ctrl+C to stop)..."
@echo "========================================"
@log stream --predicate 'processImagePath CONTAINS "CodMate"' --style compact
debug-file: ## Build and run with output to both terminal and logs/debug.log
@echo "Building CodMate.app for debug..."
@VER_RUN=$${VER:-$$(git describe --tags --abbrev=0 2>/dev/null || echo 0.0.0)}; \
ARCH_NATIVE=$$(uname -m); \
VER="$$VER_RUN" BUILD_NUMBER_STRATEGY=$(BUILD_NUMBER_STRATEGY) \
ARCH_MATRIX="$$ARCH_NATIVE" APP_DIR=$(APP_DIR) STRIP=0 SWIFT_CONFIG=debug \
SIGN_ADHOC=1 \
./scripts/create-app-bundle.sh
@mkdir -p logs
@echo ""
@echo "Starting CodMate with output to terminal and file..."
@echo "Log file: logs/debug.log"
@echo "Press Ctrl+C to stop"
@echo "========================================"
@"$(APP_DIR)/Contents/MacOS/CodMate" 2>&1 | tee logs/debug.log
dmg: ## Build Developer ID DMG (ARCH=arm64|x86_64|"arm64 x86_64")
@if [ -z "$(VER)" ]; then echo "error: VER is required (e.g., VER=1.2.3)"; exit 1; fi
@VER=$(VER) BUILD_NUMBER_STRATEGY=$(BUILD_NUMBER_STRATEGY) \
ARCH_MATRIX="$(ARCH)" APP_DIR=$(APP_DIR) OUTPUT_DIR=$(OUTPUT_DIR) \
./scripts/macos-build-notarized-dmg.sh
zip: ## Create zip archives from DMG files (one zip per arch, requires dmg first, VER=1.2.3)
@if [ -z "$(VER)" ]; then echo "error: VER is required (e.g., VER=1.2.3)"; exit 1; fi
@if [ ! -d "$(OUTPUT_DIR)" ]; then echo "error: OUTPUT_DIR $(OUTPUT_DIR) does not exist. Run 'make dmg' first."; exit 1; fi
@DMG_FILES=$$(find "$(OUTPUT_DIR)" -name "codmate-*.dmg" 2>/dev/null | sort); \
if [ -z "$$DMG_FILES" ]; then \
echo "error: No DMG files found in $(OUTPUT_DIR). Run 'make dmg' first."; \
exit 1; \
fi; \
echo "Creating zip archives from DMG files..."; \
cd "$(OUTPUT_DIR)" && \
for dmg_file in $$DMG_FILES; do \
dmg_basename=$$(basename "$$dmg_file" .dmg); \
zip_name="$$dmg_basename.zip"; \
echo " Creating: $$zip_name"; \
zip -q "$$zip_name" "$$dmg_basename.dmg"; \
done; \
echo "Zip archives created in $(OUTPUT_DIR)"
clean: ## Clean build artifacts
@rm -rf .build build $(APP_DIR) artifacts
================================================
FILE: NOTICE
================================================
CodMate
Copyright (c) 2025 Loocor
================================================
FILE: Package.resolved
================================================
{
"originHash" : "06ecd22962877ed07b043a2d3eeba48fbdcada27c6982dc3012cc48805daf65f",
"pins" : [
{
"identity" : "eventsource",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattt/eventsource.git",
"state" : {
"revision" : "a2965424a4babeb0c8e4b5ec9708c3939bc52449",
"version" : "1.2.0"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log.git",
"state" : {
"revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2",
"version" : "1.6.4"
}
},
{
"identity" : "swift-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/modelcontextprotocol/swift-sdk.git",
"state" : {
"revision" : "c0407a0b52677cb395d824cac2879b963075ba8c",
"version" : "0.10.2"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system",
"state" : {
"revision" : "395a77f0aa927f0ff73941d7ac35f2b46d47c9db",
"version" : "1.6.3"
}
}
],
"version" : 3
}
================================================
FILE: Package.swift
================================================
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "CodMate",
defaultLocalization: "en",
platforms: [.macOS(.v13)],
products: [
.executable(
name: "CodMate",
targets: ["CodMate"]
),
.executable(
name: "notify",
targets: ["notify"]
),
],
dependencies: [
// Ghostty GPU-accelerated terminal
.package(path: "ghostty"),
// MCP Swift SDK for real MCP client connections
.package(url: "https://github.com/modelcontextprotocol/swift-sdk.git", from: "0.10.2"),
],
targets: [
.executableTarget(
name: "CodMate",
dependencies: [
.product(name: "GhosttyKit", package: "ghostty"),
.product(name: "MCP", package: "swift-sdk"),
],
path: ".",
exclude: [
"ghostty",
"notify",
"build",
".build",
"scripts",
"docs",
"payload",
"Tests",
"AGENTS.md",
"LICENSE",
"NOTICE",
"README.md",
"THIRD-PARTY-NOTICES.md",
"Makefile",
"screenshot.png",
"PrivacyInfo.xcprivacy",
"assets/Assets.xcassets",
"assets/Info.plist",
"assets/CodMate.entitlements",
"assets/CodMate-Notify.entitlements",
"Ghostty-header.h",
],
sources: [
"CodMateApp.swift",
"models",
"services",
"utils",
"views",
]
),
.executableTarget(
name: "notify",
path: "notify",
sources: ["NotifyMain.swift"]
),
.testTarget(
name: "CodMateTests",
dependencies: ["CodMate"]
),
],
swiftLanguageModes: [.v5]
)
================================================
FILE: PrivacyInfo.xcprivacy
================================================
{
"NSPrivacyTracking": false,
"NSPrivacyTrackingDomains": [],
"NSPrivacyCollectedDataTypes": [],
"NSPrivacyAccessedAPITypes": []
}
================================================
FILE: README.md
================================================
# CodMate

CodMate is a macOS SwiftUI app for **managing CLI AI sessions**: browse, search, organize, resume, and review work produced by **Codex**, **Claude Code**, and **Gemini CLI**.
It focuses on speed (incremental indexing + caching), a compact three-column UI, and “ship it” workflows like **Project Review (Git Changes)** and **one-click Resume/New**.
Status: **macOS 13.5+**, **Swift 6 toolchain**. Universal binary (arm64 + x86_64).
## Project status (Archival note)
I plan to **archive CodMate** after this update. Here is the reasoning that led me to this decision:
- **Scope drift with limited new insight**: CodMate grew from a simple history viewer into a broader desktop GUI for experience, integration, and workflow consolidation. However, it has not pushed the core exploration of Agents/LLMs as much as I hoped.
- **Traditional heavyweight GUI is no longer the right center of gravity**: the underlying Agent/LLM ecosystem evolves quickly, and a heavier desktop GUI becomes harder to justify when CLI/TUI approaches can iterate faster with less inertia. What feels more important to me now is a broader **HUI (Human Usability Interface)** direction: designing interfaces that help humans work effectively with rapidly improving AI systems, rather than anchoring exploration to one traditional app surface.
- **Ecosystem already covers part of the gap**: Codex and Claude Code now offer VS Code/Zed extensions that share history with their CLI sessions, which increasingly addresses the original problem CodMate set out to solve.
- **Model exploration now calls for a different center of gravity**: I want to spend more time learning how different model families are best used in practice — not just comparing open or low-cost options, but understanding where each type fits. The community already has strong examples such as `oh-my-openagent`, and there are also emerging Generative UI directions such as A2UI that I want to keep watching and learning from. In a time when AI/LLMs are accelerating what can be created through logic alone, I think the human-facing usability layer is becoming more urgent, not less.
- **The architecture also boxed the project into macOS**: CodMate’s SwiftUI desktop design helped it move quickly at first, but it also constrained the project to one environment. For the next phase, I want more room for cross-platform orchestration and CLI-first experimentation rather than continuing from a macOS-only foundation.
This does not diminish what CodMate achieved. If anything, the recent increase in attention around CodMate makes the tradeoff clearer to me: people are clearly interested in better ways to work with CLI agents, and I still believe interface design around these systems matters deeply. But I no longer think this particular macOS GUI is the best place for me to continue that exploration. The focus shift is toward orchestration, model-specific workflows, HUI, and more portable foundations.
## Where this exploration continues
While I will keep many of the ideas behind CodMate in mind, the project I am actively building now is [MCPMate](https://github.com/loocor/mcpmate).
MCPMate is not a brand-new project. I started shaping it around May last year, paused it around October, and recently returned to it with a clearer view of where MCP has irreplaceable value. It was previously closed-source and is now being reopened in public.
At a high level, MCPMate is a management center for MCP servers and AI clients. The direction I care about most there is usability: building on its earlier profile-based approach for removing redundant capabilities in specific scenarios, and extending its hosted mode toward a more progressively disclosed smart mode. Part of the goal is to bring some of the lower first-token-cost and lower-friction qualities that people appreciated in skills- and CLI-shaped workflows into MCP as well.
So while CodMate is ending here, the broader exploration is not. If CodMate resonated with you, I would love for you to take a look at MCPMate and share feedback.
## Download
- **Latest release (DMG)**: [GitHub Releases](https://github.com/loocor/CodMate/releases/latest)
## Why CodMate
- **Find anything fast**: a global search panel (⌘F) with scoped search + progress/cancel, plus quick list filtering.
- **Keep work organized**: Projects + Tasks let you group sessions by repo and by goal, with a shareable task context file.
- **Continue instantly**: Resume/New into Terminal/iTerm2/Warp (or embedded terminal in non-sandbox builds), with copyable exact commands.
- **Review & commit without leaving the app**: Project Review shows diffs, staging state, and supports commit (with optional AI commit message generation).
## Features (organized by value)
### Organize and understand sessions across CLIs
- **Multi-source session browsing**:
- **Codex**: `~/.codex/sessions` (`.jsonl`)
- **Claude Code**: `~/.claude/projects` (`.jsonl`)
- **Gemini CLI**: `~/.gemini/tmp` (Gemini’s session storage)
- **Sidebar navigation**:
- **Projects** list with counts, including “All” and an **unassigned/Other** bucket.
- **Calendar** (pinned bottom) with per-day counts and a Created/Updated toggle.
- Directory-based navigation built from session `cwd` statistics.
- **Session list**:
- Default scope is **Today** for fast first paint.
- Sorting: Most Recent (created/updated aware), Duration, Activity, etc.
- Rows show title, timestamps/duration, snippet, and compact metrics (user/assistant/tool/reasoning), plus states like running/updating/awaiting follow-up.
### Projects + Tasks (workspaces instead of loose logs)
- **Projects**:
- Create/edit projects (name, directory, overview, trust level, optional runtime profile).
- Assign sessions to projects via row actions/context menus.
- Storage: `~/.codmate/projects/` (project metadata + memberships mapping).
- “New” sessions started inside a project can be **auto-assigned** to that project.
- **Tasks (within projects)**:
- Create/edit/delete tasks, collapse/expand task groups, and assign/move sessions into tasks.
- **Task context sync**: generates/updates a shareable context file and prepares a prompt pointing to it.
- Storage: `~/.codmate/tasks/` (task metadata + relationships mapping).
### Resume/New (local, remote, embedded)
- **Resume**:
- Launch in **Terminal.app / iTerm2 / Warp**, or **embedded terminal** (non-App Store / non-sandbox builds).
- When embedded is active, CodMate can show a **Copy real command** action for reproducibility.
- **New**:
- Start a fresh session from the focused session’s `cwd` (and project profile when available).
- Start sessions directly from a selected project, even without a focused session.
- **Remote Hosts (SSH mirroring)**:
- Enable hosts from `~/.ssh/config`, then mirror remote sessions over SSH.
- Remote bases:
- Codex remote: `$HOME/.codex/sessions`
- Claude remote: `$HOME/.claude/projects`
- Mirror cache is stored under `~/Library/Caches/CodMate/remote/`.
### Search, export, and metadata (make history useful)
- **Global Search (⌘F)**:
- Floating window or toolbar popover style (configurable).
- Scope picker + progress/cancel for long searches.
- **Rename/comment**:
- Click the session title in the detail pane to edit title/comment.
- Storage: `~/.codmate/notes/<sessionId-sanitized>.json` (with automatic migration from legacy locations).
- **Conversation export**:
- Export Markdown from the detail pane.
- Settings allow choosing which message types appear in the timeline and which are included in Markdown export.
### Project Review (Git Changes) + AI commit message generation
- **Git Changes surface** (Project Review mode):
- Lists changed files, supports **stage/unstage**, and shows **unified diff** or raw preview.
- Commit UI with message editor and **Commit** action.
- Optional **AI generate commit message** (uses your selected Provider/Model and a prompt template from settings).
- Repo authorization is **on-demand** (especially relevant in sandboxed builds).
- **Settings › Git Review**:
- Diff options (line numbers, soft wrap).
- Commit generation: choose Provider/Model and an optional prompt template.
### Providers, MCP, notifications, diagnostics (make the ecosystem manageable)
- **Providers (Settings › Providers)**:
- Add/edit providers with Codex + Claude endpoints, shared API key env var, wire API (Chat/Responses), and model catalog with capability flags.
- Built-in templates are bundled from `payload/providers.json`; user registry is stored at `~/.codmate/providers.json`.
- Built-in health check: **Test** endpoints before saving.
- **MCP Servers (Settings › MCP Server)**:
- Uni-Import (paste/drag JSON), per-server enable toggle, per-target toggles (Codex/Claude/Gemini), and connectivity **Test**.
- Storage: `~/.codmate/mcp-servers.json`
- Exports enabled servers into `~/.claude/settings.json` (and writes a helper file `~/.codmate/mcp-enabled-claude.json`).
- **Claude Code notifications (Settings › Claude Code › Notifications)**:
- Installs/removes hooks that forward permission/completion events via `codmate://notify` and provides a self-test.
- **Dialectics (Settings › Dialectics)**:
- Deep diagnostics for session roots, notes/projects dirs, environment, and ripgrep indexes.
- One-click “Save Report…” plus rebuild actions for coverage/session index.
## Keyboard shortcuts
- **⌘,**: Settings
- **⌘F**: Global Search
- **⌘R**: Refresh (also recomputes global sidebar statistics)
- **⌘1**: Toggle sidebar
- **⌘2**: Toggle session list
## Data locations (quick reference)
- **Codex sessions**: `~/.codex/sessions`
- **Claude sessions**: `~/.claude/projects`
- **Gemini sessions**: `~/.gemini/tmp`
- **Notes**: `~/.codmate/notes/`
- **Projects**: `~/.codmate/projects/`
- **Tasks**: `~/.codmate/tasks/`
- **Providers registry**: `~/.codmate/providers.json`
- **MCP servers**: `~/.codmate/mcp-servers.json`
- **Session index cache (SQLite)**: `~/.codmate/sessionIndex-v4.db`
- **Additional caches**: `~/Library/Caches/CodMate/` (includes remote mirrors and best-effort caches)
## Performance
- Fast path indexing: memory‑mapped reads; parse the first ~64 lines plus tail sampling (up to ~1 MB) to fix `lastUpdatedAt`.
- Background enrichment: full parse in constrained task groups; batched UI updates.
- Full‑text search: chunked scan (128 KB), case‑insensitive; avoids lowercasing the whole file.
- Caching: persistent SQLite index + best-effort caches to keep subsequent launches fast.
- Sidebar statistics are global and decoupled from the list scope to keep navigation snappy.
## Architecture
- App: macOS SwiftUI (min macOS 13.5). SwiftPM-only build.
- MVVM layering
- Models: `SessionSummary`, `SessionEvent`, `DateDimension`, `SessionLoadScope`, …
- Services: `SessionIndexer`, `SessionCacheStore`, `SessionActions`, `SessionTimelineLoader`, `CodexConfigService`, `SessionsDiagnosticsService`
- ViewModel: `SessionListViewModel`
- Views: SwiftUI only (no business logic)
- Concurrency & IO
- Services that share caches are `actor`s; UI updates on MainActor only.
- Cancel previous tasks on search/scope changes; guard `Task.isCancelled` in loops.
- File IO prefers `Data(mappedIfSafe:)` and chunked reads; avoids loading huge files into Strings.
## Build
Prerequisites
- macOS 13.5+, Swift 6 toolchain, Xcode Command Line Tools (for `xcrun actool`).
- Install the CLIs you use (Codex / Claude / Gemini) somewhere on your `PATH`.
Makefile (recommended)
```sh
make build # SwiftPM debug build
make test # SwiftPM tests (if any)
make run # Build (debug, native arch) and launch for local testing
make app VER=1.2.3 # Create CodMate.app in build/ (ARCH defaults to host)
make app VER=1.2.3 ARCH=arm64
make app VER=1.2.3 ARCH=x86_64
make app VER=1.2.3 ARCH="arm64 x86_64"
make dmg VER=1.2.3 # Create Developer ID DMG (ARCH defaults to host)
make dmg VER=1.2.3 ARCH=arm64
make dmg VER=1.2.3 ARCH=x86_64
make dmg VER=1.2.3 ARCH="arm64 x86_64" # produces codmate-arm64.dmg + codmate-x86_64.dmg
make notices # Regenerate THIRD-PARTY-NOTICES.md
```
Direct scripts
```sh
VER=1.2.3 ./scripts/create-app-bundle.sh
VER=1.2.3 ./scripts/macos-build-notarized-dmg.sh
```
### Versioning strategy (build script)
- Marketing version (CFBundleShortVersionString): set with `VER` (e.g., `1.4.0`).
- Build number (CFBundleVersion): controlled by `BUILD_NUMBER_STRATEGY`:
- `date` (default): `yyyymmddHHMM` (e.g., `202510291430`).
- `git`: `git rev-list --count HEAD`.
- `counter`: monotonically increments a file counter at `$BUILD_DIR/build-number` (override path via `BUILD_COUNTER_FILE`).
- DMG name: `codmate-<ARCH>.dmg`.
- Override via environment variables when running the build script:
```sh
VER=1.4.0 BUILD_NUMBER_STRATEGY=date \
./scripts/macos-build-notarized-dmg.sh
```
This sets CFBundleShortVersionString to `1.4.0`, CFBundleVersion to the computed build number, and names the DMG accordingly.
## CLI Integration (Codex / Claude / Gemini)
- Executable resolution: CodMate launches CLIs via `/usr/bin/env codex` (and `claude` / `gemini`) to respect your system `PATH` (no user-configurable CLI path).
- PATH robustness: before launching, CodMate ensures `PATH` includes `/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin`.
- Resume:
- Uses the original session `cwd` when it exists; otherwise falls back to the log file directory.
- Can launch into Terminal.app / iTerm2 / Warp, and (in non-sandbox builds) an embedded terminal.
- When embedded is active, CodMate can copy the **exact** invocation it used (e.g. `codex resume <id>`).
- New:
- Starts a fresh session in the focused session’s working directory (or the selected project directory).
- When a Project Profile is present, its model/sandbox/approval defaults are applied when generating commands.
- Command flags exposed by the UI:
- Codex: sandbox policy (`-s/--sandbox`), approval policy (`-a/--ask-for-approval`), `--full-auto`, `--dangerously-bypass-approvals-and-sandbox`.
- Claude: common runtime/permission flags plus MCP strict mode (see Settings › Claude Code and Settings › Command).
- MCP integration:
- CodMate can export enabled MCP servers into `~/.claude/settings.json` and also writes `~/.codmate/mcp-enabled-claude.json` for explicit `--mcp-config` usage.
## Project Layout
```
assets/ # Assets and Info.plist (not in Copy Bundle Resources)
CodMateApp.swift # App entry point
models/ # Data models (pure types)
services/ # IO + indexing + integrations
utils/ # Helpers (shell, sandbox, formatting, etc.)
views/ # SwiftUI views
payload/ # Bundled presets (e.g. providers.json templates)
notify/ # Swift command-line helper installed as `codmate-notify`
SwiftTerm/ # Embedded terminal dependency (local package)
scripts/ # Helper scripts (icons, build flows)
docs/ # Design notes and investigation docs
```
## Known Pitfalls
- Prefer a toolbar search field (far‑right aligned) over `.searchable` to avoid hijacking toolbar slots on macOS.
- Outline row height needs explicit tightening (see `defaultMinListRowHeight` and insets in the row views).
## Development Tips
- Run tests: `swift test`.
- Formatting: follow existing code style; keep changes minimal and focused.
- Performance: measure large trees; first paint should be fast; enrichment is incremental.
## License
- Apache License 2.0. See `LICENSE` for full text.
- `NOTICE` includes project attribution. SPDX: `Apache-2.0`.
- Third-party attributions and license texts: see `THIRD-PARTY-NOTICES.md`.
================================================
FILE: THIRD-PARTY-NOTICES.md
================================================
Third-Party Notices
This document lists third-party components included in CodMate distributions, along with their licenses and attributions. The original license texts are reproduced or referenced below.
If you distribute CodMate binaries, keep this file together with `LICENSE`.
---
Aizen (Ghostty embedding implementation reference)
Repository: https://github.com/vivy-company/aizen
License: GNU General Public License v3.0
The GhosttyKit integration code in CodMate was adapted from Aizen's Ghostty embedding implementation. While the code has been significantly modified and adapted for CodMate's use case, we acknowledge Aizen as the original source of the Ghostty integration approach.
Copyright (C) 2025 Vivy Technologies Co., Limited
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
For the full GPL-3.0 license text, see: https://www.gnu.org/licenses/gpl-3.0.html
---
eventsource (1.2.0)
Repository: https://github.com/mattt/eventsource.git
License file: LICENSE.md
Copyright 2025 Mattt (https://mat.tt)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
---
Ghostty
Repository: https://github.com/ghostty-org/ghostty
License: MIT License
CodMate uses libghostty, the embeddable terminal library from Ghostty, to provide fast, feature-rich terminal emulation with GPU acceleration. While the integration approach was adapted from Aizen, the core terminal functionality and performance benefits come from Ghostty itself.
Copyright (c) 2022-2025 Ghostty contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
swift-argument-parser (1.6.2)
Repository: https://github.com/apple/swift-argument-parser
License file: LICENSE.txt
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
## Runtime Library Exception to the Apache 2.0 License: ##
As an exception, if you use this Software to compile your source code and
portions of this Software are embedded into the binary product as a result,
you may redistribute such product without providing attribution as would
otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.
---
swift-log (1.6.4)
Repository: https://github.com/apple/swift-log.git
License file: LICENSE.txt
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
NOTICE (NOTICE.txt)
The SwiftLog Project
========================
Please visit the SwiftLog web site for more information:
* https://github.com/apple/swift-log
Copyright 2018, 2019 The SwiftLog Project
The SwiftLog Project licenses this file to you under the Apache License,
version 2.0 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at:
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Also, please refer to each LICENSE.<component>.txt file, which is located in
the 'license' directory of the distribution file, for the license terms of the
components that this product depends on.
---
swift-sdk (0.10.2)
Repository: https://github.com/modelcontextprotocol/swift-sdk.git
License file: LICENSE
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
swift-subprocess (main@00b0496)
Repository: https://github.com/swiftlang/swift-subprocess
License file: LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---
swift-system (1.6.3)
Repository: https://github.com/apple/swift-system
License file: LICENSE.txt
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
## Runtime Library Exception to the Apache 2.0 License: ##
As an exception, if you use this Software to compile your source code and
portions of this Software are embedded into the binary product as a result,
you may redistribute such product without providing attribution as would
otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.
---
-
This product contains a derivation of the Tony Stone's 'process_test_files.rb'.
* LICENSE (Apache License 2.0):
* https://www.apache.org/licenses/LICENSE-2.0
* HOMEPAGE:
* https://codegists.com/snippet/ruby/generate_xctest_linux_runnerrb_tonystone_ruby
---
This product contains a derivation of the lock implementation and various
scripts from SwiftNIO.
* LICENSE (Apache License 2.0):
* https://www.apache.org/licenses/LICENSE-2.0
* HOMEPAGE:
* https://github.com/apple/swift-nio
================================================
FILE: Tests/CodMateTests/ClaudeHooksAdapterTests.swift
================================================
import XCTest
@testable import CodMate
final class ClaudeHooksAdapterTests: XCTestCase {
func testApplyHooksWritesClaudeSettingsHooks() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-claude-hooks-\(UUID().uuidString)", isDirectory: true)
try fm.createDirectory(at: tmp, withIntermediateDirectories: true)
let settingsURL = tmp.appendingPathComponent("settings.json")
let paths = ClaudeSettingsService.Paths(dir: tmp, file: settingsURL)
let service = ClaudeSettingsService(fileManager: fm, paths: paths)
let rule = HookRule(
name: "PreToolUse · Write",
event: "PreToolUse",
matcher: "Write|Edit",
commands: [HookCommand(command: "/usr/bin/echo", args: ["ok"], timeoutMs: 30_000)],
enabled: true,
targets: HookTargets(codex: false, claude: true, gemini: false)
)
let warnings = try await service.applyHooksFromCodMate([rule])
XCTAssertTrue(warnings.isEmpty)
let data = try Data(contentsOf: settingsURL)
let obj = try JSONSerialization.jsonObject(with: data) as? [String: Any]
let hooks = obj?["hooks"] as? [String: Any]
let pre = hooks?["PreToolUse"] as? [[String: Any]]
XCTAssertEqual(pre?.count, 1)
XCTAssertEqual(pre?.first?["matcher"] as? String, "Write|Edit")
let nested = pre?.first?["hooks"] as? [[String: Any]]
XCTAssertEqual(nested?.count, 1)
XCTAssertEqual(nested?.first?["type"] as? String, "command")
XCTAssertEqual(nested?.first?["command"] as? String, "/usr/bin/echo")
XCTAssertEqual(nested?.first?["timeout"] as? Int, 30_000)
XCTAssertNotNil(nested?.first?["name"] as? String)
}
func testAllowManagedHooksOnlySkipsApply() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-claude-hooks-\(UUID().uuidString)", isDirectory: true)
try fm.createDirectory(at: tmp, withIntermediateDirectories: true)
let settingsURL = tmp.appendingPathComponent("settings.json")
let initial = #"{"allowManagedHooksOnly":true}"#
try initial.write(to: settingsURL, atomically: true, encoding: .utf8)
let paths = ClaudeSettingsService.Paths(dir: tmp, file: settingsURL)
let service = ClaudeSettingsService(fileManager: fm, paths: paths)
let rule = HookRule(name: "Stop", event: "Stop", commands: [HookCommand(command: "/bin/echo")], enabled: true, targets: HookTargets(codex: false, claude: true, gemini: false))
let warnings = try await service.applyHooksFromCodMate([rule])
XCTAssertEqual(warnings.count, 1)
let text = try String(contentsOf: settingsURL, encoding: .utf8)
XCTAssertTrue(text.contains("allowManagedHooksOnly"))
XCTAssertFalse(text.contains("codmate-hook:"))
}
func testApplyPrunesPreviouslyManagedHooks() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-claude-hooks-\(UUID().uuidString)", isDirectory: true)
try fm.createDirectory(at: tmp, withIntermediateDirectories: true)
let settingsURL = tmp.appendingPathComponent("settings.json")
let paths = ClaudeSettingsService.Paths(dir: tmp, file: settingsURL)
let service = ClaudeSettingsService(fileManager: fm, paths: paths)
let rule = HookRule(
name: "Stop",
event: "Stop",
commands: [HookCommand(command: "/usr/bin/echo")],
enabled: true,
targets: HookTargets(codex: false, claude: true, gemini: false)
)
_ = try await service.applyHooksFromCodMate([rule])
_ = try await service.applyHooksFromCodMate([rule])
let data = try Data(contentsOf: settingsURL)
let obj = try JSONSerialization.jsonObject(with: data) as? [String: Any]
let hooks = obj?["hooks"] as? [String: Any]
let stop = hooks?["Stop"] as? [[String: Any]]
let nested = stop?.first?["hooks"] as? [[String: Any]]
let managed = (nested ?? []).filter { ($0["name"] as? String)?.hasPrefix("codmate-hook:") == true }
XCTAssertEqual(managed.count, 1)
}
}
================================================
FILE: Tests/CodMateTests/CodexHooksAdapterTests.swift
================================================
import XCTest
@testable import CodMate
final class CodexHooksAdapterTests: XCTestCase {
func testApplySingleStopHookWritesNotifyArray() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-codex-hooks-\(UUID().uuidString)", isDirectory: true)
let home = tmp.appendingPathComponent(".codex", isDirectory: true)
try fm.createDirectory(at: home, withIntermediateDirectories: true)
let configURL = home.appendingPathComponent("config.toml")
try "".write(to: configURL, atomically: true, encoding: .utf8)
let service = CodexConfigService(paths: .init(home: home, configURL: configURL), fileManager: fm)
let rule = HookRule(
name: "Stop · echo",
event: "Stop",
commands: [HookCommand(command: "/usr/bin/echo", args: ["hello"])],
enabled: true,
targets: HookTargets(codex: true, claude: false, gemini: false)
)
let warnings = try await service.applyHooksFromCodMate([rule])
XCTAssertTrue(warnings.isEmpty)
let text = try String(contentsOf: configURL, encoding: .utf8)
XCTAssertTrue(text.contains("notify = [\"/usr/bin/echo\", \"hello\"]"))
}
func testApplyMultipleCodexRulesDoesNotOverwriteExistingNotify() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-codex-hooks-\(UUID().uuidString)", isDirectory: true)
let home = tmp.appendingPathComponent(".codex", isDirectory: true)
try fm.createDirectory(at: home, withIntermediateDirectories: true)
let configURL = home.appendingPathComponent("config.toml")
try "notify = [\"old-notify\"]\n".write(to: configURL, atomically: true, encoding: .utf8)
let service = CodexConfigService(paths: .init(home: home, configURL: configURL), fileManager: fm)
let rules = [
HookRule(name: "Stop A", event: "Stop", commands: [HookCommand(command: "/bin/echo", args: ["a"])], enabled: true, targets: HookTargets(codex: true, claude: false, gemini: false)),
HookRule(name: "Stop B", event: "Stop", commands: [HookCommand(command: "/bin/echo", args: ["b"])], enabled: true, targets: HookTargets(codex: true, claude: false, gemini: false)),
]
let warnings = try await service.applyHooksFromCodMate(rules)
XCTAssertEqual(warnings.count, 1)
let unchanged = await service.getNotifyArray()
XCTAssertEqual(unchanged.first, "old-notify")
}
}
================================================
FILE: Tests/CodMateTests/GeminiHooksAdapterTests.swift
================================================
import XCTest
@testable import CodMate
final class GeminiHooksAdapterTests: XCTestCase {
func testApplyHooksWritesGeminiSettingsHooksAndEnablesTools() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-gemini-hooks-\(UUID().uuidString)", isDirectory: true)
try fm.createDirectory(at: tmp, withIntermediateDirectories: true)
let settingsURL = tmp.appendingPathComponent("settings.json")
let paths = GeminiSettingsService.Paths(directory: tmp, file: settingsURL)
let service = GeminiSettingsService(paths: paths, fileManager: fm)
let rule = HookRule(
name: "PreToolUse",
event: "PreToolUse",
matcher: "Write",
commands: [HookCommand(command: "/usr/bin/echo", args: ["ok"], timeoutMs: 10_000)],
enabled: true,
targets: HookTargets(codex: false, claude: false, gemini: true)
)
let warnings = try await service.applyHooksFromCodMate([rule])
XCTAssertTrue(warnings.isEmpty)
let data = try Data(contentsOf: settingsURL)
let obj = try JSONSerialization.jsonObject(with: data) as? [String: Any]
let hooks = obj?["hooks"] as? [String: Any]
let pre = hooks?["PreToolUse"] as? [[String: Any]]
XCTAssertEqual(pre?.count, 1)
XCTAssertEqual(pre?.first?["matcher"] as? String, "Write")
let nested = pre?.first?["hooks"] as? [[String: Any]]
XCTAssertEqual(nested?.count, 1)
XCTAssertTrue((nested?.first?["name"] as? String)?.hasPrefix("codmate-hook:") == true)
let tools = obj?["tools"] as? [String: Any]
XCTAssertEqual(tools?["enableHooks"] as? Bool, true)
XCTAssertEqual(tools?["enableMessageBusIntegration"] as? Bool, true)
}
func testApplyPrunesPreviouslyManagedHooks() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-gemini-hooks-\(UUID().uuidString)", isDirectory: true)
try fm.createDirectory(at: tmp, withIntermediateDirectories: true)
let settingsURL = tmp.appendingPathComponent("settings.json")
let paths = GeminiSettingsService.Paths(directory: tmp, file: settingsURL)
let service = GeminiSettingsService(paths: paths, fileManager: fm)
let rule = HookRule(
name: "Stop",
event: "Stop",
commands: [HookCommand(command: "/usr/bin/echo")],
enabled: true,
targets: HookTargets(codex: false, claude: false, gemini: true)
)
_ = try await service.applyHooksFromCodMate([rule])
_ = try await service.applyHooksFromCodMate([rule])
let data = try Data(contentsOf: settingsURL)
let obj = try JSONSerialization.jsonObject(with: data) as? [String: Any]
let hooks = obj?["hooks"] as? [String: Any]
let stop = hooks?["Stop"] as? [[String: Any]]
let nested = stop?.first?["hooks"] as? [[String: Any]]
let managed = (nested ?? []).filter { ($0["name"] as? String)?.hasPrefix("codmate-hook:") == true }
XCTAssertEqual(managed.count, 1)
}
}
================================================
FILE: Tests/CodMateTests/HooksStoreTests.swift
================================================
import XCTest
@testable import CodMate
final class HooksStoreTests: XCTestCase {
func testUpsertListUpdateDelete() async throws {
let fm = FileManager.default
let tmp = fm.temporaryDirectory.appendingPathComponent("codmate-hooks-store-\(UUID().uuidString)", isDirectory: true)
try fm.createDirectory(at: tmp, withIntermediateDirectories: true)
let paths = HooksStore.Paths(home: tmp, fileURL: tmp.appendingPathComponent("hooks.json"))
let store = HooksStore(paths: paths, fileManager: fm)
let rule = HookRule(
name: "Stop · echo",
event: "Stop",
commands: [HookCommand(command: "/usr/bin/echo", args: ["hello"])],
enabled: true,
targets: HookTargets(codex: true, claude: true, gemini: true),
source: "test"
)
try await store.upsert(rule)
let list1 = await store.list()
XCTAssertEqual(list1.count, 1)
XCTAssertEqual(list1.first?.id, rule.id)
try await store.update(id: rule.id) { r in
r.enabled = false
}
let list2 = await store.list()
XCTAssertEqual(list2.first?.enabled, false)
try await store.delete(id: rule.id)
let list3 = await store.list()
XCTAssertEqual(list3.count, 0)
}
}
================================================
FILE: Tests/CodMateTests/UpdateServiceTests.swift
================================================
import XCTest
@testable import CodMate
final class UpdateServiceTests: XCTestCase {
func testParseLatestRelease() throws {
let json = """
{
"tag_name": "v1.2.3",
"html_url": "https://github.com/loocor/CodMate/releases/tag/v1.2.3",
"draft": false,
"prerelease": false,
"assets": [
{"name": "codmate-arm64.dmg", "browser_download_url": "https://example.com/codmate-arm64.dmg"}
]
}
"""
let data = Data(json.utf8)
let release = try UpdateService.Release.decode(from: data)
XCTAssertEqual(release.tagName, "v1.2.3")
XCTAssertEqual(release.assets.first?.name, "codmate-arm64.dmg")
}
}
================================================
FILE: Tests/CodMateTests/UpdateSupportTests.swift
================================================
import XCTest
@testable import CodMate
final class UpdateSupportTests: XCTestCase {
func testVersionCompare() {
XCTAssertTrue(Version("1.2.3")! < Version("1.2.4")!)
XCTAssertTrue(Version("1.2.3")! > Version("1.2.2")!)
XCTAssertTrue(Version("1.2.0")! == Version("1.2")!)
}
func testAssetNameForArch() {
XCTAssertEqual(UpdateAssetSelector.assetName(for: .arm64), "codmate-arm64.dmg")
XCTAssertEqual(UpdateAssetSelector.assetName(for: .x86_64), "codmate-x86_64.dmg")
}
}
================================================
FILE: Tests/CodMateTests/UpdateViewModelTests.swift
================================================
import Foundation
import XCTest
@testable import CodMate
final class UpdateViewModelTests: XCTestCase {
@MainActor
func testInstallInstructions() {
let vm = UpdateViewModel(service: UpdateService())
XCTAssertTrue(vm.installInstructions.contains("Applications"))
}
@MainActor
func testSandboxDownloadUsesTemporaryDirectory() async throws {
let originalSandbox = getenv("APP_SANDBOX_CONTAINER_ID").map { String(cString: $0) }
defer {
if let originalSandbox {
setenv("APP_SANDBOX_CONTAINER_ID", originalSandbox, 1)
} else {
unsetenv("APP_SANDBOX_CONTAINER_ID")
}
MockURLProtocol.requestHandler = nil
}
let fileManager = FileManager.default
let downloadsDir = fileManager.urls(for: .downloadsDirectory, in: .userDomainMask).first ?? fileManager.temporaryDirectory
let sourceURL = fileManager.temporaryDirectory.appendingPathComponent("codmate-test-source.dmg")
try Data("test".utf8).write(to: sourceURL)
let assetName = UpdateAssetSelector.assetName(for: .current)
let releaseJSON = """
{
"tag_name": "v999.0.0",
"html_url": "https://example.com/release",
"draft": false,
"prerelease": false,
"assets": [
{
"name": "\(assetName)",
"browser_download_url": "\(sourceURL.absoluteString)"
}
]
}
"""
let releaseData = Data(releaseJSON.utf8)
MockURLProtocol.requestHandler = { request in
let response = HTTPURLResponse(
url: request.url ?? URL(string: "https://api.github.com/")!,
statusCode: 200,
httpVersion: nil,
headerFields: nil
)!
return (response, releaseData)
}
let config = URLSessionConfiguration.ephemeral
config.protocolClasses = [MockURLProtocol.self]
let session = URLSession(configuration: config)
let defaults = UserDefaults(suiteName: "UpdateViewModelTests")!
defaults.removePersistentDomain(forName: "UpdateViewModelTests")
let service = UpdateService(defaults: defaults, session: session, calendar: Calendar(identifier: .gregorian))
let vm = UpdateViewModel(service: service)
vm.checkNow()
let didUpdate = await waitUntil({
if case .updateAvailable = vm.state { return true }
return false
}, timeout: 2.0)
XCTAssertTrue(didUpdate)
setenv("APP_SANDBOX_CONTAINER_ID", "1", 1)
let start = Date()
vm.downloadIfNeeded()
let didDownload = await waitUntil({
vm.showInstallInstructions || (!vm.isDownloading && vm.lastError != nil)
}, timeout: 5.0)
XCTAssertTrue(didDownload)
XCTAssertNil(vm.lastError)
XCTAssertTrue(vm.showInstallInstructions)
let tempHit = findDownloadedFile(in: fileManager.temporaryDirectory, baseName: assetName, since: start)
let downloadsHit = findDownloadedFile(in: downloadsDir, baseName: assetName, since: start)
XCTAssertNotNil(tempHit)
XCTAssertNil(downloadsHit)
if let tempHit { try? fileManager.removeItem(at: tempHit) }
if let downloadsHit { try? fileManager.removeItem(at: downloadsHit) }
try? fileManager.removeItem(at: sourceURL)
}
}
private final class MockURLProtocol: URLProtocol {
static var requestHandler: ((URLRequest) throws -> (HTTPURLResponse, Data))?
override class func canInit(with request: URLRequest) -> Bool {
true
}
override class func canonicalRequest(for request: URLRequest) -> URLRequest {
request
}
override func startLoading() {
guard let handler = Self.requestHandler else {
client?.urlProtocol(self, didFailWithError: URLError(.unsupportedURL))
return
}
do {
let (response, data) = try handler(request)
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
client?.urlProtocol(self, didLoad: data)
client?.urlProtocolDidFinishLoading(self)
} catch {
client?.urlProtocol(self, didFailWithError: error)
}
}
override func stopLoading() {}
}
private func findDownloadedFile(in directory: URL, baseName: String, since: Date) -> URL? {
let cutoff = since.addingTimeInterval(-2)
guard let urls = try? FileManager.default.contentsOfDirectory(
at: directory,
includingPropertiesForKeys: [.contentModificationDateKey],
options: [.skipsHiddenFiles]
) else { return nil }
for url in urls {
let name = url.lastPathComponent
guard name == baseName || name.hasSuffix("-\(baseName)") else { continue }
let values = try? url.resourceValues(forKeys: [.contentModificationDateKey])
if let date = values?.contentModificationDate, date >= cutoff {
return url
}
}
return nil
}
private func waitUntil(_ condition: @escaping () -> Bool, timeout: TimeInterval) async -> Bool {
let deadline = Date().addingTimeInterval(timeout)
while Date() < deadline {
if condition() { return true }
try? await Task.sleep(nanoseconds: 50_000_000)
}
return condition()
}
================================================
FILE: Tests/CodMateTests/WizardResponseParserTests.swift
================================================
import XCTest
@testable import CodMate
final class WizardResponseParserTests: XCTestCase {
func testDecodeEnvelope() {
let raw = """
{"mode":"draft","draft":{"event":"Stop","commands":[{"command":"/bin/echo"}]}}
"""
let envelope: WizardDraftEnvelope<HookWizardDraft>? = WizardResponseParser.decodeEnvelope(raw)
XCTAssertEqual(envelope?.mode, .draft)
XCTAssertEqual(envelope?.draft?.event, "Stop")
}
func testDecodeWithCodeFence() {
let raw = """
```json
{"mode":"draft","draft":{"event":"Stop","commands":[{"command":"/bin/echo"}]}}
```
"""
let envelope: WizardDraftEnvelope<HookWizardDraft>? = WizardResponseParser.decodeEnvelope(raw)
XCTAssertEqual(envelope?.mode, .draft)
XCTAssertEqual(envelope?.draft?.commands.count, 1)
}
func testDecodeEnvelopeFromWrapper() {
let raw = """
{"result":"{\\"mode\\":\\"draft\\",\\"draft\\":{\\"event\\":\\"Stop\\",\\"commands\\":[{\\"command\\":\\"/bin/echo\\"}]}}"}
"""
let envelope: WizardDraftEnvelope<HookWizardDraft>? = WizardResponseParser.decodeEnvelope(raw)
XCTAssertEqual(envelope?.mode, .draft)
XCTAssertEqual(envelope?.draft?.event, "Stop")
}
}
================================================
FILE: assets/Assets.xcassets/AntigravityIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "antigravity.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{ "idiom" : "mac", "size" : "16x16", "scale" : "1x", "filename" : "icon_16x16.png" },
{ "idiom" : "mac", "size" : "16x16", "scale" : "2x", "filename" : "icon_16x16@2x.png" },
{ "idiom" : "mac", "size" : "32x32", "scale" : "1x", "filename" : "icon_32x32.png" },
{ "idiom" : "mac", "size" : "32x32", "scale" : "2x", "filename" : "icon_32x32@2x.png" },
{ "idiom" : "mac", "size" : "128x128", "scale" : "1x", "filename" : "icon_128x128.png" },
{ "idiom" : "mac", "size" : "128x128", "scale" : "2x", "filename" : "icon_128x128@2x.png" },
{ "idiom" : "mac", "size" : "256x256", "scale" : "1x", "filename" : "icon_256x256.png" },
{ "idiom" : "mac", "size" : "256x256", "scale" : "2x", "filename" : "icon_256x256@2x.png" },
{ "idiom" : "mac", "size" : "512x512", "scale" : "1x", "filename" : "icon_512x512.png" },
{ "idiom" : "mac", "size" : "512x512", "scale" : "2x", "filename" : "icon_512x512@2x.png" }
],
"info" : { "version" : 1, "author" : "xcode" }
}
================================================
FILE: assets/Assets.xcassets/ChatGPTIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "chatgpt.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/ClaudeIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "claude.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: assets/Assets.xcassets/DeepSeekIcon.imageset/Contents.json
================================================
{
"images": [
{
"filename": "deepseek.svg",
"idiom": "mac"
}
],
"info": {
"author": "xcode",
"version": 1
},
"properties": {
"preserves-vector-representation": true,
"template-rendering-intent": "original"
}
}
================================================
FILE: assets/Assets.xcassets/GeminiIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "gemini.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/KimiIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "kimi.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/MCPMateLogo.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "MCPMate.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
================================================
FILE: assets/Assets.xcassets/MiniMaxIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "minimax.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/OpenRouterIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "openrouter.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/QwenIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "qwen.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/Assets.xcassets/ZaiIcon.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "zai.svg",
"idiom" : "mac"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
================================================
FILE: assets/CodMate-Notify.entitlements
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.temporary-exception.files.home-relative-path.read-only</key>
<array>
<string>.ssh/config</string>
</array>
</dict>
</plist>
================================================
FILE: assets/CodMate.entitlements
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.temporary-exception.files.home-relative-path.read-only</key>
<array>
<string>.ssh/config</string>
</array>
</dict>
</plist>
================================================
FILE: assets/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>CodMate</string>
<key>CFBundleExecutable</key>
<string>CodMate</string>
<key>CFBundleIdentifier</key>
<string>ai.umate.codmate</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>CodMate</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
<key>LSMinimumSystemVersion</key>
<string>13.5</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>NSMainStoryboardFile</key>
<string></string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2025 CodMate</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSAppleEventsUsageDescription</key>
<string>CodMate may open Terminal or other apps on your request.</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>ai.codmate.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>codmate</string>
</array>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Folder</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>public.folder</string>
<string>public.directory</string>
</array>
</dict>
</array>
<key>CodMateGitTag</key>
<string></string>
<key>CodMateGitCommit</key>
<string></string>
<key>CodMateGitDirty</key>
<string></string>
</dict>
</plist>
================================================
FILE: docs/feature-inventory.md
================================================
# CodMate Feature Inventory
> Purpose: Provide a traceable feature inventory with code evidence (file paths) for value/advantage/use-case synthesis. Each feature includes code evidence (file paths).
## Coverage and Methodology
- Coverage sources: `README.md`, `AGENTS.md`, `docs/` specification documents + `views/` (UI entry points) + `services/` (capability implementations) + `models/` (data/state).
- Evidence format: Each feature is annotated with `Evidence:`, containing minimal necessary file paths (traceable item by item).
- Note: This inventory focuses on "feature points", not marketing copy; it can be used to extract "value/advantage/scenarios" later.
---
## 1) Session Sources and Collection (Multi-CLI Unified Management)
- Codex session parsing and provider (local `.jsonl`). Evidence: `services/SessionProvider.swift`, `services/CodexConfigService.swift`, `services/SessionIndexer.swift`
- Claude Code session parsing and provider. Evidence: `services/ClaudeSessionParser.swift`, `services/ClaudeSessionProvider.swift`
- Gemini CLI session parsing and provider. Evidence: `services/GeminiSessionParser.swift`, `services/GeminiSessionProvider.swift`
- Remote session mirroring (SSH sync of remote sessions). Evidence: `services/RemoteSessionMirror.swift`, `services/RemoteSessionProvider.swift`, `services/SSHConfigResolver.swift`
- Directory change monitoring (incremental session/index updates). Evidence: `services/DirectoryMonitor.swift`
- Session activity tracking and statistics. Evidence: `services/SessionActivityTracker.swift`, `models/OverviewAggregate.swift`
## 2) Indexing, Caching, and Performance Paths
- Session indexing (SQLite) with incremental updates. Evidence: `services/SessionIndexSQLiteStore.swift`, `services/SessionIndexer.swift`
- Lightweight caching and disk cache strategies. Evidence: `services/SessionCacheStore.swift`, `services/RipgrepDiskCache.swift`
- Full-text scanning (ripgrep) and search caching. Evidence: `services/SessionRipgrepStore.swift`, `services/RipgrepRunner.swift`
- Session timeline loading and incremental parsing. Evidence: `services/SessionTimelineLoader.swift`, `services/SessionEnrichmentService.swift`
- Context pruning and optimization (avoiding oversized contexts). Evidence: `services/ContextTreeshaker.swift`
## 3) Main Interface Structure and Navigation (3-Column Layout + Sidebar)
- Three-column structure: Sidebar / List / Detail. Evidence: `views/Content/ContentView.swift`, `views/SessionNavigationView.swift`, `views/Content/ContentView+Sidebar.swift`
- Sidebar top "All Sessions" entry and count. Evidence: `views/Content/ContentView+Sidebar.swift`, `models/SidebarState.swift`
- Directory tree navigation (aggregated by cwd statistics). Evidence: `models/PathTree.swift`, `services/PathTreeStore.swift`, `views/PathTreeView.swift`
- Calendar month view (daily statistics + multi-select). Evidence: `views/CalendarMonthView.swift`, `models/DateDimension.swift`
- Overview cards and activity charts. Evidence: `views/OverviewCard.swift`, `views/OverviewActivityChart.swift`, `models/ActivityChartData.swift`
## 4) Session List and Filtering
- Session list row information (title/time/snippet/metrics). Evidence: `views/SessionListRowView.swift`, `models/SessionSummary.swift`
- Sorting and scope (Today/Recent, etc.). Evidence: `models/SessionLoadScope.swift`, `models/SessionListViewModel.swift`
- List filtering, status indicators, running sessions. Evidence: `models/SessionListViewModel.swift`, `models/SessionNavigation.swift`
- Multi-dimensional filtering by project/directory/date. Evidence: `models/SessionListViewModel+Projects.swift`, `models/SessionListViewModel.swift`
## 5) Session Details and Timeline
- Conversation timeline view (user/assistant/tool/info). Evidence: `views/ConversationTimelineView.swift`, `models/TimelineEvent.swift`, `models/ConversationTurn.swift`
- Timeline attachment parsing and opening. Evidence: `services/TimelineAttachmentDecoder.swift`, `services/TimelineAttachmentOpener.swift`
- Environment Context/Turn Context display. Evidence: `models/EnvironmentContextInfo.swift`, `views/SessionDetailView.swift`
- Task Instructions collapsible display. Evidence: `views/SessionDetailView.swift`
## 6) Global Search and Content Retrieval
- Global search panel (shortcuts/progress/cancel). Evidence: `views/Search/GlobalSearchPanel.swift`, `models/GlobalSearchViewModel.swift`
- Search index service and incremental scanning. Evidence: `services/GlobalSearchService.swift`, `services/SessionRipgrepStore.swift`
- Repository content search (repo-level scanning). Evidence: `services/RepoContentSearchService.swift`
- Toolbar search entry. Evidence: `views/Search/ToolbarSearchField.swift`
## 7) Projects / Tasks / Session Archiving
- Project management (create/edit/select). Evidence: `views/ProjectsListView.swift`, `services/ProjectsStore.swift`, `models/Project.swift`
- Task management and grouping. Evidence: `views/TaskListView.swift`, `services/TasksStore.swift`, `models/Task.swift`
- Session assignment to projects/tasks. Evidence: `models/SessionListViewModel+Projects.swift`, `models/SessionListViewModel.swift`
- Project-level Overview container and statistics. Evidence: `views/ProjectSpecificOverviewContainerView.swift`, `models/ProjectOverviewViewModel.swift`
## 8) Session Metadata (Rename/Comment)
- Session title/comment editing. Evidence: `views/EditSessionMetaView.swift`, `models/SessionListViewModel+Notes.swift`
- Notes storage and migration. Evidence: `services/SessionNotesStore.swift`, `utils/FilenameSanitizer.swift`
## 9) Resume / New / Terminal Workflow
- Resume session (external terminal or embedded terminal). Evidence: `services/SessionActions+Terminal.swift`, `views/EmbeddedTerminalView.swift`, `views/CodMateTerminalView.swift`
- New session (reuse cwd / model / policy). Evidence: `services/SessionActions+Commands.swift`, `models/SessionListViewModel+Commands.swift`
- Terminal session management (keep running per session). Evidence: `services/TerminalSessionManager.swift`
- External terminal configuration (Terminal/iTerm2/Warp). Evidence: `services/ExternalTerminalProfileStore.swift`, `views/ExternalTerminalMenuHelpers.swift`
- Copy "real command" (full parameters). Evidence: `views/Content/ContentView+DetailActionBar.swift`, `services/SessionActions+Commands.swift`
## 10) Prompt System and Quick Commands
- Prompts Picker (insert into terminal input). Evidence: `views/Content/ContentView.swift`, `views/Content/ContentView+DetailActionBar.swift`
- Prompt presets and merging (project-level/user-level/built-in). Evidence: `services/PresetPromptsStore.swift`
- Prompt maintenance (add/delete/hide). Evidence: `services/PresetPromptsStore.swift`, `views/Content/ContentView.swift`
- Warp title prompt (prompt title). Evidence: `utils/WarpTitlePrompt.swift`, `services/SessionPreferencesStore.swift`
## 11) Git Review (Review Mode)
- Git changes tree + diff preview. Evidence: `views/GitChanges/GitChangesPanel.swift`, `services/GitService.swift`
- Stage / Unstage, operations by file/directory. Evidence: `views/GitChanges/GitChangesPanel+DiffTree.swift`, `services/GitService.swift`
- Commit editing and execution. Evidence: `views/GitChanges/GitChangesPanel.swift`, `models/GitChangesViewModel.swift`
- AI-generated Commit Message. Evidence: `models/GitChangesViewModel.swift`, `services/LLMHTTPService.swift`
- Git history graph and commit details. Evidence: `views/GitChanges/GitChangesPanel+Graph.swift`, `models/GitGraphViewModel.swift`
- Review panel state and persistence. Evidence: `models/ReviewPanelState.swift`, `views/GitChanges/GitChangesPanel+Lifecycle.swift`
## 12) Providers / Models / Usage
- Providers registry (unified management of API Key / Base URL / models). Evidence: `services/ProvidersRegistryService.swift`, `views/ProvidersSettingsView.swift`
- Provider icon/display. Evidence: `views/ProviderIconView.swift`
- Usage API clients and status. Evidence: `services/ClaudeUsageAPIClient.swift`, `services/CodexFeaturesService.swift`, `services/GeminiUsageAPIClient.swift`
- Usage status UI and triple-ring indicator. Evidence: `views/UsageStatusControl.swift`, `views/TripleUsageDonutView.swift`
## 13) MCP Servers and Extensions
- MCP Servers list, enable, edit. Evidence: `models/MCPServer.swift`, `services/MCPServersStore.swift`, `views/MCPServersSettingsView.swift`
- MCP Uni-Import (import/normalization). Evidence: `services/UniImportMCPNormalizer.swift`, `views/MCPServersSettingsView.swift`
- MCP connection testing and capability detection. Evidence: `services/MCPQuickTestService.swift`
- Extensions settings entry (MCP / Skills). Evidence: `views/ExtensionsSettingsView.swift`, `models/ExtensionsSettingsTab.swift`
## 14) Skills (Skill Packages)
- Skills list, loading, configuration. Evidence: `services/SkillsStore.swift`, `views/SkillsSettingsView.swift`
- Skills synchronization and application to projects. Evidence: `services/SkillsSyncService.swift`, `services/ProjectExtensionsApplier.swift`
- Skills package preview and details. Evidence: `views/Skills/SkillPackageExplorerView.swift`, `models/SkillsModels.swift`
- Project-level Skills settings. Evidence: `views/ProjectsListView.swift`, `models/ProjectExtensionsViewModel.swift`
## 15) Notification System
- System notification wrapper. Evidence: `services/SystemNotifier.swift`, `services/EmbeddedNotifySniffer.swift`
- Claude Code notification hook setup. Evidence: `models/ClaudeCodeVM.swift`, `services/ClaudeSettingsService.swift`
- Gemini notification settings. Evidence: `views/GeminiSettingsView.swift`, `models/GeminiVM.swift`
## 16) Diagnostics and Advanced Settings
- Dialectics diagnostics panel (data directories/index/reports). Evidence: `views/DialecticsPane.swift`, `services/SessionsDiagnosticsService.swift`
- Advanced Settings: Path / Dialectics. Evidence: `views/AdvancedSettingsView.swift`, `views/AdvancedPathPane.swift`
- Diagnostics report export. Evidence: `views/DiagnosticsViews.swift`, `services/SessionsDiagnosticsService.swift`
## 17) Settings System (Multi-Page/Multi-Tab)
- Settings main entry and categorization. Evidence: `views/SettingsView.swift`, `models/SettingCategory.swift`
### 17.1 General
- System menu bar icon display policy. Evidence: `views/SettingsView.swift`, `models/SystemMenuVisibility.swift`
- Default editor selection (for quick opening in Review, etc.). Evidence: `views/SettingsView.swift`, `models/EditorApp.swift`
- Global search panel style (⌘F display mode). Evidence: `views/SettingsView.swift`, `models/GlobalSearchModels.swift`
- Timeline/Markdown message type visibility configuration (with "Restore Defaults"). Evidence: `views/SettingsView.swift`, `models/SessionPreferencesStore.swift`, `models/TimelineEvent.swift`
### 17.2 Terminal
- Embedded terminal toggle (non-sandboxed version), CLI console mode. Evidence: `views/SettingsView.swift`, `services/TerminalSessionManager.swift`
- Terminal font and cursor style selection. Evidence: `views/SettingsView.swift`, `utils/TerminalFontResolver.swift`, `models/TerminalCursorStyleOption.swift`
- External terminal default app and auto-open. Evidence: `views/SettingsView.swift`, `services/ExternalTerminalProfileStore.swift`
- New/resume command auto-copy to clipboard. Evidence: `views/SettingsView.swift`, `services/SessionPreferencesStore.swift`
- Warp tab title prompt. Evidence: `views/SettingsView.swift`, `utils/WarpTitlePrompt.swift`
### 17.3 Command (Codex CLI Default Parameters)
- Sandbox policy and Approval policy defaults. Evidence: `views/SettingsView.swift`, `models/ExecutionPolicy.swift`
- `--full-auto` and dangerous bypass (bypass approvals/sandbox) toggle. Evidence: `views/SettingsView.swift`
### 17.4 Providers (Global Provider Management)
- Provider list, template add, edit/delete. Evidence: `views/ProvidersSettingsView.swift`, `services/ProvidersRegistryService.swift`
- Provider editor: Codex/Claude Base URL, API Key Env, Wire API. Evidence: `views/ProvidersSettingsView.swift`
- Model catalog editing: add/delete, default model, capability tags (reasoning/tool/vision/long context). Evidence: `views/ProvidersSettingsView.swift`, `services/ProvidersRegistryService.swift`
- Connection testing and documentation entry. Evidence: `views/ProvidersSettingsView.swift`
### 17.5 Codex Settings
- Provider binding (Active Provider + Model). Evidence: `views/CodexSettingsView.swift`, `models/CodexVM.swift`
- Runtime defaults: Reasoning Effort/Summary, Verbosity, Sandbox, Approval. Evidence: `views/CodexSettingsView.swift`, `models/CodexVM.swift`
- Feature Flags: fetch and per-item override toggles. Evidence: `views/CodexSettingsView.swift`, `services/CodexFeaturesService.swift`
- Notifications: TUI notifications, system notifications, notify bridge self-test. Evidence: `views/CodexSettingsView.swift`, `services/SystemNotifier.swift`
- Privacy/environment policy: inheritance scope, include/exclude, environment variable overrides, hide/show reasoning. Evidence: `views/CodexSettingsView.swift`, `models/CodexVM.swift`
- Raw Config read-only view and quick open. Evidence: `views/CodexSettingsView.swift`
### 17.6 Claude Code Settings
- Provider: Active Provider, default model and aliases (Haiku/Sonnet/Opus), login method. Evidence: `views/ClaudeCodeSettingsView.swift`, `models/ClaudeCodeVM.swift`
- Runtime: Permission Mode, Skip Permissions, Debug/Verbose, tool allow/deny, IDE auto-connect, Strict MCP, Fallback Model. Evidence: `views/ClaudeCodeSettingsView.swift`, `models/ClaudeCodeVM.swift`
- Notifications: install hook, hook command preview and self-test. Evidence: `views/ClaudeCodeSettingsView.swift`, `services/ClaudeSettingsService.swift`
- Raw Config: settings.json read-only view and open. Evidence: `views/ClaudeCodeSettingsView.swift`
### 17.7 Gemini CLI Settings
- General: Preview Features, Prompt Completion, Vim Mode, Disable Auto Update, Session Retention. Evidence: `views/GeminiSettingsView.swift`, `models/GeminiVM.swift`
- Runtime: Sandbox/Approval defaults. Evidence: `views/GeminiSettingsView.swift`, `models/ExecutionPolicy.swift`
- Model: model selection, Max Session Turns, Compression Threshold, Skip Next Speaker Check. Evidence: `views/GeminiSettingsView.swift`, `models/GeminiVM.swift`
- Notifications: system notifications and self-test. Evidence: `views/GeminiSettingsView.swift`
- Raw Config: settings.json read-only view and open. Evidence: `views/GeminiSettingsView.swift`
### 17.8 Extensions Settings
- MCP Servers: list, enable/disable, Uni‑Import, form/JSON editing, connection testing. Evidence: `views/MCPServersSettingsView.swift`, `services/MCPQuickTestService.swift`
- Skills: search, install (folder/Zip/URL/drag-drop), enable/disable, reinstall/uninstall, details preview. Evidence: `views/SkillsSettingsView.swift`, `models/SkillsLibraryViewModel.swift`
### 17.9 Git Review Settings
- Diff display (line numbers, soft wrap). Evidence: `views/GitReviewSettingsView.swift`, `services/GitService.swift`
- Commit generation (Provider/Model selection). Evidence: `views/GitReviewSettingsView.swift`, `services/ProvidersRegistryService.swift`
- Commit Prompt template. Evidence: `views/GitReviewSettingsView.swift`, `services/SessionPreferencesStore.swift`
### 17.10 Remote Hosts
- SSH host list and enable toggle (from `~/.ssh/config`). Evidence: `views/RemoteHostsSettingsView.swift`, `services/SSHConfigResolver.swift`
- One-click sync/refresh, unavailable host prompts and permission guidance. Evidence: `views/RemoteHostsSettingsView.swift`, `services/SandboxPermissionsManager.swift`
### 17.11 Advanced
- Path: Projects/Notes root directory switching. Evidence: `views/AdvancedPathPane.swift`, `models/SessionPreferencesStore.swift`
- CLI path overrides and auto-detection, PATH snapshot. Evidence: `views/AdvancedPathPane.swift`, `models/CLIPathVM.swift`
- Dialectics: environment info, ripgrep statistics, index rebuild, sessions/notes/projects directory diagnostics, report export. Evidence: `views/DialecticsPane.swift`, `services/SessionsDiagnosticsService.swift`, `services/SessionRipgrepStore.swift`
### 17.12 About
- Version/build time, project link, license viewing. Evidence: `views/AboutViews.swift`
## 18) Menu Bar (Status Bar)
- Status bar menu and quick actions. Evidence: `services/MenuBarController.swift`
- Provider/model/usage display. Evidence: `services/MenuBarController.swift`, `models/UsageProviderSnapshot.swift`
- Recent projects/sessions entry. Evidence: `services/MenuBarController.swift`, `views/RecentSessionsListView.swift`
## 19) Security and Authorization
- Security Scoped Bookmarks management. Evidence: `services/SecurityScopedBookmarks.swift`, `services/AuthorizationHub.swift`
- Sandbox permissions management and prompts. Evidence: `services/SandboxPermissionsManager.swift`, `views/SandboxPermissionsView.swift`
- External URL routing (codmate://). Evidence: `services/ExternalURLRouter.swift`
## 20) Data Export and Formatting
- Markdown export builder. Evidence: `utils/MarkdownExportBuilder.swift`, `views/SessionDetailView.swift`
- Token/time/duration formatting. Evidence: `utils/TokenFormatter.swift`, `models/SessionEvent.swift`
- Configurable Timeline/Markdown visibility. Evidence: `models/SessionPreferencesStore.swift`, `views/SettingsView.swift`
## 21) Statistics and Display Helpers
- Usage / Stats cards and aggregation. Evidence: `models/OverviewAggregate.swift`, `views/OverviewCard.swift`
- Usage status models (Codex/Claude/Gemini). Evidence: `models/CodexUsageStatus.swift`, `models/ClaudeUsageStatus.swift`, `models/GeminiUsageStatus.swift`
- Dual/triple-column statistics display components. Evidence: `views/TripleUsageDonutView.swift`, `views/UsageStatusControl.swift`
## 22) Compatibility and Runtime Environment
- CLI PATH environment setup and snapshot. Evidence: `utils/CLIEnvironment.swift`, `views/AdvancedPathPane.swift`
- App distribution/environment identification. Evidence: `utils/AppDistribution.swift`, `utils/AppAvailability.swift`
- Window/state persistence. Evidence: `services/WindowStateStore.swift`, `utils/WindowConfigurator.swift`
## 23) Claude Web / Browser Integration (Auxiliary Capabilities)
- Chrome/Safari cookie reading (Claude sessionKey). Evidence: `services/BrowserCookies/ChromeCookieImporter.swift`, `services/BrowserCookies/SafariCookieImporter.swift`
- Claude Web API client (sessions/usage, etc.). Evidence: `services/ClaudeWebAPIClient.swift`, `services/LLMHTTPService.swift`
---
## 24) Value/Advantage Tag Library and Mapping (For Synthesis)
> Note: The following tags can be used directly as "value point" titles or cards; features can be mapped to values later.
### 24.1 Value Tag Library (Suggested Terms)
- Efficiency and Speed (fast retrieval/fast resume/fast navigation)
- Context Continuity (uninterrupted across terminals, across CLIs)
- Traceability and Knowledge Accumulation (searchable, exportable, reviewable)
- Customization and Control (Provider/Model/policy/permissions)
- Security and Compliance (Sandbox, permissions, environment variables)
- Collaboration and Standardization (projects/tasks/skills/prompt library)
- Quality and Delivery Loop (Review/Commit)
- Operations and Remote (SSH mirroring, remote sessions)
- Ecosystem Compatibility (Codex/Claude/Gemini multi-source)
- Diagnosability and Recoverability (diagnostics/index rebuild/reports)
### 24.2 Feature → Value Mapping (Summary)
- **Multi-source session unified management + remote mirroring** → Ecosystem compatibility, operations and remote, traceability
Evidence: `services/SessionProvider.swift`, `services/RemoteSessionMirror.swift`
- **Global search + high-performance indexing** → Efficiency and speed, traceability
Evidence: `services/GlobalSearchService.swift`, `services/SessionIndexSQLiteStore.swift`
- **Projects/Tasks organization** → Collaboration and standardization, context continuity
Evidence: `services/ProjectsStore.swift`, `services/TasksStore.swift`
- **Resume/New + terminal integration** → Context continuity, efficiency and speed
Evidence: `services/SessionActions+Terminal.swift`, `views/EmbeddedTerminalView.swift`
- **Review (Git Changes)** → Quality and delivery loop
Evidence: `views/GitChanges/GitChangesPanel.swift`, `services/GitService.swift`
- **Providers/Models/Policies** → Customization and control, ecosystem compatibility
Evidence: `views/ProvidersSettingsView.swift`, `views/CodexSettingsView.swift`
- **Notification system** → Efficiency and speed (reduced waiting and switching)
Evidence: `services/SystemNotifier.swift`, `views/ClaudeCodeSettingsView.swift`
- **Diagnostics/Dialectics** → Diagnosability and recoverability, stability
Evidence: `views/DialecticsPane.swift`, `services/SessionsDiagnosticsService.swift`
- **Sandbox/permissions/environment policy** → Security and compliance
Evidence: `views/CodexSettingsView.swift`, `services/SandboxPermissionsManager.swift`
---
## 25) Use Case Matrix (Suggested)
> Note: For "recommended use cases" synthesis; can be rewritten as marketing descriptions.
| Scenario | Key Requirements | Corresponding Capabilities (Examples) |
|---|---|---|
| Personal daily development | Quick history retrieval/continue context | Global search, Resume/New, timeline |
| Team collaboration and standardization | Shared standards and prompts | Projects/Tasks, Skills, Prompts, Providers |
| Multi-model/multi-vendor switching | Unified API/model management | Providers Registry, model catalog/capability tags |
| Security-sensitive environments | Access/permission control | Sandbox/Approval/permission management/environment policy |
| Remote development/operations | Unified remote session archiving | SSH remote mirroring, Remote Hosts |
| Code review and delivery | Diff/Commit loop | Review mode, Stage/Unstage, AI Commit |
| Large-scale history review | Traceability and export | Timeline, Markdown export, Notes |
| Diagnostics and repair | Index/data anomaly troubleshooting | Dialectics, index rebuild, report export |
---
## 26) Secondary Inventory Supplements (Search / Terminal / Review)
### 26.1 Search (Global Search)
- Search scope switching (Scope segmented selection). Evidence: `views/Search/GlobalSearchPanel.swift`, `models/GlobalSearchModels.swift`
- Search panel style (floating window / Popover). Evidence: `views/Search/GlobalSearchPanel.swift`, `models/GlobalSearchModels.swift`
- Progress/statistics/cancel (files/matches). Evidence: `views/Search/GlobalSearchPanel.swift`, `services/SessionRipgrepStore.swift`
- Result types and summaries (session/notes/project summaries). Evidence: `views/Search/GlobalSearchPanel.swift`, `models/GlobalSearchViewModel.swift`
### 26.2 Terminal
- Embedded terminal (SwiftTerm) and external terminal coexistence. Evidence: `views/EmbeddedTerminalView.swift`, `views/CodMateTerminalView.swift`
- Theme synchronization (dark/light) and font strategy (CJK-friendly). Evidence: `views/EmbeddedTerminalView.swift`
- Initial command injection and one-click copy/open external terminal. Evidence: `views/EmbeddedTerminalView.swift`
- Terminal running and session binding (no exit on switch). Evidence: `services/TerminalSessionManager.swift`, `views/Content/ContentView+Detail.swift`
### 26.3 Review (Git Changes)
- Multi-mode layout: Diff / Graph / Explorer (or preview). Evidence: `views/GitChanges/GitChangesPanel.swift`, `views/GitChanges/GitChangesPanel+Graph.swift`
- File tree and staged/unstaged view separation. Evidence: `views/GitChanges/GitChangesPanel+LeftPane.swift`
- Line numbers/soft wrap settings. Evidence: `views/GitReviewSettingsView.swift`
- Commit message generation and template. Evidence: `views/GitReviewSettingsView.swift`, `models/GitChangesViewModel.swift`
---
## To Be Refined Later (Optional)
- Fine-grained UI entry inventory (function mapping for each Button/ToolbarItem).
- Feature points → marketing copy (rewritten for different audiences).
- Case-based implementation of typical scenarios (real project stories or flowcharts).
================================================
FILE: docs/icon.icon/icon.json
================================================
{
"fill" : {
"automatic-gradient" : "extended-srgb:0.00000,0.53333,1.00000,1.00000"
},
"groups" : [
{
"layers" : [
{
"blend-mode" : "plus-lighter",
"glass" : true,
"image-name" : "4.4-–-layer.png",
"name" : "4.4-–-layer"
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
},
{
"layers" : [
{
"blend-mode" : "normal",
"image-name" : "3.3-–-layer.png",
"name" : "3.3-–-layer"
},
{
"glass" : true,
"hidden" : false,
"image-name" : "2.2-–-layer.png",
"name" : "2.2-–-layer"
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
},
{
"layers" : [
{
"image-name" : "1.background.png",
"name" : "1.background",
"opacity-specializations" : [
{
"appearance" : "dark",
"value" : 0.25
}
]
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
================================================
FILE: docs/projects.md
================================================
Projects in CodMate (Phase 1)
Overview
- Introduces a virtual “Projects” view to organize Codex sessions conceptually, in addition to the existing physical directory view.
- Projects map to the `projects` group in Codex `config.toml` and can also be assigned per-session.
- Minimal viable goals: list projects, filter sessions by project, create a new project, and assign sessions to a project.
Goals (v1)
- Toggle sidebar middle area between Directories and Projects without changing top “All Sessions” and bottom Calendar.
- Read/write projects from Codex config: `[projects.<id>]` tables holding at least folder path and trust level.
- Allow creating a project (name, folder, trust, overview, instructions, optional profile).
- Assign sessions to a project (context menu; drag-and-drop planned for v1.1).
- When a project is selected, filter the middle session list accordingly.
Non-goals (deferred)
- Automatic profile creation/rename sync.
- Project-scoped overrides of all global runtime settings.
- Cross-session knowledge linking UX; export/minify pipelines.
- Drag-drop from middle list to sidebar project rows (v1.1).
Data Model
- Project (new model):
- `id: String` – stable identifier used in config/notes
- `name: String` – display name
- `directory: String` – absolute path for project root
- `trustLevel: String?` – e.g., `trusted` | `untrusted` (string passthrough)
- `overview: String?` – short description
- `instructions: String?` – default instructions for new sessions
- `profileId: String?` – optional profile association (future use)
- Session metadata extension (notes JSON per session id):
- `projectId: String?`
- `profileId: String?` (reserved)
- Backward compatible with existing title/comment; missing keys are tolerated.
Persistence
- Projects: Codex config at `~/.codex/config.toml` via `[projects.<id>]` tables.
- Supported keys: `name`, `directory`, `trust_level`, `overview`, `instructions`, `profile`.
- We read both `directory` and `path` for compatibility; we write `directory`.
- Session-to-project mapping: stored in notes JSON under `~/.codmate/notes/<sessionId>.json` along with title/comment (with automatic migration from the legacy `~/.codex/notes`).
View Model Changes
- `SessionListViewModel`
- New state: `projects: [Project]`, `selectedProjectIDs: Set<String>` (Cmd-click enables multi-select filters).
- Loads projects on startup and when config changes.
- Filters sessions by selected project (matches notes.projectId; directory matching is a future enhancement).
- New APIs: `assignSessions(to projectId: String, ids: [String])`, `loadProjects()`, `setSelectedProject(_:)`, `clearAllFilters()` resets both path and project.
UI/UX
- Sidebar (left):
- Top fixed: “All Sessions” row (unchanged). Click clears both path and project filters.
- Middle scrollable: segmented toggle – “Directories” | “Projects”.
- Directories: existing Path tree.
- Projects: list of projects with count badges; “New Project” button.
- Bottom fixed: calendar month view (unchanged).
- Only the middle area scrolls. Width rules unchanged.
- Projects list interactions:
- Click selects project → filters sessions. Cmd-click toggles multi-selection across projects; the filter matches any selected project (including descendants).
- Context menu on session rows (middle column): “Assign to Project…” flyout that lists projects.
- “New Project” opens a sheet to input: Name, Directory (choose…), Trust Level, Overview, Instructions, Profile (optional).
CLI Integration (preparation)
- New session from a Project will reuse the project’s directory and (later) its profile/config defaults. For v1, we only expose the project selection and filtering; project-scoped new-session is planned in a follow-up.
Performance
- Projects list is small; reads config once and caches in memory. Writes rewrite only the `projects` region similar to providers.
- Session assignment uses existing notes store; no large scans. Filtering is O(n) over the already-loaded day scope.
Error Handling
- Config I/O surfaced via `SessionListViewModel.errorMessage` and non-blocking alerts.
- Notes writes are best-effort; UI does not crash on failures.
Extensibility (v1.1+)
- Drag-and-drop from middle list to project rows (drop target) to assign sessions.
- Directory inference: if a session’s `cwd` is under a project directory and no explicit assignment exists, consider it in that project (opt-in).
- Project-level overrides for model, reasoning, sandbox/approval flags.
- Auto-create and sync a same-id Profile; conflict prompts.
================================================
FILE: ghostty/Package.swift
================================================
// swift-tools-version: 6.0
import PackageDescription
import Foundation
let packageDir = URL(fileURLWithPath: #filePath).deletingLastPathComponent()
let vendorLibDirDefault = packageDir.appendingPathComponent("Vendor/lib").path
let vendorLibDir = ProcessInfo.processInfo.environment["GHOSTTY_VENDOR_LIB"] ?? vendorLibDirDefault
let package = Package(
name: "ghostty",
platforms: [.macOS(.v13)],
products: [
.library(
name: "GhosttyKit",
targets: ["GhosttyKit"]
),
],
targets: [
// C library target for libghostty
.systemLibrary(
name: "CGhostty",
path: "Sources/CGhostty",
pkgConfig: nil
),
// Swift wrapper target
.target(
name: "GhosttyKit",
dependencies: ["CGhostty"],
path: "Sources/GhosttyKit",
resources: [
.process("../../Resources/themes"),
],
linkerSettings: [
.linkedLibrary("ghostty"),
.unsafeFlags([
"-L", vendorLibDir,
"-Xlinker", "-rpath", "-Xlinker", "@executable_path/../Frameworks",
// Enable dead code stripping to remove unused symbols from static library
"-Xlinker", "-dead_strip",
]),
.linkedFramework("Metal"),
.linkedFramework("MetalKit"),
.linkedFramework("IOSurface"),
.linkedFramework("Carbon"),
]
),
],
swiftLanguageModes: [.v5]
)
================================================
FILE: ghostty/Resources/themes/Apple Classic
================================================
palette = 0=#000000
palette = 1=#c91b00
palette = 2=#00c200
palette = 3=#c7c400
palette = 4=#1c3fe1
palette = 5=#ca30c7
palette = 6=#00c5c7
palette = 7=#c7c7c7
palette = 8=#686868
palette = 9=#ff6e67
palette = 10=#5ffa68
palette = 11=#fffc67
palette = 12=#6871ff
palette = 13=#ff77ff
palette = 14=#60fdff
palette = 15=#ffffff
background = #2c2b2b
foreground = #d5a200
cursor-color = #c7c7c7
cursor-text = #ffffff
selection-background = #6b5b02
selection-foreground = #67e000
================================================
FILE: ghostty/Resources/themes/Apple System Colors
================================================
palette = 0=#1a1a1a
palette = 1=#cc372e
palette = 2=#26a439
palette = 3=#cdac08
palette = 4=#0869cb
palette = 5=#9647bf
palette = 6=#479ec2
palette = 7=#98989d
palette = 8=#464646
palette = 9=#ff453a
palette = 10=#32d74b
palette = 11=#ffd60a
palette = 12=#0a84ff
palette = 13=#bf5af2
palette = 14=#76d6ff
palette = 15=#ffffff
background = #1e1e1e
foreground = #ffffff
cursor-color = #98989d
cursor-text = #ffffff
selection-background = #3f638b
selection-foreground = #ffffff
================================================
FILE: ghostty/Resources/themes/Apple System Colors Light
================================================
palette = 0=#1a1a1a
palette = 1=#cc372e
palette = 2=#26a439
palette = 3=#cdac08
palette = 4=#0869cb
palette = 5=#9647bf
palette = 6=#479ec2
palette = 7=#98989d
palette = 8=#464646
palette = 9=#ff453a
palette = 10=#32d74b
palette = 11=#edbb00
palette = 12=#0a84ff
palette = 13=#bf5af2
palette = 14=#3accf7
palette = 15=#ffffff
background = #feffff
foreground = #000000
cursor-color = #98989d
cursor-text = #ffffff
selection-background = #abd8ff
selection-foreground = #000000
================================================
FILE: ghostty/Resources/themes/Atom
================================================
palette = 0=#000000
palette = 1=#fd5ff1
palette = 2=#87c38a
palette = 3=#ffd7b1
palette = 4=#85befd
palette = 5=#b9b6fc
palette = 6=#85befd
palette = 7=#e0e0e0
palette = 8=#4c4c4c
palette = 9=#fd5ff1
palette = 10=#94fa36
palette = 11=#f5ffa8
palette = 12=#96cbfe
palette = 13=#b9b6fc
palette = 14=#85befd
palette = 15=#e0e0e0
background = #161719
foreground = #c5c8c6
cursor-color = #d0d0d0
cursor-text = #151515
selection-background = #444444
selection-foreground = #c5c8c6
================================================
FILE: ghostty/Resources/themes/Atom One Dark
================================================
palette = 0=#21252b
palette = 1=#e06c75
palette = 2=#98c379
palette = 3=#e5c07b
palette = 4=#61afef
palette = 5=#c678dd
palette = 6=#56b6c2
palette = 7=#abb2bf
palette = 8=#767676
palette = 9=#e06c75
palette = 10=#98c379
palette = 11=#e5c07b
palette = 12=#61afef
palette = 13=#c678dd
palette = 14=#56b6c2
palette = 15=#abb2bf
background = #21252b
foreground = #abb2bf
cursor-color = #abb2bf
cursor-text = #21252b
selection-background = #323844
selection-foreground = #abb2bf
================================================
FILE: ghostty/Resources/themes/Atom One Light
================================================
palette = 0=#000000
palette = 1=#de3e35
palette = 2=#3f953a
palette = 3=#d2b67c
palette = 4=#2f5af3
palette = 5=#950095
palette = 6=#3f953a
palette = 7=#bbbbbb
palette = 8=#000000
palette = 9=#de3e35
palette = 10=#3f953a
palette = 11=#d2b67c
palette = 12=#2f5af3
palette = 13=#a00095
palette = 14=#3f953a
palette = 15=#ffffff
background = #f9f9f9
foreground = #2a2c33
cursor-color = #bbbbbb
cursor-text = #ffffff
selection-background = #ededed
selection-foreground = #2a2c33
================================================
FILE: ghostty/Resources/themes/Dracula
================================================
palette = 0=#21222c
palette = 1=#ff5555
palette = 2=#50fa7b
palette = 3=#f1fa8c
palette = 4=#bd93f9
palette = 5=#ff79c6
palette = 6=#8be9fd
palette = 7=#f8f8f2
palette = 8=#6272a4
palette = 9=#ff6e6e
palette = 10=#69ff94
palette = 11=#ffffa5
palette = 12=#d6acff
palette = 13=#ff92df
palette = 14=#a4ffff
palette = 15=#ffffff
background = #282a36
foreground = #f8f8f2
cursor-color = #f8f8f2
cursor-text = #282a36
selection-background = #44475a
selection-foreground = #ffffff
================================================
FILE: ghostty/Resources/themes/Dracula+
================================================
palette = 0=#21222c
palette = 1=#ff5555
palette = 2=#50fa7b
palette = 3=#ffcb6b
palette = 4=#82aaff
palette = 5=#c792ea
palette = 6=#8be9fd
palette = 7=#f8f8f2
palette = 8=#545454
palette = 9=#ff6e6e
palette = 10=#69ff94
palette = 11=#ffcb6b
palette = 12=#d6acff
palette = 13=#ff92df
palette = 14=#a4ffff
palette = 15=#f8f8f2
background = #212121
foreground = #f8f8f2
cursor-color = #eceff4
cursor-text = #282828
selection-background = #f8f8f2
selection-foreground = #545454
================================================
FILE: ghostty/Resources/themes/Farmhouse Dark
================================================
palette = 0=#1d2027
palette = 1=#ba0004
palette = 2=#549d00
palette = 3=#c87300
palette = 4=#0049e6
palette = 5=#9f1b61
palette = 6=#1fb65c
palette = 7=#e8e4e1
palette = 8=#464d54
palette = 9=#eb0009
palette = 10=#7ac100
palette = 11=#ea9a00
palette = 12=#006efe
palette = 13=#bf3b7f
palette = 14=#19e062
palette = 15=#f4eef0
background = #1d2027
foreground = #e8e4e1
cursor-color = #006efe
cursor-text = #e8e4e1
selection-background = #4d5658
selection-foreground = #b3b1aa
================================================
FILE: ghostty/Resources/themes/Farmhouse Light
================================================
palette = 0=#1d2027
palette = 1=#8d0003
palette = 2=#3a7d00
palette = 3=#a95600
palette = 4=#092ccd
palette = 5=#820046
palette = 6=#229256
palette = 7=#a8a4a1
palette = 8=#394047
palette = 9=#eb0009
palette = 10=#7ac100
palette = 11=#ea9a00
palette = 12=#006efe
palette = 13=#bf3b7f
palette = 14=#00c649
palette = 15=#f4eef0
background = #e8e4e1
foreground = #1d2027
cursor-color = #006efe
cursor-text = #1d2027
selection-background = #b3b1aa
selection-foreground = #4d5658
================================================
FILE: ghostty/Resources/themes/Flexoki Dark
================================================
palette = 0=#100f0f
palette = 1=#d14d41
palette = 2=#879a39
palette = 3=#d0a215
palette = 4=#4385be
palette = 5=#ce5d97
palette = 6=#3aa99f
palette = 7=#878580
palette = 8=#575653
palette = 9=#af3029
palette = 10=#66800b
palette = 11=#ad8301
palette = 12=#205ea6
palette = 13=#a02f6f
palette = 14=#24837b
palette = 15=#cecdc3
background = #100f0f
foreground = #cecdc3
cursor-color = #cecdc3
cursor-text = #100f0f
selection-background = #403e3c
selection-foreground = #cecdc3
================================================
FILE: ghostty/Resources/themes/Flexoki Light
================================================
palette = 0=#100f0f
palette = 1=#af3029
palette = 2=#66800b
palette = 3=#ad8301
palette = 4=#205ea6
palette = 5=#a02f6f
palette = 6=#24837b
palette = 7=#6f6e69
palette = 8=#b7b5ac
palette = 9=#d14d41
palette = 10=#879a39
palette = 11=#d0a215
palette = 12=#4385be
palette = 13=#ce5d97
palette = 14=#3aa99f
palette = 15=#cecdc3
background = #fffcf0
foreground = #100f0f
cursor-color = #100f0f
cursor-text = #fffcf0
selection-background = #cecdc3
selection-foreground = #100f0f
================================================
FILE: ghostty/Resources/themes/GitHub
================================================
palette = 0=#3e3e3e
palette = 1=#970b16
palette = 2=#07962a
palette = 3=#c5bb94
palette = 4=#003e8a
palette = 5=#e94691
palette = 6=#7cc4df
palette = 7=#b2b2b2
palette = 8=#666666
palette = 9=#de0000
palette = 10=#7ac895
palette = 11=#d7b600
palette = 12=#2e6cba
palette = 13=#f29592
palette = 14=#00c7cb
palette = 15=#ffffff
background = #f4f4f4
foreground = #3e3e3e
cursor-color = #3f3f3f
cursor-text = #f4f4f4
selection-background = #a9c1e2
selection-foreground = #535353
================================================
FILE: ghostty/Resources/themes/GitHub Dark
================================================
palette = 0=#000000
palette = 1=#f78166
palette = 2=#56d364
palette = 3=#e3b341
palette = 4=#6ca4f8
palette = 5=#db61a2
palette = 6=#2b7489
palette = 7=#ffffff
palette = 8=#4d4d4d
palette = 9=#f78166
palette = 10=#56d364
palette = 11=#e3b341
palette = 12=#6ca4f8
palette = 13=#db61a2
palette = 14=#2b7489
palette = 15=#ffffff
background = #101216
foreground = #8b949e
cursor-color = #c9d1d9
cursor-text = #101216
selection-background = #3b5070
selection-foreground = #ffffff
================================================
FILE: ghostty/Resources/themes/GitHub Dark Colorblind
================================================
palette = 0=#484f58
palette = 1=#ec8e2c
palette = 2=#58a6ff
palette = 3=#d29922
palette = 4=#58a6ff
palette = 5=#bc8cff
palette = 6=#39c5cf
palette = 7=#b1bac4
palette = 8=#6e7681
palette = 9=#fdac54
palette = 10=#79c0ff
palette = 11=#e3b341
palette = 12=#79c0ff
palette = 13=#d2a8ff
palette = 14=#56d4dd
palette = 15=#ffffff
background = #0d1117
foreground = #c9d1d9
cursor-color = #58a6ff
cursor-text = #58a6ff
selection-background = #c9d1d9
selection-foreground = #0d1117
================================================
FILE: ghostty/Resources/themes/GitHub Dark Default
================================================
palette = 0=#484f58
palette = 1=#ff7b72
palette = 2=#3fb950
palette = 3=#d29922
palette = 4=#58a6ff
palette = 5=#bc8cff
palette = 6=#39c5cf
palette = 7=#b1bac4
palette = 8=#6e7681
palette = 9=#ffa198
palette = 10=#56d364
palette = 11=#e3b341
palette = 12=#79c0ff
palette = 13=#d2a8ff
palette = 14=#56d4dd
palette = 15=#ffffff
background = #0d1117
foreground = #e6edf3
cursor-color = #2f81f7
cursor-text = #2f81f7
selection-background = #e6edf3
selection-foreground = #0d1117
================================================
FILE: ghostty/Resources/themes/GitHub Dark Dimmed
================================================
palette = 0=#545d68
palette = 1=#f47067
palette = 2=#57ab5a
palette = 3=#c69026
palette = 4=#539bf5
palette = 5=#b083f0
palette = 6=#39c5cf
palette = 7=#909dab
palette = 8=#636e7b
palette = 9=#ff938a
palette = 10=#6bc46d
palette = 11=#daaa3f
palette = 12=#6cb6ff
palette = 13=#dcbdfb
palette = 14=#56d4dd
palette = 15=#cdd9e5
background = #22272e
foreground = #adbac7
cur
gitextract_0tk3_bnf/
├── .gitignore
├── .vscode/
│ └── launch.json
├── AGENTS.md
├── CodMateApp.swift
├── Ghostty-header.h
├── LICENSE
├── Makefile
├── NOTICE
├── Package.resolved
├── Package.swift
├── PrivacyInfo.xcprivacy
├── README.md
├── THIRD-PARTY-NOTICES.md
├── Tests/
│ └── CodMateTests/
│ ├── ClaudeHooksAdapterTests.swift
│ ├── CodexHooksAdapterTests.swift
│ ├── GeminiHooksAdapterTests.swift
│ ├── HooksStoreTests.swift
│ ├── UpdateServiceTests.swift
│ ├── UpdateSupportTests.swift
│ ├── UpdateViewModelTests.swift
│ └── WizardResponseParserTests.swift
├── assets/
│ ├── Assets.xcassets/
│ │ ├── AntigravityIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── ChatGPTIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── ClaudeIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── DeepSeekIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── GeminiIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── KimiIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── MCPMateLogo.imageset/
│ │ │ └── Contents.json
│ │ ├── MiniMaxIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── OpenRouterIcon.imageset/
│ │ │ └── Contents.json
│ │ ├── QwenIcon.imageset/
│ │ │ └── Contents.json
│ │ └── ZaiIcon.imageset/
│ │ └── Contents.json
│ ├── CodMate-Notify.entitlements
│ ├── CodMate.entitlements
│ └── Info.plist
├── docs/
│ ├── feature-inventory.md
│ ├── icon.icon/
│ │ └── icon.json
│ └── projects.md
├── ghostty/
│ ├── Package.swift
│ ├── Resources/
│ │ └── themes/
│ │ ├── Apple Classic
│ │ ├── Apple System Colors
│ │ ├── Apple System Colors Light
│ │ ├── Atom
│ │ ├── Atom One Dark
│ │ ├── Atom One Light
│ │ ├── Dracula
│ │ ├── Dracula+
│ │ ├── Farmhouse Dark
│ │ ├── Farmhouse Light
│ │ ├── Flexoki Dark
│ │ ├── Flexoki Light
│ │ ├── GitHub
│ │ ├── GitHub Dark
│ │ ├── GitHub Dark Colorblind
│ │ ├── GitHub Dark Default
│ │ ├── GitHub Dark Dimmed
│ │ ├── GitHub Dark High Contrast
│ │ ├── GitHub Light Colorblind
│ │ ├── GitHub Light Default
│ │ ├── GitHub Light High Contrast
│ │ ├── GitLab Dark
│ │ ├── GitLab Dark Grey
│ │ ├── GitLab Light
│ │ ├── Iceberg Dark
│ │ ├── Iceberg Light
│ │ ├── Material
│ │ ├── Material Dark
│ │ ├── Material Darker
│ │ ├── Material Design Colors
│ │ ├── Material Ocean
│ │ ├── Melange Dark
│ │ ├── Melange Light
│ │ ├── Monokai Pro
│ │ ├── Monokai Pro Light
│ │ ├── Monokai Pro Light Sun
│ │ ├── Monokai Pro Machine
│ │ ├── Monokai Pro Octagon
│ │ ├── Monokai Pro Ristretto
│ │ ├── Monokai Pro Spectrum
│ │ ├── Monokai Remastered
│ │ ├── Neobones Dark
│ │ ├── Neobones Light
│ │ ├── Nvim Dark
│ │ ├── Nvim Light
│ │ ├── One Double Dark
│ │ ├── One Double Light
│ │ ├── One Half Dark
│ │ ├── One Half Light
│ │ ├── Pencil Dark
│ │ ├── Pencil Light
│ │ ├── Raycast Dark
│ │ ├── Raycast Light
│ │ ├── Selenized Dark
│ │ ├── Selenized Light
│ │ ├── Seoulbones Dark
│ │ ├── Seoulbones Light
│ │ ├── Tinacious Design Dark
│ │ ├── Tinacious Design Light
│ │ ├── TokyoNight
│ │ ├── TokyoNight Day
│ │ ├── TokyoNight Moon
│ │ ├── TokyoNight Night
│ │ ├── TokyoNight Storm
│ │ ├── Tomorrow
│ │ ├── Tomorrow Night
│ │ ├── Tomorrow Night Blue
│ │ ├── Tomorrow Night Bright
│ │ ├── Tomorrow Night Burns
│ │ ├── Tomorrow Night Eighties
│ │ ├── Xcode Dark
│ │ ├── Xcode Dark hc
│ │ ├── Xcode Light
│ │ ├── Xcode Light hc
│ │ ├── Zenbones Dark
│ │ ├── Zenbones Light
│ │ ├── Zenwritten Dark
│ │ ├── Zenwritten Light
│ │ ├── iTerm2 Solarized Dark
│ │ ├── iTerm2 Solarized Light
│ │ ├── iTerm2 Tango Dark
│ │ └── iTerm2 Tango Light
│ ├── Sources/
│ │ ├── CGhostty/
│ │ │ └── module.modulemap
│ │ └── GhosttyKit/
│ │ ├── Clipboard.swift
│ │ ├── Ghostty.Action.swift
│ │ ├── Ghostty.App.swift
│ │ ├── Ghostty.Input.swift
│ │ ├── Ghostty.Key.swift
│ │ ├── Ghostty.KeyEvent.swift
│ │ ├── Ghostty.Mods.swift
│ │ ├── Ghostty.MouseEvent.swift
│ │ ├── Ghostty.Surface.swift
│ │ ├── GhosttyIMEHandler.swift
│ │ ├── GhosttyInputHandler.swift
│ │ ├── GhosttyProgressState.swift
│ │ ├── GhosttyRenderingSetup.swift
│ │ ├── GhosttyTerminalView.swift
│ │ ├── GhosttyThemeLoader.swift
│ │ ├── TerminalScrollView.swift
│ │ └── TerminalTextCleaner.swift
│ └── Vendor/
│ ├── VERSION
│ └── include/
│ ├── ghostty/
│ │ ├── vt/
│ │ │ ├── allocator.h
│ │ │ ├── color.h
│ │ │ ├── key/
│ │ │ │ ├── encoder.h
│ │ │ │ └── event.h
│ │ │ ├── key.h
│ │ │ ├── osc.h
│ │ │ ├── paste.h
│ │ │ ├── result.h
│ │ │ ├── sgr.h
│ │ │ └── wasm.h
│ │ └── vt.h
│ ├── ghostty.h
│ └── module.modulemap
├── models/
│ ├── ActivityChartData.swift
│ ├── AllOverviewViewModel.swift
│ ├── CLIPathVM.swift
│ ├── ClaudeCodeVM.swift
│ ├── ClaudeUsageStatus.swift
│ ├── CodexUsageStatus.swift
│ ├── CodexVM.swift
│ ├── CommandRecord.swift
│ ├── CommandsViewModel.swift
│ ├── ConversationTurn.swift
│ ├── DateDimension.swift
│ ├── DialecticsVM.swift
│ ├── EditorApp.swift
│ ├── EnvironmentContextInfo.swift
│ ├── ExecutionPolicy.swift
│ ├── ExtensionsImportModels.swift
│ ├── ExtensionsSettingsTab.swift
│ ├── ExternalTerminalProfile.swift
│ ├── GeminiUsageStatus.swift
│ ├── GeminiVM.swift
│ ├── GitChangesViewModel.swift
│ ├── GitGraphViewModel.swift
│ ├── GitReviewTree.swift
│ ├── GlobalSearchModels.swift
│ ├── GlobalSearchViewModel.swift
│ ├── HookCommandVariableCatalog.swift
│ ├── HookEventCatalog.swift
│ ├── HookSyncWarning.swift
│ ├── Hooks.swift
│ ├── HooksViewModel.swift
│ ├── InternalSkill.swift
│ ├── LocalAuthProvider.swift
│ ├── MCPServer.swift
│ ├── MCPServersViewModel.swift
│ ├── OverviewAggregate.swift
│ ├── PathTree.swift
│ ├── Project.swift
│ ├── ProjectExtensionsModels.swift
│ ├── ProjectExtensionsViewModel.swift
│ ├── ProjectOverviewViewModel.swift
│ ├── ProjectWorkspaceMode.swift
│ ├── ProjectWorkspaceViewModel+Generation.swift
│ ├── ProjectWorkspaceViewModel.swift
│ ├── RefreshRequest.swift
│ ├── ReviewPanelState.swift
│ ├── SessionEvent.swift
│ ├── SessionLaunchProvider.swift
│ ├── SessionListViewModel+Commands.swift
│ ├── SessionListViewModel+Editor.swift
│ ├── SessionListViewModel+Intents.swift
│ ├── SessionListViewModel+Notes.swift
│ ├── SessionListViewModel+Projects.swift
│ ├── SessionListViewModel+SearchSupport.swift
│ ├── SessionListViewModel.swift
│ ├── SessionLoadScope.swift
│ ├── SessionNavigation.swift
│ ├── SessionPathConfig.swift
│ ├── SessionSource+CaseIterable.swift
│ ├── SessionSummary.swift
│ ├── SettingCategory.swift
│ ├── SidebarState.swift
│ ├── SkillsLibraryViewModel.swift
│ ├── SkillsModels.swift
│ ├── StatusBarLogEntry.swift
│ ├── StatusBarVisibility.swift
│ ├── SystemMenuVisibility.swift
│ ├── Task.swift
│ ├── TerminalCursorStyleOption.swift
│ ├── TimelineEvent.swift
│ ├── UnifiedProviderCatalog.swift
│ ├── UnifiedProviderID.swift
│ ├── UpdateViewModel.swift
│ ├── UsageProviderSnapshot.swift
│ ├── WarpTitleBuilder.swift
│ ├── WizardConversationViewModel.swift
│ ├── WizardGuard.swift
│ └── WizardModels.swift
├── notify/
│ └── NotifyMain.swift
├── payload/
│ ├── commands/
│ │ └── index.json
│ ├── hook-events.json
│ ├── hook-variables.json
│ ├── internal-skills/
│ │ ├── commands-wizard/
│ │ │ ├── SKILL.md
│ │ │ ├── prompt.md
│ │ │ └── schema.json
│ │ ├── hooks-wizard/
│ │ │ ├── SKILL.md
│ │ │ ├── prompt.md
│ │ │ └── schema.json
│ │ ├── index.json
│ │ ├── mcp-wizard/
│ │ │ ├── SKILL.md
│ │ │ ├── prompt.md
│ │ │ └── schema.json
│ │ └── skills-wizard/
│ │ ├── SKILL.md
│ │ ├── prompt.md
│ │ └── schema.json
│ ├── knowledge/
│ │ └── wizard-docs.json
│ ├── prompts/
│ │ ├── commit-message.md
│ │ ├── task-title-and-description.md
│ │ ├── task-title-only.md
│ │ └── title-and-comment.md
│ ├── providers.json
│ └── terminals.json
├── scripts/
│ ├── BUILD.md
│ ├── build-libghostty-local.sh
│ ├── create-app-bundle.sh
│ ├── gen-third-party-notices.py
│ ├── macos-build-notarized-dmg.sh
│ └── test-commands-sync.sh
├── services/
│ ├── AppLogger.swift
│ ├── AuthorizationHub.swift
│ ├── BrowserCookies/
│ │ ├── ChromeCookieImporter.swift
│ │ ├── CookieRecord.swift
│ │ ├── DataReader.swift
│ │ └── SafariCookieImporter.swift
│ ├── CLIProxyBridge.swift
│ ├── CLIProxyService.swift
│ ├── ClaudeSessionParser.swift
│ ├── ClaudeSessionProvider.swift
│ ├── ClaudeSettingsService.swift
│ ├── ClaudeUsageAPIClient.swift
│ ├── ClaudeUsageAnalyzer.swift
│ ├── ClaudeWebAPIClient.swift
│ ├── CodexAppServerProbeService.swift
│ ├── CodexConfigService.swift
│ ├── CodexFeaturesService.swift
│ ├── CodexOAuthUsageFetcher.swift
│ ├── CommandsImportService.swift
│ ├── CommandsStore.swift
│ ├── CommandsSyncService.swift
│ ├── ContextTreeshaker.swift
│ ├── DirectoryMonitor.swift
│ ├── DockOpenCoordinator.swift
│ ├── EmbeddedNotifySniffer.swift
│ ├── ExternalTerminalProfileStore.swift
│ ├── ExternalURLRouter.swift
│ ├── GeminiSessionParser.swift
│ ├── GeminiSessionProvider.swift
│ ├── GeminiSettingsService.swift
│ ├── GeminiUsageAPIClient.swift
│ ├── GhosttySessionManager.swift
│ ├── GitService.swift
│ ├── GlobalSearchService.swift
│ ├── HooksImportService.swift
│ ├── HooksStore.swift
│ ├── HooksSyncService.swift
│ ├── InternalSkillRunner.swift
│ ├── InternalSkillsRegistry.swift
│ ├── LLMHTTPService.swift
│ ├── LaunchAtLoginService.swift
│ ├── LocalServerBuiltInProvider.swift
│ ├── MCPImportService.swift
│ ├── MCPQuickTestService.swift
│ ├── MCPServersStore.swift
│ ├── MainWindowCoordinator.swift
│ ├── MenuBarController.swift
│ ├── PathTreeStore.swift
│ ├── PresetPromptsStore.swift
│ ├── ProjectExtensionsApplier.swift
│ ├── ProjectExtensionsStore.swift
│ ├── ProjectsStore.swift
│ ├── ProvidersRegistryService.swift
│ ├── RemoteSessionMirror.swift
│ ├── RemoteSessionProvider+Adapter.swift
│ ├── RemoteSessionProvider.swift
│ ├── RepoContentSearchService.swift
│ ├── RipgrepDiskCache.swift
│ ├── RipgrepRunner.swift
│ ├── SSHConfigResolver.swift
│ ├── SandboxPermissionsManager.swift
│ ├── SecurityScopedBookmarks.swift
│ ├── SessionActions+Commands.swift
│ ├── SessionActions+Config.swift
│ ├── SessionActions+FileActions.swift
│ ├── SessionActions+Terminal.swift
│ ├── SessionActions.swift
│ ├── SessionActivityTracker.swift
│ ├── SessionCacheStore.swift
│ ├── SessionCommandGenerator.swift
│ ├── SessionEnrichmentService.swift
│ ├── SessionIndexSQLiteStore.swift
│ ├── SessionIndexer.swift
│ ├── SessionNotesStore.swift
│ ├── SessionPreferencesStore.swift
│ ├── SessionProvider.swift
│ ├── SessionRipgrepStore.swift
│ ├── SessionTimelineLoader.swift
│ ├── SessionsDiagnosticsService.swift
│ ├── SkillsImportService.swift
│ ├── SkillsStore.swift
│ ├── SkillsSyncService.swift
│ ├── StatusBarLogStore.swift
│ ├── SystemNotifier.swift
│ ├── TasksStore.swift
│ ├── TimelineAttachmentDecoder.swift
│ ├── TimelineAttachmentOpener.swift
│ ├── UniImportMCPNormalizer.swift
│ ├── UpdateService.swift
│ ├── WindowStateStore.swift
│ ├── WizardDocsService.swift
│ └── WizardResponseParser.swift
├── utils/
│ ├── AppAvailability.swift
│ ├── AppDistribution.swift
│ ├── AppSandbox.swift
│ ├── CLIEnvironment.swift
│ ├── EmbeddedSessionNotification.swift
│ ├── FilenameSanitizer.swift
│ ├── FlexibleDecoders.swift
│ ├── InternalWizardPaths.swift
│ ├── MarkdownExportBuilder.swift
│ ├── ModelNameSanitizer.swift
│ ├── ProviderIconResource.swift
│ ├── ProviderIconThemeHelper.swift
│ ├── SessionPathFilter.swift
│ ├── SessionSummaryMaterialBuilder.swift
│ ├── ShellCommandRunner.swift
│ ├── TagView.swift
│ ├── TerminalFontResolver.swift
│ ├── TimelineEventClassifier.swift
│ ├── TokenFormatter.swift
│ ├── UpdateSupport.swift
│ ├── WarpTitlePrompt.swift
│ └── WindowConfigurator.swift
└── views/
├── APIKeyProviderIconView.swift
├── AboutViews.swift
├── AdvancedPathPane.swift
├── AdvancedSettingsView.swift
├── AttributedTextView.swift
├── AutoAssignSheet.swift
├── CLIProxyAdvancedPane.swift
├── CalendarMonthView.swift
├── ClaudeCodeSettingsView.swift
├── ClaudeModelMappingSheet.swift
├── CodexSettingsView.swift
├── CommandsSettingsView.swift
├── Content/
│ ├── AllOverviewView.swift
│ ├── ContentView+Detail.swift
│ ├── ContentView+DetailActionBar.swift
│ ├── ContentView+Helpers.swift
│ ├── ContentView+MainDetail.swift
│ ├── ContentView+Modifiers.swift
│ ├── ContentView+Search.swift
│ ├── ContentView+Sidebar.swift
│ ├── ContentView.swift
│ └── StatusBarOverlayView.swift
├── Controls/
│ ├── CollapseExpandButtonGroup.swift
│ ├── FontPickerButton.swift
│ ├── RainbowSpinnerView.swift
│ └── TableSpacingRemover.swift
├── ConversationTimelineView.swift
├── DiagnosticsViews.swift
├── DialecticsPane.swift
├── EditSessionMetaView.swift
├── EditorMenuHelpers.swift
├── EmbeddedTerminalView.swift
├── EquatableContainers.swift
├── ExtensionsImportSheets.swift
├── ExtensionsSettingsView.swift
├── ExternalTerminalMenuHelpers.swift
├── GeminiSettingsView.swift
├── GitChanges/
│ ├── GitChangesPanel+Browser.swift
│ ├── GitChangesPanel+Detail.swift
│ ├── GitChangesPanel+DiffTree.swift
│ ├── GitChangesPanel+Graph.swift
│ ├── GitChangesPanel+Header.swift
│ ├── GitChangesPanel+Helpers.swift
│ ├── GitChangesPanel+LeftPane.swift
│ ├── GitChangesPanel+Lifecycle.swift
│ ├── GitChangesPanel+Menus.swift
│ └── GitChangesPanel.swift
├── GitReviewSettingsView.swift
├── HookEditSheet.swift
├── HooksSettingsView.swift
├── LiveFileSizeText.swift
├── LocalAuthProviderIconView.swift
├── MCPServerTargetToggle.swift
├── MCPServersSettingsView.swift
├── ModelListEditorSheet.swift
├── NewTaskSheet.swift
├── OverviewActivityChart.swift
├── OverviewCard.swift
├── PathTreeView.swift
├── ProjectAgentsView.swift
├── ProjectOverviewView.swift
├── ProjectSpecificOverviewContainerView.swift
├── ProjectsListView.swift
├── ProviderEditorView.swift
├── ProviderIconView.swift
├── ProvidersSettingsView.swift
├── RecentSessionsListView.swift
├── RemoteHostsSettingsView.swift
├── SandboxApprovalEditor.swift
├── SandboxPermissionsView.swift
├── Search/
│ ├── GlobalSearchPanel.swift
│ └── ToolbarSearchField.swift
├── SessionDetailView.swift
├── SessionListColumnView.swift
├── SessionListRowView.swift
├── SessionNavigationView.swift
├── SessionPathGroup.swift
├── SessionPathRow.swift
├── SessionsPathPane.swift
├── SettingsCompatibility.swift
├── SettingsTabContent.swift
├── SettingsView.swift
├── SimpleProviderPicker.swift
├── Skills/
│ └── SkillPackageExplorerView.swift
├── SkillsSettingsView.swift
├── SplitControls.swift
├── TaskListView.swift
├── TripleUsageDonutView.swift
├── UnavailableStateView.swift
├── UnifiedProviderPickerView.swift
├── UsageStatusControl.swift
└── Wizard/
├── CommandWizardSheet.swift
├── HookWizardSheet.swift
├── MCPWizardSheet.swift
├── SkillWizardSheet.swift
└── WizardConversationView.swift
SYMBOL INDEX (129 symbols across 9 files)
FILE: ghostty/Vendor/include/ghostty.h
type ghostty_platform_e (line 37) | typedef enum {
type ghostty_clipboard_e (line 43) | typedef enum {
type ghostty_clipboard_content_s (line 48) | typedef struct {
type ghostty_clipboard_request_e (line 53) | typedef enum {
type ghostty_input_mouse_state_e (line 59) | typedef enum {
type ghostty_input_mouse_button_e (line 64) | typedef enum {
type ghostty_input_mouse_momentum_e (line 71) | typedef enum {
type ghostty_color_scheme_e (line 81) | typedef enum {
type ghostty_input_scroll_mods_t (line 89) | typedef int ghostty_input_scroll_mods_t;
type ghostty_input_mods_e (line 91) | typedef enum {
type ghostty_binding_flags_e (line 105) | typedef enum {
type ghostty_input_action_e (line 112) | typedef enum {
type ghostty_input_key_e (line 119) | typedef enum {
type ghostty_input_key_s (line 314) | typedef struct {
type ghostty_input_trigger_tag_e (line 324) | typedef enum {
type ghostty_input_trigger_key_u (line 330) | typedef union {
type ghostty_input_trigger_s (line 337) | typedef struct {
type ghostty_command_s (line 343) | typedef struct {
type ghostty_build_mode_e (line 350) | typedef enum {
type ghostty_info_s (line 357) | typedef struct {
type ghostty_diagnostic_s (line 363) | typedef struct {
type ghostty_string_s (line 367) | typedef struct {
type ghostty_text_s (line 373) | typedef struct {
type ghostty_point_tag_e (line 382) | typedef enum {
type ghostty_point_coord_e (line 389) | typedef enum {
type ghostty_point_s (line 395) | typedef struct {
type ghostty_selection_s (line 402) | typedef struct {
type ghostty_env_var_s (line 408) | typedef struct {
type ghostty_platform_macos_s (line 413) | typedef struct {
type ghostty_platform_ios_s (line 417) | typedef struct {
type ghostty_platform_u (line 421) | typedef union {
type ghostty_surface_context_e (line 426) | typedef enum {
type ghostty_surface_config_s (line 432) | typedef struct {
type ghostty_surface_size_s (line 447) | typedef struct {
type ghostty_config_color_s (line 459) | typedef struct {
type ghostty_config_color_list_s (line 466) | typedef struct {
type ghostty_config_command_list_s (line 472) | typedef struct {
type ghostty_config_palette_s (line 478) | typedef struct {
type ghostty_quick_terminal_size_tag_e (line 483) | typedef enum {
type ghostty_quick_terminal_size_value_u (line 489) | typedef union {
type ghostty_quick_terminal_size_s (line 494) | typedef struct {
type ghostty_config_quick_terminal_size_s (line 499) | typedef struct {
type ghostty_target_tag_e (line 505) | typedef enum {
type ghostty_target_u (line 510) | typedef union {
type ghostty_target_s (line 514) | typedef struct {
type ghostty_action_split_direction_e (line 520) | typedef enum {
type ghostty_action_goto_split_e (line 528) | typedef enum {
type ghostty_action_goto_window_e (line 538) | typedef enum {
type ghostty_action_resize_split_direction_e (line 544) | typedef enum {
type ghostty_action_resize_split_s (line 552) | typedef struct {
type ghostty_action_move_tab_s (line 558) | typedef struct {
type ghostty_action_goto_tab_e (line 563) | typedef enum {
type ghostty_action_fullscreen_e (line 570) | typedef enum {
type ghostty_action_float_window_e (line 578) | typedef enum {
type ghostty_action_secure_input_e (line 585) | typedef enum {
type ghostty_action_inspector_e (line 592) | typedef enum {
type ghostty_action_quit_timer_e (line 599) | typedef enum {
type ghostty_action_readonly_e (line 605) | typedef enum {
type ghostty_action_desktop_notification_s (line 611) | typedef struct {
type ghostty_action_set_title_s (line 617) | typedef struct {
type ghostty_action_prompt_title_e (line 622) | typedef enum {
type ghostty_action_pwd_s (line 628) | typedef struct {
type ghostty_action_mouse_shape_e (line 633) | typedef enum {
type ghostty_action_mouse_visibility_e (line 671) | typedef enum {
type ghostty_action_mouse_over_link_s (line 677) | typedef struct {
type ghostty_action_size_limit_s (line 683) | typedef struct {
type ghostty_action_initial_size_s (line 691) | typedef struct {
type ghostty_action_cell_size_s (line 697) | typedef struct {
type ghostty_action_renderer_health_e (line 703) | typedef enum {
type ghostty_action_key_sequence_s (line 709) | typedef struct {
type ghostty_action_key_table_tag_e (line 715) | typedef enum {
type ghostty_action_key_table_u (line 722) | typedef union {
type ghostty_action_key_table_s (line 730) | typedef struct {
type ghostty_action_color_kind_e (line 736) | typedef enum {
type ghostty_action_color_change_s (line 743) | typedef struct {
type ghostty_action_config_change_s (line 751) | typedef struct {
type ghostty_action_reload_config_s (line 756) | typedef struct {
type ghostty_action_open_url_kind_e (line 761) | typedef enum {
type ghostty_action_open_url_s (line 768) | typedef struct {
type ghostty_action_close_tab_mode_e (line 775) | typedef enum {
type ghostty_surface_message_childexited_s (line 782) | typedef struct {
type ghostty_action_progress_report_state_e (line 788) | typedef enum {
type ghostty_action_progress_report_s (line 797) | typedef struct {
type ghostty_action_command_finished_s (line 805) | typedef struct {
type ghostty_action_start_search_s (line 813) | typedef struct {
type ghostty_action_search_total_s (line 818) | typedef struct {
type ghostty_action_search_selected_s (line 823) | typedef struct {
type ghostty_action_scrollbar_s (line 828) | typedef struct {
type ghostty_action_tag_e (line 835) | typedef enum {
type ghostty_action_u (line 901) | typedef union {
type ghostty_action_s (line 941) | typedef struct {
type ghostty_runtime_config_s (line 965) | typedef struct {
type ghostty_ipc_target_tag_e (line 977) | typedef enum {
type ghostty_ipc_target_u (line 982) | typedef union {
type chostty_ipc_target_s (line 986) | typedef struct {
type ghostty_ipc_action_new_window_s (line 992) | typedef struct {
type ghostty_ipc_action_u (line 997) | typedef union {
type ghostty_ipc_action_tag_e (line 1002) | typedef enum {
FILE: ghostty/Vendor/include/ghostty/vt/allocator.h
type GhosttyAllocatorVtable (line 83) | typedef struct {
type GhosttyAllocator (line 179) | typedef struct GhosttyAllocator {
FILE: ghostty/Vendor/include/ghostty/vt/color.h
type GhosttyColorRgb (line 21) | typedef struct {
type GhosttyColorPaletteIndex (line 32) | typedef uint8_t GhosttyColorPaletteIndex;
FILE: ghostty/Vendor/include/ghostty/vt/key/encoder.h
type GhosttyKeyEncoder (line 24) | struct GhosttyKeyEncoder
type GhosttyKittyKeyFlags (line 35) | typedef uint8_t GhosttyKittyKeyFlags;
type GhosttyOptionAsAlt (line 66) | typedef enum {
type GhosttyKeyEncoderOption (line 85) | typedef enum {
FILE: ghostty/Vendor/include/ghostty/vt/key/event.h
type GhosttyKeyEvent (line 24) | struct GhosttyKeyEvent
type GhosttyKeyAction (line 31) | typedef enum {
type GhosttyMods (line 56) | typedef uint16_t GhosttyMods;
type GhosttyKey (line 106) | typedef enum {
FILE: ghostty/Vendor/include/ghostty/vt/osc.h
type GhosttyOscParser (line 24) | struct GhosttyOscParser
type GhosttyOscCommand (line 34) | struct GhosttyOscCommand
type GhosttyOscCommandType (line 62) | typedef enum {
type GhosttyOscCommandData (line 94) | typedef enum {
FILE: ghostty/Vendor/include/ghostty/vt/result.h
type GhosttyResult (line 13) | typedef enum {
FILE: ghostty/Vendor/include/ghostty/vt/sgr.h
type GhosttySgrParser (line 93) | struct GhosttySgrParser
type GhosttySgrAttributeTag (line 103) | typedef enum {
type GhosttySgrUnderline (line 143) | typedef enum {
type GhosttySgrUnknown (line 160) | typedef struct {
type GhosttySgrAttributeValue (line 176) | typedef union {
type GhosttySgrAttribute (line 204) | typedef struct {
FILE: scripts/gen-third-party-notices.py
function run_git (line 26) | def run_git(args, cwd):
function repo_url_for_path (line 36) | def repo_url_for_path(path):
function read_file (line 41) | def read_file(path):
function pick_first_existing (line 46) | def pick_first_existing(base_dir, names):
function checkout_dir_for_pin (line 54) | def checkout_dir_for_pin(identity, location):
function version_label (line 69) | def version_label(state):
function load_pins (line 81) | def load_pins():
function main (line 90) | def main():
Condensed preview — 472 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,388K chars).
[
{
"path": ".gitignore",
"chars": 581,
"preview": ".build/\n.swiftpm/\n.DS_Store\nartifacts/\nbuild/\nbuild-mas/\nlogs/\n.xcuserstate\n._*\nCodMate.app\n\n# Xcode per-user state and "
},
{
"path": ".vscode/launch.json",
"chars": 582,
"preview": "{\n \"configurations\": [\n {\n \"type\": \"lldb\",\n \"request\": \"launch\",\n \"args\": [],\n \"cwd\": \"${workspa"
},
{
"path": "AGENTS.md",
"chars": 23168,
"preview": "CodMate – AGENTS Guidelines\n\nPurpose\n- This document tells AI/code agents how to work inside the CodMate repository (mac"
},
{
"path": "CodMateApp.swift",
"chars": 13883,
"preview": "import SwiftUI\nimport GhosttyKit\n\n#if os(macOS)\n import AppKit\n#endif\n\n@main\nstruct CodMateApp: App {\n #if os(macOS)\n "
},
{
"path": "Ghostty-header.h",
"chars": 520,
"preview": "//\n// Ghostty-header.h\n// CodMate\n//\n// Bridging header to expose Ghostty C API to Swift\n//\n\n#ifndef Ghostty_header_h"
},
{
"path": "LICENSE",
"chars": 11367,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Makefile",
"chars": 4956,
"preview": ".PHONY: help build release test app dmg zip clean run debug debug-logs debug-app debug-file notices\n\nAPP_NAME := CodMate"
},
{
"path": "NOTICE",
"chars": 34,
"preview": "CodMate\nCopyright (c) 2025 Loocor\n"
},
{
"path": "Package.resolved",
"chars": 1196,
"preview": "{\n \"originHash\" : \"06ecd22962877ed07b043a2d3eeba48fbdcada27c6982dc3012cc48805daf65f\",\n \"pins\" : [\n {\n \"identit"
},
{
"path": "Package.swift",
"chars": 1676,
"preview": "// swift-tools-version: 6.0\n\nimport PackageDescription\n\nlet package = Package(\n name: \"CodMate\",\n defaultLocalization:"
},
{
"path": "PrivacyInfo.xcprivacy",
"chars": 140,
"preview": "{\n \"NSPrivacyTracking\": false,\n \"NSPrivacyTrackingDomains\": [],\n \"NSPrivacyCollectedDataTypes\": [],\n \"NSPrivacyAcces"
},
{
"path": "README.md",
"chars": 15812,
"preview": "# CodMate\n\n\n\nCodMate is a macOS SwiftUI app for **managing CLI AI sessions**: brows"
},
{
"path": "THIRD-PARTY-NOTICES.md",
"chars": 52873,
"preview": "Third-Party Notices\n\nThis document lists third-party components included in CodMate distributions, along with their lice"
},
{
"path": "Tests/CodMateTests/ClaudeHooksAdapterTests.swift",
"chars": 4043,
"preview": "import XCTest\n@testable import CodMate\n\nfinal class ClaudeHooksAdapterTests: XCTestCase {\n func testApplyHooksWritesCla"
},
{
"path": "Tests/CodMateTests/CodexHooksAdapterTests.swift",
"chars": 2431,
"preview": "import XCTest\n@testable import CodMate\n\nfinal class CodexHooksAdapterTests: XCTestCase {\n func testApplySingleStopHookW"
},
{
"path": "Tests/CodMateTests/GeminiHooksAdapterTests.swift",
"chars": 2973,
"preview": "import XCTest\n@testable import CodMate\n\nfinal class GeminiHooksAdapterTests: XCTestCase {\n func testApplyHooksWritesGem"
},
{
"path": "Tests/CodMateTests/HooksStoreTests.swift",
"chars": 1205,
"preview": "import XCTest\n@testable import CodMate\n\nfinal class HooksStoreTests: XCTestCase {\n func testUpsertListUpdateDelete() as"
},
{
"path": "Tests/CodMateTests/UpdateServiceTests.swift",
"chars": 660,
"preview": "import XCTest\n@testable import CodMate\n\nfinal class UpdateServiceTests: XCTestCase {\n func testParseLatestRelease() thr"
},
{
"path": "Tests/CodMateTests/UpdateSupportTests.swift",
"chars": 498,
"preview": "import XCTest\n@testable import CodMate\n\nfinal class UpdateSupportTests: XCTestCase {\n func testVersionCompare() {\n X"
},
{
"path": "Tests/CodMateTests/UpdateViewModelTests.swift",
"chars": 4949,
"preview": "import Foundation\nimport XCTest\n@testable import CodMate\n\nfinal class UpdateViewModelTests: XCTestCase {\n @MainActor\n "
},
{
"path": "Tests/CodMateTests/WizardResponseParserTests.swift",
"chars": 1189,
"preview": "import XCTest\n@testable import CodMate\n\nfinal class WizardResponseParserTests: XCTestCase {\n func testDecodeEnvelope() "
},
{
"path": "assets/Assets.xcassets/AntigravityIcon.imageset/Contents.json",
"chars": 270,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"antigravity.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" "
},
{
"path": "assets/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 1020,
"preview": "{\n \"images\" : [\n { \"idiom\" : \"mac\", \"size\" : \"16x16\", \"scale\" : \"1x\", \"filename\" : \"icon_16x16.png\" },\n { \"idio"
},
{
"path": "assets/Assets.xcassets/ChatGPTIcon.imageset/Contents.json",
"chars": 266,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"chatgpt.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"x"
},
{
"path": "assets/Assets.xcassets/ClaudeIcon.imageset/Contents.json",
"chars": 265,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"claude.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"xc"
},
{
"path": "assets/Assets.xcassets/Contents.json",
"chars": 64,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n\n"
},
{
"path": "assets/Assets.xcassets/DeepSeekIcon.imageset/Contents.json",
"chars": 257,
"preview": "{\n \"images\": [\n {\n \"filename\": \"deepseek.svg\",\n \"idiom\": \"mac\"\n }\n ],\n \"info\": {\n \"author\": \"xcode"
},
{
"path": "assets/Assets.xcassets/GeminiIcon.imageset/Contents.json",
"chars": 265,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"gemini.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"xc"
},
{
"path": "assets/Assets.xcassets/KimiIcon.imageset/Contents.json",
"chars": 263,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"kimi.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"xcod"
},
{
"path": "assets/Assets.xcassets/MCPMateLogo.imageset/Contents.json",
"chars": 220,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"MCPMate.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"x"
},
{
"path": "assets/Assets.xcassets/MiniMaxIcon.imageset/Contents.json",
"chars": 266,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"minimax.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"x"
},
{
"path": "assets/Assets.xcassets/OpenRouterIcon.imageset/Contents.json",
"chars": 269,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"openrouter.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" :"
},
{
"path": "assets/Assets.xcassets/QwenIcon.imageset/Contents.json",
"chars": 263,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"qwen.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"xcod"
},
{
"path": "assets/Assets.xcassets/ZaiIcon.imageset/Contents.json",
"chars": 262,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"zai.svg\",\n \"idiom\" : \"mac\"\n }\n ],\n \"info\" : {\n \"author\" : \"xcode"
},
{
"path": "assets/CodMate-Notify.entitlements",
"chars": 639,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "assets/CodMate.entitlements",
"chars": 639,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "assets/Info.plist",
"chars": 2065,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "docs/feature-inventory.md",
"chars": 24006,
"preview": "# CodMate Feature Inventory\n\n> Purpose: Provide a traceable feature inventory with code evidence (file paths) for value/"
},
{
"path": "docs/icon.icon/icon.json",
"chars": 1513,
"preview": "{\n \"fill\" : {\n \"automatic-gradient\" : \"extended-srgb:0.00000,0.53333,1.00000,1.00000\"\n },\n \"groups\" : [\n {\n "
},
{
"path": "docs/projects.md",
"chars": 4599,
"preview": "Projects in CodMate (Phase 1)\n\nOverview\n- Introduces a virtual “Projects” view to organize Codex sessions conceptually, "
},
{
"path": "ghostty/Package.swift",
"chars": 1606,
"preview": "// swift-tools-version: 6.0\n\nimport PackageDescription\nimport Foundation\n\nlet packageDir = URL(fileURLWithPath: #filePat"
},
{
"path": "ghostty/Resources/themes/Apple Classic",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#c91b00\npalette = 2=#00c200\npalette = 3=#c7c400\npalette = 4=#1c3fe1\npalette = 5=#ca30c7\n"
},
{
"path": "ghostty/Resources/themes/Apple System Colors",
"chars": 475,
"preview": "palette = 0=#1a1a1a\npalette = 1=#cc372e\npalette = 2=#26a439\npalette = 3=#cdac08\npalette = 4=#0869cb\npalette = 5=#9647bf\n"
},
{
"path": "ghostty/Resources/themes/Apple System Colors Light",
"chars": 475,
"preview": "palette = 0=#1a1a1a\npalette = 1=#cc372e\npalette = 2=#26a439\npalette = 3=#cdac08\npalette = 4=#0869cb\npalette = 5=#9647bf\n"
},
{
"path": "ghostty/Resources/themes/Atom",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#fd5ff1\npalette = 2=#87c38a\npalette = 3=#ffd7b1\npalette = 4=#85befd\npalette = 5=#b9b6fc\n"
},
{
"path": "ghostty/Resources/themes/Atom One Dark",
"chars": 475,
"preview": "palette = 0=#21252b\npalette = 1=#e06c75\npalette = 2=#98c379\npalette = 3=#e5c07b\npalette = 4=#61afef\npalette = 5=#c678dd\n"
},
{
"path": "ghostty/Resources/themes/Atom One Light",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#de3e35\npalette = 2=#3f953a\npalette = 3=#d2b67c\npalette = 4=#2f5af3\npalette = 5=#950095\n"
},
{
"path": "ghostty/Resources/themes/Dracula",
"chars": 475,
"preview": "palette = 0=#21222c\npalette = 1=#ff5555\npalette = 2=#50fa7b\npalette = 3=#f1fa8c\npalette = 4=#bd93f9\npalette = 5=#ff79c6\n"
},
{
"path": "ghostty/Resources/themes/Dracula+",
"chars": 475,
"preview": "palette = 0=#21222c\npalette = 1=#ff5555\npalette = 2=#50fa7b\npalette = 3=#ffcb6b\npalette = 4=#82aaff\npalette = 5=#c792ea\n"
},
{
"path": "ghostty/Resources/themes/Farmhouse Dark",
"chars": 475,
"preview": "palette = 0=#1d2027\npalette = 1=#ba0004\npalette = 2=#549d00\npalette = 3=#c87300\npalette = 4=#0049e6\npalette = 5=#9f1b61\n"
},
{
"path": "ghostty/Resources/themes/Farmhouse Light",
"chars": 475,
"preview": "palette = 0=#1d2027\npalette = 1=#8d0003\npalette = 2=#3a7d00\npalette = 3=#a95600\npalette = 4=#092ccd\npalette = 5=#820046\n"
},
{
"path": "ghostty/Resources/themes/Flexoki Dark",
"chars": 475,
"preview": "palette = 0=#100f0f\npalette = 1=#d14d41\npalette = 2=#879a39\npalette = 3=#d0a215\npalette = 4=#4385be\npalette = 5=#ce5d97\n"
},
{
"path": "ghostty/Resources/themes/Flexoki Light",
"chars": 475,
"preview": "palette = 0=#100f0f\npalette = 1=#af3029\npalette = 2=#66800b\npalette = 3=#ad8301\npalette = 4=#205ea6\npalette = 5=#a02f6f\n"
},
{
"path": "ghostty/Resources/themes/GitHub",
"chars": 475,
"preview": "palette = 0=#3e3e3e\npalette = 1=#970b16\npalette = 2=#07962a\npalette = 3=#c5bb94\npalette = 4=#003e8a\npalette = 5=#e94691\n"
},
{
"path": "ghostty/Resources/themes/GitHub Dark",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#f78166\npalette = 2=#56d364\npalette = 3=#e3b341\npalette = 4=#6ca4f8\npalette = 5=#db61a2\n"
},
{
"path": "ghostty/Resources/themes/GitHub Dark Colorblind",
"chars": 475,
"preview": "palette = 0=#484f58\npalette = 1=#ec8e2c\npalette = 2=#58a6ff\npalette = 3=#d29922\npalette = 4=#58a6ff\npalette = 5=#bc8cff\n"
},
{
"path": "ghostty/Resources/themes/GitHub Dark Default",
"chars": 475,
"preview": "palette = 0=#484f58\npalette = 1=#ff7b72\npalette = 2=#3fb950\npalette = 3=#d29922\npalette = 4=#58a6ff\npalette = 5=#bc8cff\n"
},
{
"path": "ghostty/Resources/themes/GitHub Dark Dimmed",
"chars": 475,
"preview": "palette = 0=#545d68\npalette = 1=#f47067\npalette = 2=#57ab5a\npalette = 3=#c69026\npalette = 4=#539bf5\npalette = 5=#b083f0\n"
},
{
"path": "ghostty/Resources/themes/GitHub Dark High Contrast",
"chars": 475,
"preview": "palette = 0=#7a828e\npalette = 1=#ff9492\npalette = 2=#26cd4d\npalette = 3=#f0b72f\npalette = 4=#71b7ff\npalette = 5=#cb9eff\n"
},
{
"path": "ghostty/Resources/themes/GitHub Light Colorblind",
"chars": 475,
"preview": "palette = 0=#24292f\npalette = 1=#b35900\npalette = 2=#0550ae\npalette = 3=#4d2d00\npalette = 4=#0969da\npalette = 5=#8250df\n"
},
{
"path": "ghostty/Resources/themes/GitHub Light Default",
"chars": 475,
"preview": "palette = 0=#24292f\npalette = 1=#cf222e\npalette = 2=#116329\npalette = 3=#4d2d00\npalette = 4=#0969da\npalette = 5=#8250df\n"
},
{
"path": "ghostty/Resources/themes/GitHub Light High Contrast",
"chars": 475,
"preview": "palette = 0=#0e1116\npalette = 1=#a0111f\npalette = 2=#024c1a\npalette = 3=#3f2200\npalette = 4=#0349b4\npalette = 5=#622cbc\n"
},
{
"path": "ghostty/Resources/themes/GitLab Dark",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#f57f6c\npalette = 2=#52b87a\npalette = 3=#d99530\npalette = 4=#7fb6ed\npalette = 5=#f88aaf\n"
},
{
"path": "ghostty/Resources/themes/GitLab Dark Grey",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#f57f6c\npalette = 2=#52b87a\npalette = 3=#d99530\npalette = 4=#7fb6ed\npalette = 5=#f88aaf\n"
},
{
"path": "ghostty/Resources/themes/GitLab Light",
"chars": 475,
"preview": "palette = 0=#303030\npalette = 1=#a31700\npalette = 2=#0a7f3d\npalette = 3=#af551d\npalette = 4=#006cd8\npalette = 5=#583cac\n"
},
{
"path": "ghostty/Resources/themes/Iceberg Dark",
"chars": 475,
"preview": "palette = 0=#1e2132\npalette = 1=#e27878\npalette = 2=#b4be82\npalette = 3=#e2a478\npalette = 4=#84a0c6\npalette = 5=#a093c7\n"
},
{
"path": "ghostty/Resources/themes/Iceberg Light",
"chars": 475,
"preview": "palette = 0=#dcdfe7\npalette = 1=#cc517a\npalette = 2=#668e3d\npalette = 3=#c57339\npalette = 4=#2d539e\npalette = 5=#7759b4\n"
},
{
"path": "ghostty/Resources/themes/Material",
"chars": 475,
"preview": "palette = 0=#212121\npalette = 1=#b7141f\npalette = 2=#457b24\npalette = 3=#f6981e\npalette = 4=#134eb2\npalette = 5=#560088\n"
},
{
"path": "ghostty/Resources/themes/Material Dark",
"chars": 475,
"preview": "palette = 0=#212121\npalette = 1=#b7141f\npalette = 2=#457b24\npalette = 3=#f6981e\npalette = 4=#134eb2\npalette = 5=#6f1aa1\n"
},
{
"path": "ghostty/Resources/themes/Material Darker",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#ff5370\npalette = 2=#c3e88d\npalette = 3=#ffcb6b\npalette = 4=#82aaff\npalette = 5=#c792ea\n"
},
{
"path": "ghostty/Resources/themes/Material Design Colors",
"chars": 475,
"preview": "palette = 0=#435b67\npalette = 1=#fc3841\npalette = 2=#5cf19e\npalette = 3=#fed032\npalette = 4=#37b6ff\npalette = 5=#fc226e\n"
},
{
"path": "ghostty/Resources/themes/Material Ocean",
"chars": 475,
"preview": "palette = 0=#546e7a\npalette = 1=#ff5370\npalette = 2=#c3e88d\npalette = 3=#ffcb6b\npalette = 4=#82aaff\npalette = 5=#c792ea\n"
},
{
"path": "ghostty/Resources/themes/Melange Dark",
"chars": 475,
"preview": "palette = 0=#34302c\npalette = 1=#bd8183\npalette = 2=#78997a\npalette = 3=#e49b5d\npalette = 4=#7f91b2\npalette = 5=#b380b0\n"
},
{
"path": "ghostty/Resources/themes/Melange Light",
"chars": 475,
"preview": "palette = 0=#e9e1db\npalette = 1=#c77b8b\npalette = 2=#6e9b72\npalette = 3=#bc5c00\npalette = 4=#7892bd\npalette = 5=#be79bb\n"
},
{
"path": "ghostty/Resources/themes/Monokai Pro",
"chars": 475,
"preview": "palette = 0=#2d2a2e\npalette = 1=#ff6188\npalette = 2=#a9dc76\npalette = 3=#ffd866\npalette = 4=#fc9867\npalette = 5=#ab9df2\n"
},
{
"path": "ghostty/Resources/themes/Monokai Pro Light",
"chars": 475,
"preview": "palette = 0=#faf4f2\npalette = 1=#e14775\npalette = 2=#269d69\npalette = 3=#cc7a0a\npalette = 4=#e16032\npalette = 5=#7058be\n"
},
{
"path": "ghostty/Resources/themes/Monokai Pro Light Sun",
"chars": 475,
"preview": "palette = 0=#f8efe7\npalette = 1=#ce4770\npalette = 2=#218871\npalette = 3=#b16803\npalette = 4=#d4572b\npalette = 5=#6851a2\n"
},
{
"path": "ghostty/Resources/themes/Monokai Pro Machine",
"chars": 475,
"preview": "palette = 0=#273136\npalette = 1=#ff6d7e\npalette = 2=#a2e57b\npalette = 3=#ffed72\npalette = 4=#ffb270\npalette = 5=#baa0f8\n"
},
{
"path": "ghostty/Resources/themes/Monokai Pro Octagon",
"chars": 475,
"preview": "palette = 0=#282a3a\npalette = 1=#ff657a\npalette = 2=#bad761\npalette = 3=#ffd76d\npalette = 4=#ff9b5e\npalette = 5=#c39ac9\n"
},
{
"path": "ghostty/Resources/themes/Monokai Pro Ristretto",
"chars": 475,
"preview": "palette = 0=#2c2525\npalette = 1=#fd6883\npalette = 2=#adda78\npalette = 3=#f9cc6c\npalette = 4=#f38d70\npalette = 5=#a8a9eb\n"
},
{
"path": "ghostty/Resources/themes/Monokai Pro Spectrum",
"chars": 475,
"preview": "palette = 0=#222222\npalette = 1=#fc618d\npalette = 2=#7bd88f\npalette = 3=#fce566\npalette = 4=#fd9353\npalette = 5=#948ae3\n"
},
{
"path": "ghostty/Resources/themes/Monokai Remastered",
"chars": 475,
"preview": "palette = 0=#1a1a1a\npalette = 1=#f4005f\npalette = 2=#98e024\npalette = 3=#fd971f\npalette = 4=#9d65ff\npalette = 5=#f4005f\n"
},
{
"path": "ghostty/Resources/themes/Neobones Dark",
"chars": 475,
"preview": "palette = 0=#0f191f\npalette = 1=#de6e7c\npalette = 2=#90ff6b\npalette = 3=#b77e64\npalette = 4=#8190d4\npalette = 5=#b279a7\n"
},
{
"path": "ghostty/Resources/themes/Neobones Light",
"chars": 475,
"preview": "palette = 0=#e5ede6\npalette = 1=#a8334c\npalette = 2=#567a30\npalette = 3=#944927\npalette = 4=#286486\npalette = 5=#88507d\n"
},
{
"path": "ghostty/Resources/themes/Nvim Dark",
"chars": 475,
"preview": "palette = 0=#07080d\npalette = 1=#ffc0b9\npalette = 2=#b3f6c0\npalette = 3=#fce094\npalette = 4=#a6dbff\npalette = 5=#ffcaff\n"
},
{
"path": "ghostty/Resources/themes/Nvim Light",
"chars": 475,
"preview": "palette = 0=#07080d\npalette = 1=#590008\npalette = 2=#005523\npalette = 3=#6b5300\npalette = 4=#004c73\npalette = 5=#470045\n"
},
{
"path": "ghostty/Resources/themes/One Double Dark",
"chars": 475,
"preview": "palette = 0=#3d4452\npalette = 1=#f16372\npalette = 2=#8cc570\npalette = 3=#ecbe70\npalette = 4=#3fb1f5\npalette = 5=#d373e3\n"
},
{
"path": "ghostty/Resources/themes/One Double Light",
"chars": 475,
"preview": "palette = 0=#454b58\npalette = 1=#f74840\npalette = 2=#25a343\npalette = 3=#cc8100\npalette = 4=#0087c1\npalette = 5=#b50da9\n"
},
{
"path": "ghostty/Resources/themes/One Half Dark",
"chars": 475,
"preview": "palette = 0=#282c34\npalette = 1=#e06c75\npalette = 2=#98c379\npalette = 3=#e5c07b\npalette = 4=#61afef\npalette = 5=#c678dd\n"
},
{
"path": "ghostty/Resources/themes/One Half Light",
"chars": 475,
"preview": "palette = 0=#383a42\npalette = 1=#e45649\npalette = 2=#50a14f\npalette = 3=#c18401\npalette = 4=#0184bc\npalette = 5=#a626a4\n"
},
{
"path": "ghostty/Resources/themes/Pencil Dark",
"chars": 475,
"preview": "palette = 0=#212121\npalette = 1=#c30771\npalette = 2=#10a778\npalette = 3=#a89c14\npalette = 4=#008ec4\npalette = 5=#5f4986\n"
},
{
"path": "ghostty/Resources/themes/Pencil Light",
"chars": 475,
"preview": "palette = 0=#212121\npalette = 1=#c30771\npalette = 2=#10a778\npalette = 3=#a89c14\npalette = 4=#008ec4\npalette = 5=#523c79\n"
},
{
"path": "ghostty/Resources/themes/Raycast Dark",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#ff5360\npalette = 2=#59d499\npalette = 3=#ffc531\npalette = 4=#56c2ff\npalette = 5=#cf2f98\n"
},
{
"path": "ghostty/Resources/themes/Raycast Light",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#b12424\npalette = 2=#006b4f\npalette = 3=#f8a300\npalette = 4=#138af2\npalette = 5=#9a1b6e\n"
},
{
"path": "ghostty/Resources/themes/Selenized Dark",
"chars": 475,
"preview": "palette = 0=#184956\npalette = 1=#fa5750\npalette = 2=#75b938\npalette = 3=#dbb32d\npalette = 4=#4695f7\npalette = 5=#f275be\n"
},
{
"path": "ghostty/Resources/themes/Selenized Light",
"chars": 475,
"preview": "palette = 0=#ece3cc\npalette = 1=#d2212d\npalette = 2=#489100\npalette = 3=#ad8900\npalette = 4=#0072d4\npalette = 5=#ca4898\n"
},
{
"path": "ghostty/Resources/themes/Seoulbones Dark",
"chars": 475,
"preview": "palette = 0=#4b4b4b\npalette = 1=#e388a3\npalette = 2=#98bd99\npalette = 3=#ffdf9b\npalette = 4=#97bdde\npalette = 5=#a5a6c5\n"
},
{
"path": "ghostty/Resources/themes/Seoulbones Light",
"chars": 475,
"preview": "palette = 0=#e2e2e2\npalette = 1=#dc5284\npalette = 2=#628562\npalette = 3=#c48562\npalette = 4=#0084a3\npalette = 5=#896788\n"
},
{
"path": "ghostty/Resources/themes/Tinacious Design Dark",
"chars": 475,
"preview": "palette = 0=#1d1d26\npalette = 1=#ff3399\npalette = 2=#00d364\npalette = 3=#ffcc66\npalette = 4=#00cbff\npalette = 5=#cc66ff\n"
},
{
"path": "ghostty/Resources/themes/Tinacious Design Light",
"chars": 475,
"preview": "palette = 0=#1d1d26\npalette = 1=#ff3399\npalette = 2=#00d364\npalette = 3=#e5b34d\npalette = 4=#00cbff\npalette = 5=#cc66ff\n"
},
{
"path": "ghostty/Resources/themes/TokyoNight",
"chars": 475,
"preview": "palette = 0=#15161e\npalette = 1=#f7768e\npalette = 2=#9ece6a\npalette = 3=#e0af68\npalette = 4=#7aa2f7\npalette = 5=#bb9af7\n"
},
{
"path": "ghostty/Resources/themes/TokyoNight Day",
"chars": 475,
"preview": "palette = 0=#e9e9ed\npalette = 1=#f52a65\npalette = 2=#587539\npalette = 3=#8c6c3e\npalette = 4=#2e7de9\npalette = 5=#9854f1\n"
},
{
"path": "ghostty/Resources/themes/TokyoNight Moon",
"chars": 475,
"preview": "palette = 0=#1b1d2b\npalette = 1=#ff757f\npalette = 2=#c3e88d\npalette = 3=#ffc777\npalette = 4=#82aaff\npalette = 5=#c099ff\n"
},
{
"path": "ghostty/Resources/themes/TokyoNight Night",
"chars": 475,
"preview": "palette = 0=#15161e\npalette = 1=#f7768e\npalette = 2=#9ece6a\npalette = 3=#e0af68\npalette = 4=#7aa2f7\npalette = 5=#bb9af7\n"
},
{
"path": "ghostty/Resources/themes/TokyoNight Storm",
"chars": 475,
"preview": "palette = 0=#1d202f\npalette = 1=#f7768e\npalette = 2=#9ece6a\npalette = 3=#e0af68\npalette = 4=#7aa2f7\npalette = 5=#bb9af7\n"
},
{
"path": "ghostty/Resources/themes/Tomorrow",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#c82829\npalette = 2=#718c00\npalette = 3=#eab700\npalette = 4=#4271ae\npalette = 5=#8959a8\n"
},
{
"path": "ghostty/Resources/themes/Tomorrow Night",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#cc6666\npalette = 2=#b5bd68\npalette = 3=#f0c674\npalette = 4=#81a2be\npalette = 5=#b294bb\n"
},
{
"path": "ghostty/Resources/themes/Tomorrow Night Blue",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#ff9da4\npalette = 2=#d1f1a9\npalette = 3=#ffeead\npalette = 4=#bbdaff\npalette = 5=#ebbbff\n"
},
{
"path": "ghostty/Resources/themes/Tomorrow Night Bright",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#d54e53\npalette = 2=#b9ca4a\npalette = 3=#e7c547\npalette = 4=#7aa6da\npalette = 5=#c397d8\n"
},
{
"path": "ghostty/Resources/themes/Tomorrow Night Burns",
"chars": 475,
"preview": "palette = 0=#252525\npalette = 1=#832e31\npalette = 2=#a63c40\npalette = 3=#d3494e\npalette = 4=#fc595f\npalette = 5=#df9395\n"
},
{
"path": "ghostty/Resources/themes/Tomorrow Night Eighties",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#f2777a\npalette = 2=#99cc99\npalette = 3=#ffcc66\npalette = 4=#6699cc\npalette = 5=#cc99cc\n"
},
{
"path": "ghostty/Resources/themes/Xcode Dark",
"chars": 475,
"preview": "palette = 0=#414453\npalette = 1=#ff8170\npalette = 2=#78c2b3\npalette = 3=#d9c97c\npalette = 4=#4eb0cc\npalette = 5=#ff7ab2\n"
},
{
"path": "ghostty/Resources/themes/Xcode Dark hc",
"chars": 475,
"preview": "palette = 0=#43454b\npalette = 1=#ff8a7a\npalette = 2=#83c9bc\npalette = 3=#d9c668\npalette = 4=#4ec4e6\npalette = 5=#ff85b8\n"
},
{
"path": "ghostty/Resources/themes/Xcode Light",
"chars": 475,
"preview": "palette = 0=#b4d8fd\npalette = 1=#d12f1b\npalette = 2=#3e8087\npalette = 3=#78492a\npalette = 4=#0f68a0\npalette = 5=#ad3da4\n"
},
{
"path": "ghostty/Resources/themes/Xcode Light hc",
"chars": 475,
"preview": "palette = 0=#b4d8fd\npalette = 1=#ad1805\npalette = 2=#355d61\npalette = 3=#78492a\npalette = 4=#0058a1\npalette = 5=#9c2191\n"
},
{
"path": "ghostty/Resources/themes/Zenbones Dark",
"chars": 475,
"preview": "palette = 0=#1c1917\npalette = 1=#de6e7c\npalette = 2=#819b69\npalette = 3=#b77e64\npalette = 4=#6099c0\npalette = 5=#b279a7\n"
},
{
"path": "ghostty/Resources/themes/Zenbones Light",
"chars": 475,
"preview": "palette = 0=#f0edec\npalette = 1=#a8334c\npalette = 2=#4f6c31\npalette = 3=#944927\npalette = 4=#286486\npalette = 5=#88507d\n"
},
{
"path": "ghostty/Resources/themes/Zenwritten Dark",
"chars": 475,
"preview": "palette = 0=#191919\npalette = 1=#de6e7c\npalette = 2=#819b69\npalette = 3=#b77e64\npalette = 4=#6099c0\npalette = 5=#b279a7\n"
},
{
"path": "ghostty/Resources/themes/Zenwritten Light",
"chars": 475,
"preview": "palette = 0=#eeeeee\npalette = 1=#a8334c\npalette = 2=#4f6c31\npalette = 3=#944927\npalette = 4=#286486\npalette = 5=#88507d\n"
},
{
"path": "ghostty/Resources/themes/iTerm2 Solarized Dark",
"chars": 475,
"preview": "palette = 0=#073642\npalette = 1=#dc322f\npalette = 2=#859900\npalette = 3=#b58900\npalette = 4=#268bd2\npalette = 5=#d33682\n"
},
{
"path": "ghostty/Resources/themes/iTerm2 Solarized Light",
"chars": 475,
"preview": "palette = 0=#073642\npalette = 1=#dc322f\npalette = 2=#859900\npalette = 3=#b58900\npalette = 4=#268bd2\npalette = 5=#d33682\n"
},
{
"path": "ghostty/Resources/themes/iTerm2 Tango Dark",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#d81e00\npalette = 2=#5ea702\npalette = 3=#cfae00\npalette = 4=#427ab3\npalette = 5=#89658e\n"
},
{
"path": "ghostty/Resources/themes/iTerm2 Tango Light",
"chars": 475,
"preview": "palette = 0=#000000\npalette = 1=#d81e00\npalette = 2=#5ea702\npalette = 3=#cfae00\npalette = 4=#427ab3\npalette = 5=#89658e\n"
},
{
"path": "ghostty/Sources/CGhostty/module.modulemap",
"chars": 119,
"preview": "// Ghostty C API module definition\nmodule CGhostty {\n umbrella header \"ghostty.h\"\n export *\n link \"ghostty\"\n}\n"
},
{
"path": "ghostty/Sources/GhosttyKit/Clipboard.swift",
"chars": 535,
"preview": "//\n// Clipboard.swift\n// GhosttyKit\n//\n// Shared pasteboard helper for simple text copies\n//\n\nimport AppKit\n\nenum Cli"
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.Action.swift",
"chars": 1765,
"preview": "//\n// Ghostty.Action.swift\n// CodMate\n//\n// Action types for Ghostty terminal events\n//\n// This file is adapted from"
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.App.swift",
"chars": 31331,
"preview": "//\n// Ghostty.App.swift\n// CodMate\n//\n// Minimal Ghostty app wrapper - Phase 1: Basic lifecycle\n//\n// This file is a"
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.Input.swift",
"chars": 5144,
"preview": "import AppKit\nimport SwiftUI\nimport CGhostty\n\nextension SwiftUI.EventModifiers {\n /// Initialize EventModifiers from "
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.Key.swift",
"chars": 21533,
"preview": "import Foundation\nimport CGhostty\n\nextension Ghostty.Input {\n /// `ghostty_input_key_e`\n enum Key: String, CaseIte"
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.KeyEvent.swift",
"chars": 3754,
"preview": "import Foundation\nimport CGhostty\n\nextension Ghostty.Input {\n /// `ghostty_input_key_s`\n struct KeyEvent {\n "
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.Mods.swift",
"chars": 2618,
"preview": "import AppKit\nimport Foundation\nimport CGhostty\n\nextension Ghostty.Input {\n /// `ghostty_input_mods_e`\n struct Mod"
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.MouseEvent.swift",
"chars": 4734,
"preview": "import AppKit\nimport Foundation\nimport CGhostty\n\nextension Ghostty.Input {\n /// Represents a mouse input event with b"
},
{
"path": "ghostty/Sources/GhosttyKit/Ghostty.Surface.swift",
"chars": 6972,
"preview": "import Foundation\nimport CGhostty\n\nextension Ghostty {\n /// Represents a single surface within Ghostty.\n ///\n /"
},
{
"path": "ghostty/Sources/GhosttyKit/GhosttyIMEHandler.swift",
"chars": 6343,
"preview": "//\n// GhosttyIMEHandler.swift\n// CodMate\n//\n// Handles Input Method Editor (IME) support for Ghostty terminal\n// Ena"
},
{
"path": "ghostty/Sources/GhosttyKit/GhosttyInputHandler.swift",
"chars": 11445,
"preview": "//\n// GhosttyInputHandler.swift\n// CodMate\n//\n// Handles keyboard, mouse, and scroll input forwarding to Ghostty term"
},
{
"path": "ghostty/Sources/GhosttyKit/GhosttyProgressState.swift",
"chars": 790,
"preview": "//\n// GhosttyProgressState.swift\n// CodMate\n//\n// This file is adapted from Aizen (https://github.com/vivy-company/ai"
},
{
"path": "ghostty/Sources/GhosttyKit/GhosttyRenderingSetup.swift",
"chars": 10201,
"preview": "//\n// GhosttyRenderingSetup.swift\n// CodMate\n//\n// Handles Metal layer setup and rendering configuration for Ghostty "
},
{
"path": "ghostty/Sources/GhosttyKit/GhosttyTerminalView.swift",
"chars": 23014,
"preview": "//\n// GhosttyTerminalView.swift\n// CodMate\n//\n// NSView subclass that integrates Ghostty terminal rendering\n//\n// Th"
},
{
"path": "ghostty/Sources/GhosttyKit/GhosttyThemeLoader.swift",
"chars": 3955,
"preview": "import Foundation\nimport os.log\n\n/// Utility for loading and managing Ghostty terminal themes\n@MainActor\npublic struct G"
},
{
"path": "ghostty/Sources/GhosttyKit/TerminalScrollView.swift",
"chars": 12435,
"preview": "//\n// TerminalScrollView.swift\n// CodMate\n//\n// NSScrollView wrapper for terminal with native macOS scrollbar support"
},
{
"path": "ghostty/Sources/GhosttyKit/TerminalTextCleaner.swift",
"chars": 12475,
"preview": "//\n// TerminalTextCleaner.swift\n// GhosttyKit\n//\n\nimport Foundation\n\nstruct TerminalCopySettings {\n var trimTrailin"
},
{
"path": "ghostty/Vendor/VERSION",
"chars": 41,
"preview": "9fb03ba55c9e53901193187d5c43341f5b1b430d\n"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/allocator.h",
"chars": 8121,
"preview": "/**\n * @file allocator.h\n *\n * Memory management interface for libghostty-vt.\n */\n\n#ifndef GHOSTTY_VT_ALLOCATOR_H\n#defin"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/color.h",
"chars": 2515,
"preview": "/**\n * @file color.h\n *\n * Color types and utilities.\n */\n\n#ifndef GHOSTTY_VT_COLOR_H\n#define GHOSTTY_VT_COLOR_H\n\n#inclu"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/key/encoder.h",
"chars": 7666,
"preview": "/**\n * @file encoder.h\n *\n * Key event encoding to terminal escape sequences.\n */\n\n#ifndef GHOSTTY_VT_KEY_ENCODER_H\n#def"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/key/event.h",
"chars": 12681,
"preview": "/**\n * @file event.h\n *\n * Key event representation and manipulation.\n */\n\n#ifndef GHOSTTY_VT_KEY_EVENT_H\n#define GHOSTT"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/key.h",
"chars": 2398,
"preview": "/**\n * @file key.h\n *\n * Key encoding module - encode key events into terminal escape sequences.\n */\n\n#ifndef GHOSTTY_VT"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/osc.h",
"chars": 7687,
"preview": "/**\n * @file osc.h\n *\n * OSC (Operating System Command) sequence parser and command handling.\n */\n\n#ifndef GHOSTTY_VT_OS"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/paste.h",
"chars": 1665,
"preview": "/**\n * @file paste.h\n *\n * Paste utilities - validate and encode paste data for terminal input.\n */\n\n#ifndef GHOSTTY_VT_"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/result.h",
"chars": 488,
"preview": "/**\n * @file result.h\n *\n * Result codes for libghostty-vt operations.\n */\n\n#ifndef GHOSTTY_VT_RESULT_H\n#define GHOSTTY_"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/sgr.h",
"chars": 12108,
"preview": "/**\n * @file sgr.h\n *\n * SGR (Select Graphic Rendition) attribute parsing and handling.\n */\n\n#ifndef GHOSTTY_VT_SGR_H\n#d"
},
{
"path": "ghostty/Vendor/include/ghostty/vt/wasm.h",
"chars": 4615,
"preview": "/**\n * @file wasm.h\n *\n * WebAssembly utility functions for libghostty-vt.\n */\n\n#ifndef GHOSTTY_VT_WASM_H\n#define GHOSTT"
},
{
"path": "ghostty/Vendor/include/ghostty/vt.h",
"chars": 2997,
"preview": "/**\n * @file vt.h\n *\n * libghostty-vt - Virtual terminal emulator library\n * \n * This library provides functionality for"
},
{
"path": "ghostty/Vendor/include/ghostty.h",
"chars": 32714,
"preview": "// Ghostty embedding API. The documentation for the embedding API is\n// only within the Zig source files that define the"
},
{
"path": "ghostty/Vendor/include/module.modulemap",
"chars": 264,
"preview": "// This makes Ghostty available to the XCode build for the macOS app.\n// We append \"Kit\" to it not to be cute, but becau"
},
{
"path": "models/ActivityChartData.swift",
"chars": 2800,
"preview": "import Foundation\n\nstruct ActivityChartDataPoint: Identifiable, Equatable {\n let id = UUID()\n let date: Date\n l"
},
{
"path": "models/AllOverviewViewModel.swift",
"chars": 9901,
"preview": "import Combine\nimport Foundation\nimport OSLog\n\n@MainActor\nfinal class AllOverviewViewModel: ObservableObject {\n @Publis"
},
{
"path": "models/CLIPathVM.swift",
"chars": 2466,
"preview": "import Foundation\n\n@MainActor\nfinal class CLIPathVM: ObservableObject {\n struct CLIInfo: Equatable {\n var path"
},
{
"path": "models/ClaudeCodeVM.swift",
"chars": 32280,
"preview": "import Foundation\nimport SwiftUI\nimport AppKit\n\n@MainActor\nfinal class ClaudeCodeVM: ObservableObject {\n let builtinM"
},
{
"path": "models/ClaudeUsageStatus.swift",
"chars": 7170,
"preview": "import Foundation\n\nstruct ClaudeUsageStatus: Equatable {\n let updatedAt: Date\n let modelName: String?\n let cont"
},
{
"path": "models/CodexUsageStatus.swift",
"chars": 8547,
"preview": "import Foundation\n\nstruct CodexUsageStatus: Equatable {\n let updatedAt: Date\n let contextUsedTokens: Int?\n let "
},
{
"path": "models/CodexVM.swift",
"chars": 28049,
"preview": "import Foundation\nimport SwiftUI\n\n@MainActor\nfinal class CodexVM: ObservableObject {\n let builtinModels: [String] = [\n "
},
{
"path": "models/CommandRecord.swift",
"chars": 3013,
"preview": "import Foundation\n\n// MARK: - Command Record\n/// Represents a unified slash command that can be synced to multiple AI CL"
},
{
"path": "models/CommandsViewModel.swift",
"chars": 11703,
"preview": "import Foundation\nimport SwiftUI\n\n@MainActor\nclass CommandsViewModel: ObservableObject {\n @Published var commands: [Com"
},
{
"path": "models/ConversationTurn.swift",
"chars": 7489,
"preview": "import Foundation\n\n// MARK: - ConversationTurnPreview\n\n/// Lightweight preview for conversation turns, used for fast ini"
},
{
"path": "models/DateDimension.swift",
"chars": 303,
"preview": "import Foundation\n\nenum DateDimension: String, CaseIterable, Identifiable, Sendable {\n case created\n case updated\n"
},
{
"path": "models/DialecticsVM.swift",
"chars": 12036,
"preview": "import Foundation\nimport SwiftUI\nimport AppKit\n\n@MainActor\nfinal class DialecticsVM: ObservableObject {\n @Published v"
},
{
"path": "models/EditorApp.swift",
"chars": 2782,
"preview": "import Foundation\nimport AppKit\n\nenum EditorApp: String, CaseIterable, Identifiable {\n case vscode\n case cursor\n "
},
{
"path": "models/EnvironmentContextInfo.swift",
"chars": 361,
"preview": "import Foundation\n\nstruct EnvironmentContextInfo: Equatable {\n struct Entry: Identifiable, Equatable {\n let ke"
},
{
"path": "models/ExecutionPolicy.swift",
"chars": 2010,
"preview": "import Foundation\n\nenum SandboxMode: String, CaseIterable, Identifiable, Codable {\n case readOnly = \"read-only\"\n c"
},
{
"path": "models/ExtensionsImportModels.swift",
"chars": 2448,
"preview": "import Foundation\n\nenum ImportResolutionChoice: String, CaseIterable, Identifiable {\n case skip\n case overwrite\n case"
},
{
"path": "models/ExtensionsSettingsTab.swift",
"chars": 171,
"preview": "import Foundation\n\nenum ExtensionsSettingsTab: String, CaseIterable, Identifiable {\n case mcp\n case skills\n case comm"
},
{
"path": "models/ExternalTerminalProfile.swift",
"chars": 2187,
"preview": "import Foundation\n\nstruct ExternalTerminalProfile: Identifiable, Codable, Equatable {\n enum CommandStyle: String, Cod"
},
{
"path": "models/GeminiUsageStatus.swift",
"chars": 3858,
"preview": "import Foundation\n\nstruct GeminiUsageStatus: Equatable {\n struct Bucket: Equatable {\n let modelId: String?\n let t"
},
{
"path": "models/GeminiVM.swift",
"chars": 7390,
"preview": "import AppKit\nimport Foundation\nimport SwiftUI\n\n@MainActor\nfinal class GeminiVM: ObservableObject {\n struct ModelOption"
},
{
"path": "models/GitChangesViewModel.swift",
"chars": 28940,
"preview": "import AppKit\nimport OSLog\nimport Foundation\n\n@MainActor\nfinal class GitChangesViewModel: ObservableObject {\n private"
},
{
"path": "models/GitGraphViewModel.swift",
"chars": 20150,
"preview": "import Foundation\nimport SwiftUI\n\n@MainActor\nfinal class GitGraphViewModel: ObservableObject {\n @Published private(se"
},
{
"path": "models/GitReviewTree.swift",
"chars": 3663,
"preview": "import Foundation\n\nstruct GitReviewNode: Identifiable, Hashable, Sendable {\n var name: String\n var fullPath: Strin"
},
{
"path": "models/GlobalSearchModels.swift",
"chars": 10996,
"preview": "import Foundation\n\nstruct GlobalSearchSnippet: Hashable, Sendable {\n let text: String\n let highlightRange: Range<Int>?"
},
{
"path": "models/GlobalSearchViewModel.swift",
"chars": 12750,
"preview": "import Foundation\n#if canImport(Darwin)\n import Darwin\n#endif\n\n@MainActor\nfinal class GlobalSearchViewModel: Observable"
},
{
"path": "models/HookCommandVariableCatalog.swift",
"chars": 12579,
"preview": "import Foundation\n\nenum HookVariableKind: String, CaseIterable, Sendable, Codable {\n case env\n case stdin\n\n var displ"
},
{
"path": "models/HookEventCatalog.swift",
"chars": 17795,
"preview": "import Foundation\n\nstruct HookEventMatcher: Identifiable, Hashable, Sendable {\n let value: String\n let description: St"
},
{
"path": "models/HookSyncWarning.swift",
"chars": 139,
"preview": "import Foundation\n\nstruct HookSyncWarning: Identifiable, Equatable {\n let id = UUID()\n let provider: HookTarget\n let "
},
{
"path": "models/Hooks.swift",
"chars": 3901,
"preview": "import Foundation\n\nenum HookTarget: String, Codable, CaseIterable, Sendable {\n case codex\n case claude\n case gemini\n\n"
},
{
"path": "models/HooksViewModel.swift",
"chars": 7573,
"preview": "import Foundation\n\n@MainActor\nfinal class HooksViewModel: ObservableObject {\n @Published var rules: [HookRule] = []\n @"
},
{
"path": "models/InternalSkill.swift",
"chars": 1588,
"preview": "import Foundation\n\nenum InternalSkillIOMode: String, Codable, Sendable {\n case stdin\n case file\n}\n\nenum InternalSkillO"
},
{
"path": "models/LocalAuthProvider.swift",
"chars": 1005,
"preview": "import Foundation\n\nenum LocalAuthProvider: String, CaseIterable, Identifiable {\n case codex\n case claude\n case gemini"
},
{
"path": "models/MCPServer.swift",
"chars": 3893,
"preview": "import Foundation\n\n// MARK: - MCP Server Models\n\npublic enum MCPServerKind: String, Codable, Sendable { case stdio, sse,"
},
{
"path": "models/MCPServersViewModel.swift",
"chars": 28026,
"preview": "import Foundation\nimport SwiftUI\n\n@MainActor\nfinal class MCPServersViewModel: ObservableObject {\n enum Tab: Hashable "
},
{
"path": "models/OverviewAggregate.swift",
"chars": 1034,
"preview": "import Foundation\n\nstruct OverviewSourceAggregate: Sendable {\n let kind: SessionSource.Kind\n let sessionCount: Int\n l"
},
{
"path": "models/PathTree.swift",
"chars": 6220,
"preview": "import Foundation\n\nstruct PathTreeNode: Identifiable, Hashable {\n let id: String // absolute path for uniquenes"
},
{
"path": "models/Project.swift",
"chars": 2964,
"preview": "import Foundation\n\nstruct Project: Identifiable, Hashable, Sendable, Codable {\n var id: String\n var name: String\n "
},
{
"path": "models/ProjectExtensionsModels.swift",
"chars": 463,
"preview": "import Foundation\n\nstruct ProjectMCPConfig: Codable, Hashable, Sendable {\n var id: String\n var isSelected: Bool\n var "
},
{
"path": "models/ProjectExtensionsViewModel.swift",
"chars": 21222,
"preview": "import Foundation\n\nstruct ProjectMCPSelection: Identifiable, Hashable {\n var id: String { server.name }\n var serve"
},
{
"path": "models/ProjectOverviewViewModel.swift",
"chars": 10367,
"preview": "import Combine\nimport Foundation\n\n@MainActor\nfinal class ProjectOverviewViewModel: ObservableObject {\n @Published priva"
},
{
"path": "models/ProjectWorkspaceMode.swift",
"chars": 252,
"preview": "import Foundation\n\nenum ProjectWorkspaceMode: String, Codable, Hashable, CaseIterable {\n case overview\n case tasks"
},
{
"path": "models/ProjectWorkspaceViewModel+Generation.swift",
"chars": 9654,
"preview": "import Foundation\nimport SwiftUI\n\nextension ProjectWorkspaceViewModel {\n /// Generates title and description for a ta"
},
{
"path": "models/ProjectWorkspaceViewModel.swift",
"chars": 10453,
"preview": "import Foundation\nimport SwiftUI\n\n@MainActor\nclass ProjectWorkspaceViewModel: ObservableObject {\n @Published var sele"
},
{
"path": "models/RefreshRequest.swift",
"chars": 535,
"preview": "import Foundation\n\nenum RefreshRequestKind: String {\n case context\n case global\n}\n\nenum RefreshRequest {\n static let "
},
{
"path": "models/ReviewPanelState.swift",
"chars": 1214,
"preview": "import Foundation\n\n// Lightweight, per-session UI state for the Review (Git Changes) panel.\n// Keeps tree expansion/sele"
}
]
// ... and 272 more files (download for full content)
About this extraction
This page contains the full source code of the loocor/codmate GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 472 files (4.0 MB), approximately 1.1M tokens, and a symbol index with 129 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.