mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-19 13:44:48 +00:00
packages/cli/src/utils is the directory every other directory imports (83 from ui, 30 from the package root, 23 from config), so it only works as a leaf. It currently imports back into six siblings, which is what makes the package's directory graph cyclic. Three moves, each decided by who actually consumes the module: - serve/fast-path-argv.ts moves down into utils/. It is 25 lines with no imports, doing pure argv string manipulation, consumed from three layers. A utility filed under the daemon; relocate the target rather than rework the caller. Renamed serve-fast-path-argv.ts since fast-path-argv is ambiguous among general helpers. - utils/windowTitle.ts moves up into ui/utils/. Its only consumers are AppContainer and startInteractiveUI, and it imports StreamingState, ICON and the OSC-8 helper. - utils/systemInfo.ts imports formatMemoryUsage from core directly instead of through ui/utils/formatters.ts, a one-line re-export of the same symbol. It cannot move into ui/ because the daemon status provider consumes it, so the import is inverted instead. Adds a no-restricted-imports rule for utils/** rejecting serve/. Scoped to serve/ only: that direction is now completely clean, so the rule states something true. The remaining ui/, config/, i18n/ and nonInteractive/ edges are tracked in #9146. Runtime upward imports out of cli/src/utils: 25 -> 20; utils -> serve 1 -> 0, eliminating that cycle; utils -> ui 7 -> 3.
This commit is contained in:
parent
4257916e7e
commit
a29c8b11db
11 changed files with 34 additions and 13 deletions
|
|
@ -72,6 +72,27 @@ export default tseslint.config(
|
|||
'import/namespace': 'off', // Disabled due to https://github.com/import-js/eslint-plugin-import/issues/2866
|
||||
},
|
||||
},
|
||||
{
|
||||
// `utils/` is the layer every other directory imports, so it must not
|
||||
// import back into one. The daemon direction is clean and enforced here;
|
||||
// the remaining `ui/`, `config/`, `i18n/` and `nonInteractive/` edges are
|
||||
// tracked in #9146 and will be added to this group as they are resolved.
|
||||
files: ['packages/cli/src/utils/**/*.{ts,tsx}'],
|
||||
rules: {
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
patterns: [
|
||||
{
|
||||
group: ['**/serve/*', '**/serve/**'],
|
||||
message:
|
||||
'packages/cli/src/utils must not import serve/. Move lifecycle-free logic down into utils/ instead (#9146).',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
// General overrides and rules for the project (TS/TSX files)
|
||||
files: [
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from 'node:fs';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import type { ArgumentsCamelCase, Argv, Options } from 'yargs';
|
||||
import { normalizeServeFastPathArgv } from './serve/fast-path-argv.js';
|
||||
import { normalizeServeFastPathArgv } from './utils/serve-fast-path-argv.js';
|
||||
import { initStartupProfiler } from './utils/startupProfiler.js';
|
||||
import { initCpuProfiler } from './utils/cpuProfiler.js';
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
isValidMemoryBudgetMb,
|
||||
memoryBudgetRangeError,
|
||||
} from '@qwen-code/acp-bridge/daemonMemoryBudget';
|
||||
import { normalizeServeFastPathArgv } from './fast-path-argv.js';
|
||||
import { normalizeServeFastPathArgv } from '../utils/serve-fast-path-argv.js';
|
||||
import type { ServeFastPathSettings } from './fast-path-settings.js';
|
||||
import { RUNTIME_STARTUP_CANCELLED_MESSAGE } from './runtime-startup-errors.js';
|
||||
import type { ServeOptions } from './types.js';
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ vi.mock('./utils/terminal-resize-reflow.js', () => ({
|
|||
buildWakeRepaint: buildWakeRepaintSpy,
|
||||
}));
|
||||
|
||||
vi.mock('../utils/windowTitle.js', async (importOriginal) => {
|
||||
vi.mock('./utils/windowTitle.js', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('../utils/windowTitle.js')>();
|
||||
await importOriginal<typeof import('./utils/windowTitle.js')>();
|
||||
return {
|
||||
...actual,
|
||||
writeTerminalTitle: (
|
||||
|
|
@ -62,7 +62,7 @@ import {
|
|||
import {
|
||||
formatSessionWindowTitle,
|
||||
writeTerminalTitle,
|
||||
} from '../utils/windowTitle.js';
|
||||
} from './utils/windowTitle.js';
|
||||
import ansiEscapes from 'ansi-escapes';
|
||||
import {
|
||||
type Config,
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ import {
|
|||
formatSessionWindowTitle,
|
||||
titleStatusPrefix,
|
||||
writeTerminalTitle,
|
||||
} from '../utils/windowTitle.js';
|
||||
} from './utils/windowTitle.js';
|
||||
import { clearScreen } from '../utils/stdioHelpers.js';
|
||||
import { useTextBuffer } from './components/shared/text-buffer.js';
|
||||
import { useLogger } from './hooks/useLogger.js';
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ import { startPostRenderPrefetches } from '../startup/startup-prefetch.js';
|
|||
import {
|
||||
computeWindowTitle,
|
||||
writeTerminalTitle,
|
||||
} from '../utils/windowTitle.js';
|
||||
} from './utils/windowTitle.js';
|
||||
import { getCliVersion } from '../utils/version.js';
|
||||
|
||||
const debugLogger = createDebugLogger('STARTUP');
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { StreamingState } from '../ui/types.js';
|
||||
import { StreamingState } from '../types.js';
|
||||
import {
|
||||
computeWindowTitle,
|
||||
writeTerminalTitle,
|
||||
|
|
@ -4,9 +4,9 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { sanitizeForOsc } from '../ui/utils/osc8.js';
|
||||
import { ICON } from '../ui/constants.js';
|
||||
import { StreamingState } from '../ui/types.js';
|
||||
import { sanitizeForOsc } from './osc8.js';
|
||||
import { ICON } from '../constants.js';
|
||||
import { StreamingState } from '../types.js';
|
||||
|
||||
export const DEFAULT_WINDOW_TITLE = 'qwen';
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ import * as path from 'node:path';
|
|||
import { performance } from 'node:perf_hooks';
|
||||
|
||||
import type { StartupEventAttrs } from '@qwen-code/qwen-code-core';
|
||||
import { isServeFastPathArgv } from '../serve/fast-path-argv.js';
|
||||
import { isServeFastPathArgv } from './serve-fast-path-argv.js';
|
||||
|
||||
interface Checkpoint {
|
||||
name: string;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ import {
|
|||
IdeClient,
|
||||
AuthType,
|
||||
createDebugLogger,
|
||||
formatMemoryUsage,
|
||||
type LspStatusSnapshot,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import { formatMemoryUsage } from '../ui/utils/formatters.js';
|
||||
import { GIT_COMMIT_INFO } from '../generated/git-commit.js';
|
||||
|
||||
const debugLogger = createDebugLogger('STATUS');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue