refactor(paths): add @application path alias for main/core/application

Align with the existing @logger alias convention by introducing
@application as a short alias for src/main/core/application. This
reduces import verbosity across ~130 main-process files while keeping
4 intentional sub-path imports (@main/core/application/Application)
unchanged to preserve the vi.mock bypass mechanism in tests.

Configured in tsconfig.node.json and electron.vite.config.ts; Vitest
inherits the alias automatically.

Signed-off-by: fullex <0xfullex@gmail.com>
This commit is contained in:
fullex
2026-04-11 22:06:00 -07:00
parent 16e0b44eb9
commit 9b451b87a9
136 changed files with 163 additions and 150 deletions

View File

@@ -9,7 +9,7 @@ This file provides guidance to AI coding assistants when working with code in th
- **Search smart**: Prefer `ast-grep` for semantic queries; fall back to `rg`/`grep` when needed.
- **Build with Tailwind CSS & Shadcn UI**: Use components from `@packages/ui` (Shadcn UI + Tailwind CSS) for every new UI component; never add `antd` or `styled-components`.
- **Log centrally**: Route all logging through `loggerService` with the right context—no `console.log`.
- **Access paths centrally**: Use `application.getPath('namespace.key', filename?)` for all main-process filesystem paths—never call `app.getPath()`, `os.homedir()`, or construct paths ad-hoc.
- **Access paths centrally**: Use `application.getPath('namespace.key', filename?)` for all main-process filesystem paths—never call `app.getPath()`, `os.homedir()`, or construct paths ad-hoc. Import the singleton via `import { application } from '@application'`.
- **Research via subagent**: Lean on `subagent` for external docs, APIs, news, and references.
- **Always propose before executing**: Before making any changes, clearly explain your planned approach and wait for explicit user approval to ensure alignment and prevent unwanted modifications.
- **Lint, test, and format before completion**: Coding tasks are only complete after running `pnpm lint`, `pnpm test`, and `pnpm format` successfully.

View File

@@ -114,7 +114,7 @@ Note: Template keys follow the same dot-separated naming pattern as fixed keys.
Access in main process via lifecycle:
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
const cacheService = application.get('CacheService')
cacheService.setShared('window.layout', layoutConfig)

View File

@@ -118,7 +118,7 @@ Main process CacheService provides SharedCache for cross-window state management
### SharedCache in Main Process
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
const cacheService = application.get('CacheService')

View File

@@ -86,7 +86,7 @@ export const allHandlers: ApiImplementation = {
```typescript
// services/TopicService.ts
import { eq, desc, sql } from 'drizzle-orm'
import { application } from '@main/core/application'
import { application } from '@application'
import { topicTable } from '@data/db/schemas/topic'
import { DataApiErrorFactory } from '@shared/data/api'

View File

@@ -118,7 +118,7 @@ Main process provides `getStats(details?)` for debugging subscription status:
- **Warning**: Resource-intensive, recommended for development only
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
const preferenceService = application.get('PreferenceService')
const stats = preferenceService.getStats(true);

View File

@@ -135,7 +135,7 @@ unsubscribe()
In the main process, PreferenceService is lifecycle-managed. Access it via `application.get()`:
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
const preferenceService = application.get('PreferenceService')

View File

@@ -15,9 +15,10 @@ For lifecycle internals (phases, hooks, states, decorators, events), see [Lifecy
## Quick Start
Both `application` and `serviceList` are barrel-exported from the `@application` path alias (configured in `tsconfig.node.json` and `electron.vite.config.ts`):
```typescript
import { application } from '@main/core/application'
import { serviceList } from '@main/core/application'
import { application, serviceList } from '@application'
// 1. Register all services
application.registerAll(serviceList)
@@ -164,7 +165,7 @@ Always use `application.relaunch()` instead of calling `app.relaunch()` directly
- **Platform fixes**: Linux AppImage `execPath` rewrite, Windows Portable executable path
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
// Simple relaunch
application.relaunch()
@@ -178,7 +179,7 @@ application.relaunch({ args: ['--safe-mode'] })
Always use `application.quit()` or `application.forceExit()` instead of calling `app.quit()` / `app.exit()` directly. An ESLint rule (`no-restricted-properties`) will warn if `app.quit()` or `app.exit()` is used in `src/main/` outside of `Application.ts`.
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
// Graceful quit — triggers the Electron before-quit / will-quit event chain
application.quit()
@@ -242,7 +243,7 @@ The exported `application` constant is a lazy proxy — safe to import at module
```typescript
// Safe to import anywhere, even at module scope
import { application } from '@main/core/application'
import { application } from '@application'
```
## File Structure

View File

@@ -118,7 +118,7 @@ import { windowService } from '@main/services/WindowService'
windowService.createMainWindow()
// NEW
import { application } from '@main/core/application'
import { application } from '@application'
const windowService = application.get('WindowService')
windowService.createMainWindow()
```

View File

@@ -31,7 +31,7 @@ class PreferenceService extends BaseService {
// 2. Register in serviceRegistry.ts and bootstrap via Application
// See: docs/references/lifecycle/application-overview.md
import { application } from '@main/core/application'
import { application } from '@application'
await application.bootstrap()
// 3. Access service instance
@@ -350,7 +350,7 @@ class RealTimeService extends BaseService implements Pausable {
All services support stop/start operations (no special interface needed):
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
await application.stop('HeavyComputeService') // calls onStop()
await application.start('HeavyComputeService') // calls onInit() again
@@ -368,7 +368,7 @@ Unlike `Pausable` (which temporarily suspends execution), `Activatable` controls
### Interface
```typescript
import { application } from '@main/core/application'
import { application } from '@application'
import { BaseService, Injectable, type Activatable } from '@main/core/lifecycle'
@Injectable('SelectionService')

View File

@@ -34,6 +34,7 @@ export default defineConfig({
resolve: {
alias: {
'@main': resolve('src/main'),
'@application': resolve('src/main/core/application'),
'@types': resolve('src/renderer/src/types'),
'@data': resolve('src/main/data'),
'@shared': resolve('packages/shared'),

View File

@@ -8,7 +8,7 @@ const { mockPreferenceGet } = vi.hoisted(() => ({
mockPreferenceGet: vi.fn()
}))
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory({
PreferenceService: { get: mockPreferenceGet }

View File

@@ -1,4 +1,4 @@
import { application } from '@main/core/application'
import { application } from '@application'
import crypto from 'crypto'
import type { NextFunction, Request, Response } from 'express'

View File

@@ -1,7 +1,7 @@
import { createServer } from 'node:http'
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { IpcChannel } from '@shared/IpcChannel'
import { createApp } from './app'

View File

@@ -1,6 +1,6 @@
import { application } from '@application'
import { mcpServerService } from '@data/services/McpServerService'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import type { Tool } from '@modelcontextprotocol/sdk/types'
import type { MCPServer } from '@shared/data/types/mcpServer'

View File

@@ -1,6 +1,6 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { formatProviderApiHost } from '@main/aiCore/provider/providerConfig'
import { application } from '@main/core/application'
import { reduxService } from '@main/services/ReduxService'
import { isSiliconAnthropicCompatibleModel } from '@shared/config/providers'
import type { ApiModel, Model, Provider, ProviderType } from '@types'

View File

@@ -5,6 +5,16 @@ Application is the top-level orchestrator that ties together the lifecycle syste
> **Full documentation** has moved to [docs/references/lifecycle/](../../../../docs/references/lifecycle/README.md).
> This file is a quick-reference pointer.
## Import
Main-process code imports the singleton (and its companions) via the `@application` path alias:
```ts
import { application, serviceList, services } from '@application'
```
The alias is configured in `tsconfig.node.json` (`compilerOptions.paths`) and `electron.vite.config.ts` (`main.resolve.alias`). Vitest inherits the Vite alias automatically.
## Quick Links
| Topic | Reference Doc |

View File

@@ -50,10 +50,11 @@ vi.mock('@main/core/paths/pathRegistry', async () => {
import { Application } from '@main/core/application/Application'
import { buildPathRegistry } from '@main/core/paths/pathRegistry'
// Bypass the global mock of '@main/core/application' (which exports a stub
// Bypass the global mock of '@application' (which exports a stub
// `application` proxy with a no-op bootstrap) by importing the real
// Application class directly via its file path. The global mock only
// intercepts the directory/index path.
// intercepts the directory/index path, leaving `Application.ts` reachable
// via the `@main/*` alias.
describe('Application.getPath', () => {
const app = Application.getInstance()

View File

@@ -6,7 +6,7 @@ All paths are registered in `pathRegistry.ts` and accessed exclusively via `appl
## Quick Start
```ts
import { application } from '@main/core/application'
import { application } from '@application'
const dir = application.getPath('feature.files.data')
//=> '/Users/alice/Library/Application Support/CherryStudio/Data/Files'

View File

@@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
* Mocking strategy (mirrors crashTelemetry.test.ts):
* - `electron` is shadowed per test; only `app.requestSingleInstanceLock`
* is needed. The return value is toggled via a shared vi.fn().
* - `@main/core/application` is shadowed per test with a stub that
* - `@application` is shadowed per test with a stub that
* exposes only `quit()` — the global mock in tests/main.setup.ts
* does not provide it.
* - `process.exit` is a Node global. We temporarily replace it with a
@@ -40,7 +40,7 @@ function stubElectron() {
}
function stubApplication() {
vi.doMock('@main/core/application', () => ({
vi.doMock('@application', () => ({
application: {
quit: applicationQuitMock
}

View File

@@ -13,7 +13,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
* manager, and IPC handler registration functions are all backed by
* shared vi.fn() instances at module scope so assertions can inspect
* call order across test boundaries.
* - `@main/core/application` is globally mocked in tests/main.setup.ts
* - `@application` is globally mocked in tests/main.setup.ts
* but the global mock has no `quit()`; we shadow it per test with a
* factory that provides a spy-able `quit`.
* - `electron` is shadowed so `app.whenReady()` resolves synchronously
@@ -88,7 +88,7 @@ function stubElectron() {
}
function stubApplication() {
vi.doMock('@main/core/application', () => ({
vi.doMock('@application', () => ({
application: {
quit: appQuitMock
}

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { app } from 'electron'
const logger = loggerService.withContext('SingleInstance')

View File

@@ -1,5 +1,6 @@
import fs from 'node:fs'
import { application } from '@application'
import {
getAllMigrators,
migrationEngine,
@@ -15,7 +16,6 @@ import {
readPreviousVersion
} from '@data/migration/v2/core/versionPolicy'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { app, dialog } from 'electron'
const logger = loggerService.withContext('V2MigrationGate')

View File

@@ -1,6 +1,6 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { isDev } from '@main/constant'
import { application } from '@main/core/application'
import { BaseService, DependsOn, Injectable, ServicePhase } from '@main/core/lifecycle'
import { Phase } from '@main/core/lifecycle'
import { bootConfigService } from '@main/data/bootConfig'

View File

@@ -1,7 +1,7 @@
import { application } from '@application'
import type { Client } from '@libsql/client'
import { createClient } from '@libsql/client'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { BaseService, ErrorHandling, Injectable, Priority, ServicePhase } from '@main/core/lifecycle'
import { Phase } from '@main/core/lifecycle'
import { sql } from 'drizzle-orm'
@@ -28,7 +28,7 @@ const logger = loggerService.withContext('DbService')
*
* @example
* ```typescript
* import { application } from '@main/core/application'
* import { application } from '@application'
*
* const db = application.get('DbService').getDb()
* ```

View File

@@ -13,7 +13,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
// Mocks — must be declared before dynamic imports
// ─────────────────────────────────────────────────────────────────────────────
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory()
})

View File

@@ -1,8 +1,8 @@
import { application } from '@application'
import type { ProtoProviderConfig } from '@cherrystudio/provider-registry'
import { buildRuntimeEndpointConfigs, ENDPOINT_TYPE } from '@cherrystudio/provider-registry'
import { RegistryLoader } from '@cherrystudio/provider-registry/node'
import { userProviderTable } from '@data/db/schemas/userProvider'
import { application } from '@main/core/application'
import type { DbType, ISeeder } from '../../types'

View File

@@ -49,7 +49,7 @@ vi.mock('node:os', async (importOriginal) => {
return (await importOriginal()) as any
})
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
getPath: getPathMock
}

View File

@@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { MigrationContext } from '../../core/MigrationContext'
import { ProviderModelMigrator } from '../ProviderModelMigrator'
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory()
})

View File

@@ -1,8 +1,8 @@
import fs from 'node:fs'
import { pathToFileURL } from 'node:url'
import { application } from '@application'
import { type Client, createClient, type Value as LibsqlValue } from '@libsql/client'
import { application } from '@main/core/application'
import { sanitizeFilename } from '@main/utils/file'
const LEGACY_VECTOR_TABLE_NAME = 'vectors'

View File

@@ -23,7 +23,7 @@ const { setKnowledgeBaseRoot, getPathMock } = vi.hoisted(() => {
}
})
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
getPath: getPathMock
}

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type {
FileProcessorFeature,

View File

@@ -4,9 +4,9 @@
* Handles CRUD operations for knowledge bases stored in SQLite.
*/
import { application } from '@application'
import { knowledgeBaseTable } from '@data/db/schemas/knowledge'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { OffsetPaginationResponse } from '@shared/data/api/apiTypes'
import {

View File

@@ -4,9 +4,9 @@
* Handles CRUD operations for knowledge items stored in SQLite.
*/
import { application } from '@application'
import { knowledgeItemTable } from '@data/db/schemas/knowledge'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import type { OffsetPaginationResponse } from '@shared/data/api'
import { DataApiErrorFactory } from '@shared/data/api'
import type {

View File

@@ -6,9 +6,9 @@
* - Listing with optional filters (isActive, type)
*/
import { application } from '@application'
import { mcpServerTable } from '@data/db/schemas/mcpServer'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { CreateMCPServerDto, ListMCPServersQuery, UpdateMCPServerDto } from '@shared/data/api/schemas/mcpServers'
import type { MCPServer } from '@shared/data/types/mcpServer'

View File

@@ -8,10 +8,10 @@
* - Cascade delete and reparenting
*/
import { application } from '@application'
import { messageTable } from '@data/db/schemas/message'
import { topicTable } from '@data/db/schemas/topic'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type {
ActiveNodeStrategy,

View File

@@ -12,10 +12,10 @@
* definitions with DB preference rows to produce a unified MiniApp view.
*/
import { application } from '@application'
import { type MiniAppInsert, type MiniAppSelect } from '@data/db/schemas/miniapp'
import { type MiniAppStatus, miniappTable, type MiniAppType } from '@data/db/schemas/miniapp'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { OffsetPaginationResponse } from '@shared/data/api/apiTypes'
import type { CreateMiniappDto, UpdateMiniappDto } from '@shared/data/api/schemas/miniapps'

View File

@@ -7,11 +7,11 @@
* - Registry import support
*/
import { application } from '@application'
import type { ModelLookupResult } from '@cherrystudio/provider-registry'
import type { NewUserModel, UserModel } from '@data/db/schemas/userModel'
import { isRegistryEnrichableField, userModelTable } from '@data/db/schemas/userModel'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { CreateModelDto, ListModelsQuery, UpdateModelDto } from '@shared/data/api/schemas/models'
import type {

View File

@@ -10,12 +10,12 @@
* (RegistryLoader, buildRuntimeEndpointConfigs).
*/
import { application } from '@application'
import type { ProtoModelConfig, ProtoProviderModelOverride } from '@cherrystudio/provider-registry'
import type { EndpointType } from '@cherrystudio/provider-registry'
import { buildRuntimeEndpointConfigs } from '@cherrystudio/provider-registry'
import { RegistryLoader } from '@cherrystudio/provider-registry/node'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { ErrorCode, isDataApiError } from '@shared/data/api/apiErrors'
import type { Model } from '@shared/data/types/model'
import type { EndpointConfig, ReasoningFormatType } from '@shared/data/types/provider'

View File

@@ -6,10 +6,10 @@
* - Row to Provider conversion
*/
import { application } from '@application'
import type { NewUserProvider, UserProvider } from '@data/db/schemas/userProvider'
import { userProviderTable } from '@data/db/schemas/userProvider'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { CreateProviderDto, ListProvidersQuery, UpdateProviderDto } from '@shared/data/api/schemas/providers'
import type {

View File

@@ -7,10 +7,10 @@
* - Active node switching
*/
import { application } from '@application'
import { messageTable } from '@data/db/schemas/message'
import { topicTable } from '@data/db/schemas/topic'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { CreateTopicDto, UpdateTopicDto } from '@shared/data/api/schemas/topics'
import type { Topic } from '@shared/data/types/topic'

View File

@@ -2,9 +2,9 @@
* Translate History Service - handles translate history CRUD
*/
import { application } from '@application'
import { translateHistoryTable } from '@data/db/schemas/translateHistory'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { OffsetPaginationResponse } from '@shared/data/api/apiTypes'
import type {

View File

@@ -4,9 +4,9 @@
* langCode is the primary key (immutable after creation).
*/
import { application } from '@application'
import { translateLanguageTable } from '@data/db/schemas/translateLanguage'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { DataApiErrorFactory } from '@shared/data/api'
import type { CreateTranslateLanguageDto, UpdateTranslateLanguageDto } from '@shared/data/api/schemas/translate'
import type { TranslateLanguage } from '@shared/data/types/translate'

View File

@@ -7,7 +7,7 @@ const mockInsert = vi.fn()
const mockUpdate = vi.fn()
const mockDelete = vi.fn()
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn(() => ({
getDb: vi.fn(() => ({

View File

@@ -27,7 +27,7 @@ const mockDb = {
let realDb: DbType | null = null
let closeClient: (() => void) | undefined
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn(() => ({
getDb: vi.fn(() => realDb ?? mockDb)

View File

@@ -72,7 +72,7 @@ function mockChain(resolvedValue: unknown) {
let mockDb: any
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory({
DbService: { getDb: () => mockDb }

View File

@@ -9,7 +9,7 @@ const mockUpdate = vi.fn()
const mockDelete = vi.fn()
const mockTransaction = vi.fn()
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn(() => ({
getDb: vi.fn(() => ({

View File

@@ -82,7 +82,7 @@ function createCapturingMockDb(selectResults: unknown[][] = [[]]) {
// Mocks
// ─────────────────────────────────────────────────────────────────────────────
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory()
})

View File

@@ -30,7 +30,7 @@ function createChainableMockDb() {
// Mocks
// ─────────────────────────────────────────────────────────────────────────────
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory()
})

View File

@@ -46,7 +46,7 @@ function createMockDbForProvider(providerRow: unknown) {
// Mocks
// ─────────────────────────────────────────────────────────────────────────────
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory()
})

View File

@@ -22,7 +22,7 @@ const mockDb = {
transaction: vi.fn(async (fn: (tx: typeof mockTx) => Promise<unknown>) => fn(mockTx))
}
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory({
DbService: { getDb: () => mockDb }

View File

@@ -22,7 +22,7 @@ const mockDb = {
transaction: vi.fn(async (fn: (tx: typeof mockTx) => Promise<unknown>) => fn(mockTx))
}
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
return mockApplicationFactory({
DbService: { getDb: () => mockDb }

View File

@@ -16,6 +16,7 @@
import '@main/data/bootConfig'
import { application, serviceList } from '@application'
// Preboot (sync pre-bootstrap setup). Order matters — each module's JSDoc
// documents its own timing contract. See core/preboot/README.md.
import { configureChromiumFlags } from '@main/core/preboot/chromiumFlags'
@@ -24,8 +25,6 @@ import { requireSingleInstance } from '@main/core/preboot/singleInstance'
import { resolveUserDataLocation } from '@main/core/preboot/userDataLocation'
import { runV2MigrationGate } from '@main/core/preboot/v2MigrationGate'
import { application, serviceList } from './core/application'
requireSingleInstance()
resolveUserDataLocation()
configureChromiumFlags()

View File

@@ -2,9 +2,9 @@ import fs from 'node:fs'
import { arch } from 'node:os'
import path from 'node:path'
import { application } from '@application'
import { loggerService } from '@logger'
import { isMac, isWin } from '@main/constant'
import { application } from '@main/core/application'
import { generateSignature } from '@main/integration/cherryai'
import { anthropicService } from '@main/services/AnthropicService'
import { getIpCountry } from '@main/utils/ipService'

View File

@@ -1,8 +1,8 @@
import { application } from '@application'
import { BaseLoader } from '@cherrystudio/embedjs-interfaces'
import { cleanString } from '@cherrystudio/embedjs-utils'
import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import EPub from 'epub'
import * as fs from 'fs'
import path from 'path'

View File

@@ -1,7 +1,7 @@
import fs from 'node:fs'
import path from 'node:path'
import { application } from '@main/core/application'
import { application } from '@application'
import { getFileExt } from '@main/utils/file'
import type { FileMetadata, PreprocessProvider, PreprocessReadPdfResult } from '@types'
import { PDFDocument } from 'pdf-lib'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import PreprocessProvider from '@main/knowledge/preprocess/PreprocessProvider'
import type { FileMetadata, KnowledgeBaseParams, KnowledgeItem } from '@types'

View File

@@ -2,8 +2,8 @@ import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import type { Tool } from '@modelcontextprotocol/sdk/types.js'
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError } from '@modelcontextprotocol/sdk/types.js'
@@ -538,7 +538,7 @@ class AssistantServer {
const defaultModel = configManager.get<Record<string, unknown>>('defaultModel', {})
const topicNamingModel = configManager.get<Record<string, unknown>>('topicNamingModel', {})
const { application } = await import('@main/core/application')
const { application } = await import('@application')
const preferenceService = application.get('PreferenceService')
const settings = {

View File

@@ -1,4 +1,4 @@
import { application } from '@main/core/application'
import { application } from '@application'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
import fs from 'fs/promises'

View File

@@ -83,7 +83,7 @@ const mockCacheService = {
delete: vi.fn((key: string) => cacheStore.delete(key))
}
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn((name: string) => {
if (name === 'MCPService') {

View File

@@ -7,7 +7,7 @@ const mockMCPService = {
abortTool: vi.fn(async () => true)
}
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn((name: string) => {
if (name === 'MCPService') {

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError } from '@modelcontextprotocol/sdk/types.js'
import type { MCPTool } from '@types'

View File

@@ -1,7 +1,7 @@
/**
* Bridge module for Hub server to access MCPService.
*/
import { application } from '@main/core/application'
import { application } from '@application'
import type { MCPCallToolResponse, MCPTool, MCPToolResultContent } from '@types'
import { buildToolNameMapping, resolveToolId, type ToolIdentity, type ToolNameMapping } from './toolname'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { TraceMethod } from '@mcp-trace/trace-core'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError } from '@modelcontextprotocol/sdk/types.js'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError } from '@modelcontextprotocol/sdk/types.js'

View File

@@ -1,7 +1,7 @@
import { application } from '@application'
import type { TokenUsageData } from '@cherrystudio/analytics-client'
import { AnalyticsClient } from '@cherrystudio/analytics-client'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { type Activatable, BaseService, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { generateUserAgent, getClientId } from '@main/utils/systemInfo'
import { APP_NAME } from '@shared/config/constant'

View File

@@ -3,8 +3,8 @@
* This code is adapted from https://github.com/ThinkInAIXYZ/deepchat
* Original file: src/main/presenter/anthropicOAuth.ts
*/
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import * as crypto from 'crypto'
import { net, shell } from 'electron'
import { promises } from 'fs'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { type Activatable, BaseService, DependsOn, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { IpcChannel } from '@shared/IpcChannel'
import type {

View File

@@ -1,4 +1,4 @@
import { application } from '@main/core/application'
import { application } from '@application'
import { BaseService, Conditional, Injectable, onPlatform, Phase, ServicePhase } from '@main/core/lifecycle'
import { getAppLanguage, locales } from '@main/utils/language'
import { IpcChannel } from '@shared/IpcChannel'

View File

@@ -1,6 +1,6 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { isDev, isLinux, isMac, isWin } from '@main/constant'
import { application } from '@main/core/application'
import { app } from 'electron'
import fs from 'fs'
import os from 'os'

View File

@@ -1,6 +1,6 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { isWin } from '@main/constant'
import { application } from '@main/core/application'
import { BaseService, DependsOn, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { getIpCountry } from '@main/utils/ipService'
import { generateUserAgent, getClientId } from '@main/utils/systemInfo'

View File

@@ -14,9 +14,9 @@
* - v2 Refactor PR : https://github.com/CherryHQ/cherry-studio/pull/10162
* --------------------------------------------------------------------------
*/
import { application } from '@application'
import { loggerService } from '@logger'
import { isWin } from '@main/constant'
import { application } from '@main/core/application'
import { IpcChannel } from '@shared/IpcChannel'
import type { WebDavConfig } from '@types'
import type { S3Config } from '@types'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { net, safeStorage } from 'electron'
import fs from 'fs'
import path from 'path'

View File

@@ -1,8 +1,8 @@
import { application } from '@application'
import { is } from '@electron-toolkit/utils'
import { loggerService } from '@logger'
import { titleBarOverlayDark, titleBarOverlayLight } from '@main/config'
import { isLinux, isMac, isWin } from '@main/constant'
import { application } from '@main/core/application'
import { BaseService, DependsOn, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { IpcChannel } from '@shared/IpcChannel'
import { BrowserWindow, nativeTheme, shell } from 'electron'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import * as fs from 'fs'
import StreamZip from 'node-stream-zip'
import * as os from 'os'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { toAsarUnpackedPath } from '@main/utils'
import {
checkName,

View File

@@ -16,13 +16,13 @@
import * as fs from 'node:fs'
import path from 'node:path'
import { application } from '@application'
import type { RAGApplication } from '@cherrystudio/embedjs'
import { RAGApplicationBuilder } from '@cherrystudio/embedjs'
import { LibSqlDb } from '@cherrystudio/embedjs-libsql'
import { SitemapLoader } from '@cherrystudio/embedjs-loader-sitemap'
import { WebLoader } from '@cherrystudio/embedjs-loader-web'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import Embeddings from '@main/knowledge/embedjs/embeddings/Embeddings'
import { addFileLoader } from '@main/knowledge/embedjs/loader'
import { NoteLoader } from '@main/knowledge/embedjs/loader/noteLoader'

View File

@@ -2,9 +2,9 @@ import crypto from 'node:crypto'
import os from 'node:os'
import path from 'node:path'
import { application } from '@application'
import { mcpServerService } from '@data/services/McpServerService'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { BaseService, DependsOn, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { createInMemoryMCPServer } from '@main/mcpServers/factory'
import { makeSureDirExists, removeEnvProxy } from '@main/utils'

View File

@@ -1,6 +1,6 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { isDev } from '@main/constant'
import { application } from '@main/core/application'
import {
type Activatable,
BaseService,

View File

@@ -1,4 +1,4 @@
import { application } from '@main/core/application'
import { application } from '@application'
import type { Notification } from '@types'
import { Notification as ElectronNotification } from 'electron'

View File

@@ -5,9 +5,9 @@ import { Socket } from 'node:net'
import os from 'node:os'
import path from 'node:path'
import { application } from '@application'
import { loggerService } from '@logger'
import { isWin } from '@main/constant'
import { application } from '@main/core/application'
import { BaseService, DependsOn, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { isUserInChina } from '@main/utils/ipService'
import { crossPlatformSpawn, findExecutableInEnv, getBinaryPath, runInstallScript } from '@main/utils/process'

View File

@@ -2,8 +2,8 @@ import { exec } from 'node:child_process'
import fs from 'node:fs/promises'
import { promisify } from 'node:util'
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { BaseService, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { app } from 'electron'

View File

@@ -1,6 +1,6 @@
import { randomUUID } from 'node:crypto'
import { application } from '@main/core/application'
import { application } from '@application'
import { BaseService, DependsOn, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { IpcChannel } from '@shared/IpcChannel'

View File

@@ -14,8 +14,8 @@
* - v2 Refactor PR : https://github.com/CherryHQ/cherry-studio/pull/10162
* --------------------------------------------------------------------------
*/
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { IpcChannel } from '@shared/IpcChannel'
import { ipcMain } from 'electron'

View File

@@ -1,7 +1,7 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { SELECTION_FINETUNED_LIST, SELECTION_PREDEFINED_BLACKLIST } from '@main/configs/SelectionConfig'
import { isDev, isLinux, isMac, isWin } from '@main/constant'
import { application } from '@main/core/application'
import { type Activatable, BaseService, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import type { SelectionActionItem } from '@shared/data/preference/preferenceTypes'
import { SelectionTriggerMode } from '@shared/data/preference/preferenceTypes'

View File

@@ -14,8 +14,8 @@
* - v2 Refactor PR : https://github.com/CherryHQ/cherry-studio/pull/10162
* --------------------------------------------------------------------------
*/
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { BaseService, DependsOn, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { handleZoomFactor } from '@main/utils/zoom'
import { IpcChannel } from '@shared/IpcChannel'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { type Activatable, BaseService, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { convertSpanToSpanEntity } from '@mcp-trace/trace-core/core/spanConvert'
import type { TraceCache } from '@mcp-trace/trace-core/core/traceCache'

View File

@@ -1,4 +1,4 @@
import { application } from '@main/core/application'
import { application } from '@application'
import { BaseService, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { ThemeMode } from '@shared/data/preference/preferenceTypes'
import { IpcChannel } from '@shared/IpcChannel'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { isLinux, isMac, isWin } from '@main/constant'
import { application } from '@main/core/application'
import { type Activatable, BaseService, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { getI18n } from '@main/utils/language'
import type { MenuItemConstructorOptions } from 'electron'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { app } from 'electron'
import fs from 'fs'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import { BaseService, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { getAppLanguage, t } from '@main/utils/language'
import { IpcChannel } from '@shared/IpcChannel'

View File

@@ -1,7 +1,7 @@
import { application } from '@application'
import { is } from '@electron-toolkit/utils'
import { loggerService } from '@logger'
import { isDev, isLinux, isMac, isWin } from '@main/constant'
import { application } from '@main/core/application'
import { BaseService, Emitter, type Event, Injectable, Phase, ServicePhase } from '@main/core/lifecycle'
import { getWindowsBackgroundMaterial, replaceDevtoolsFont } from '@main/utils/windowUtil'
import { MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH } from '@shared/config/constant'

View File

@@ -19,7 +19,7 @@ vi.mock('@data/PreferenceService', async () => {
})
// Mock application using unified factory
vi.mock('@main/core/application', async () => {
vi.mock('@application', async () => {
const { mockApplicationFactory } = await import('@test-mocks/main/application')
const result = mockApplicationFactory()
const originalGet = result.application.get.getMockImplementation()!
@@ -101,7 +101,7 @@ vi.mock('electron-updater', () => ({
}))
// Import after mocks
import { application } from '@main/core/application'
import { application } from '@application'
import { UpdateMirror } from '@shared/config/constant'
import { MockMainPreferenceServiceUtils } from '@test-mocks/main/PreferenceService'
import { app, net } from 'electron'

View File

@@ -87,7 +87,7 @@ vi.mock('fs-extra', () => ({
createReadStream: vi.fn()
}))
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn((name: string) => {
if (name === 'WindowService') {

View File

@@ -8,7 +8,7 @@ vi.mock('@data/services/McpServerService', () => ({
}
}))
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn((name: string) => {
if (name === 'WindowService') {

View File

@@ -15,7 +15,7 @@ vi.mock('@main/core/lifecycle', () => {
}
})
vi.mock('@main/core/application', () => ({
vi.mock('@application', () => ({
application: {
get: vi.fn((name: string) => {
if (name === 'WindowService') {

View File

@@ -1,7 +1,7 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { getMcpApiService } from '@main/apiServer/services/mcp'
import { type ModelValidationError, validateModelId } from '@main/apiServer/utils'
import { application } from '@main/core/application'
import { buildFunctionCallToolName } from '@shared/mcp'
import type { AgentType, SlashCommand, SystemProviderId, Tool } from '@types'
import { objectKeys } from '@types'

View File

@@ -8,8 +8,8 @@
* The Claude Agent SDK auto-discovers skills from .claude/skills/ and
* plugins from .claude/plugins.json, so no programmatic injection is needed.
*/
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import fs from 'fs'
import path from 'path'

View File

@@ -1,5 +1,5 @@
import { application } from '@application'
import { loggerService } from '@logger'
import { application } from '@main/core/application'
import type { ChannelLogEntry, ChannelStatusEvent } from '@shared/config/types'
import { IpcChannel } from '@shared/IpcChannel'

View File

@@ -1,8 +1,8 @@
import { Readable } from 'node:stream'
import type { ReadableStream as NodeReadableStream } from 'node:stream/web'
import { application } from '@application'
import * as Lark from '@larksuiteoapi/node-sdk'
import { application } from '@main/core/application'
import type { FeishuDomain } from '@main/services/agents/database/schema'
import { IpcChannel } from '@shared/IpcChannel'

View File

@@ -1,4 +1,4 @@
import { application } from '@main/core/application'
import { application } from '@application'
import { IpcChannel } from '@shared/IpcChannel'
import { parseDataUrl } from '@shared/utils'

Some files were not shown because too many files have changed in this diff Show More