feat(01-01): refactor SubagentDetailBuilder to use FileSystemProvider
- Remove dynamic fs/promises, os, and path imports from SubagentDetailBuilder - Add fsProvider and projectsDir parameters to buildSubagentDetail function - Replace fs.access() with fsProvider.exists() for file existence check - Replace os.homedir() path construction with projectsDir parameter - Update ChunkBuilder.buildSubagentDetail() to accept and pass new parameters - Update IPC subagents handler to obtain provider and projectsDir from ProjectScanner - Update initializeSubagentHandlers to accept ProjectScanner parameter - Update handlers.ts to pass ProjectScanner to subagent handler initialization Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a3f5dafdab
commit
c12b3295e9
4 changed files with 41 additions and 17 deletions
|
|
@ -72,7 +72,7 @@ export function initializeIpcHandlers(
|
||||||
initializeProjectHandlers(scanner);
|
initializeProjectHandlers(scanner);
|
||||||
initializeSessionHandlers(scanner, parser, resolver, builder, cache);
|
initializeSessionHandlers(scanner, parser, resolver, builder, cache);
|
||||||
initializeSearchHandlers(scanner);
|
initializeSearchHandlers(scanner);
|
||||||
initializeSubagentHandlers(builder, cache, parser, resolver);
|
initializeSubagentHandlers(builder, cache, parser, resolver, scanner);
|
||||||
initializeUpdaterHandlers(updater);
|
initializeUpdaterHandlers(updater);
|
||||||
if (sshManager && sshModeSwitchCallback) {
|
if (sshManager && sshModeSwitchCallback) {
|
||||||
initializeSshHandlers(sshManager, sshModeSwitchCallback);
|
initializeSshHandlers(sshManager, sshModeSwitchCallback);
|
||||||
|
|
@ -110,7 +110,7 @@ export function reinitializeServiceHandlers(
|
||||||
initializeProjectHandlers(scanner);
|
initializeProjectHandlers(scanner);
|
||||||
initializeSessionHandlers(scanner, parser, resolver, builder, cache);
|
initializeSessionHandlers(scanner, parser, resolver, builder, cache);
|
||||||
initializeSearchHandlers(scanner);
|
initializeSearchHandlers(scanner);
|
||||||
initializeSubagentHandlers(builder, cache, parser, resolver);
|
initializeSubagentHandlers(builder, cache, parser, resolver, scanner);
|
||||||
logger.info('Service handlers re-initialized after mode switch');
|
logger.info('Service handlers re-initialized after mode switch');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,13 @@ import { type SubagentDetail } from '../types';
|
||||||
|
|
||||||
import { validateProjectId, validateSessionId, validateSubagentId } from './guards';
|
import { validateProjectId, validateSessionId, validateSubagentId } from './guards';
|
||||||
|
|
||||||
import type { ChunkBuilder, DataCache, SessionParser, SubagentResolver } from '../services';
|
import type {
|
||||||
|
ChunkBuilder,
|
||||||
|
DataCache,
|
||||||
|
ProjectScanner,
|
||||||
|
SessionParser,
|
||||||
|
SubagentResolver,
|
||||||
|
} from '../services';
|
||||||
|
|
||||||
const logger = createLogger('IPC:subagents');
|
const logger = createLogger('IPC:subagents');
|
||||||
|
|
||||||
|
|
@ -21,6 +27,7 @@ let chunkBuilder: ChunkBuilder;
|
||||||
let dataCache: DataCache;
|
let dataCache: DataCache;
|
||||||
let sessionParser: SessionParser;
|
let sessionParser: SessionParser;
|
||||||
let subagentResolver: SubagentResolver;
|
let subagentResolver: SubagentResolver;
|
||||||
|
let projectScanner: ProjectScanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes subagent handlers with service instances.
|
* Initializes subagent handlers with service instances.
|
||||||
|
|
@ -29,12 +36,14 @@ export function initializeSubagentHandlers(
|
||||||
builder: ChunkBuilder,
|
builder: ChunkBuilder,
|
||||||
cache: DataCache,
|
cache: DataCache,
|
||||||
parser: SessionParser,
|
parser: SessionParser,
|
||||||
resolver: SubagentResolver
|
resolver: SubagentResolver,
|
||||||
|
scanner: ProjectScanner
|
||||||
): void {
|
): void {
|
||||||
chunkBuilder = builder;
|
chunkBuilder = builder;
|
||||||
dataCache = cache;
|
dataCache = cache;
|
||||||
sessionParser = parser;
|
sessionParser = parser;
|
||||||
subagentResolver = resolver;
|
subagentResolver = resolver;
|
||||||
|
projectScanner = scanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -97,13 +106,19 @@ async function handleGetSubagentDetail(
|
||||||
return subagentDetail;
|
return subagentDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get provider and projectsDir from projectScanner
|
||||||
|
const fsProvider = projectScanner.getFileSystemProvider();
|
||||||
|
const projectsDir = projectScanner.getProjectsDir();
|
||||||
|
|
||||||
// Build subagent detail
|
// Build subagent detail
|
||||||
const builtDetail = await chunkBuilder.buildSubagentDetail(
|
const builtDetail = await chunkBuilder.buildSubagentDetail(
|
||||||
safeProjectId,
|
safeProjectId,
|
||||||
safeSessionId,
|
safeSessionId,
|
||||||
safeSubagentId,
|
safeSubagentId,
|
||||||
sessionParser,
|
sessionParser,
|
||||||
subagentResolver
|
subagentResolver,
|
||||||
|
fsProvider,
|
||||||
|
projectsDir
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!builtDetail) {
|
if (!builtDetail) {
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ import { buildGroups as buildConversationGroups } from './ConversationGroupBuild
|
||||||
import { buildSubagentDetail as buildSubagentDetailFn } from './SubagentDetailBuilder';
|
import { buildSubagentDetail as buildSubagentDetailFn } from './SubagentDetailBuilder';
|
||||||
|
|
||||||
import type { SubagentResolver } from '../discovery/SubagentResolver';
|
import type { SubagentResolver } from '../discovery/SubagentResolver';
|
||||||
|
import type { FileSystemProvider } from '../infrastructure/FileSystemProvider';
|
||||||
import type { SessionParser } from '../parsing/SessionParser';
|
import type { SessionParser } from '../parsing/SessionParser';
|
||||||
|
|
||||||
export class ChunkBuilder {
|
export class ChunkBuilder {
|
||||||
|
|
@ -428,7 +429,9 @@ export class ChunkBuilder {
|
||||||
sessionId: string,
|
sessionId: string,
|
||||||
subagentId: string,
|
subagentId: string,
|
||||||
sessionParser: SessionParser,
|
sessionParser: SessionParser,
|
||||||
subagentResolver: SubagentResolver
|
subagentResolver: SubagentResolver,
|
||||||
|
fsProvider: FileSystemProvider,
|
||||||
|
projectsDir: string
|
||||||
): Promise<SubagentDetail | null> {
|
): Promise<SubagentDetail | null> {
|
||||||
// Delegate to the extracted module, passing buildChunks as a callback
|
// Delegate to the extracted module, passing buildChunks as a callback
|
||||||
return buildSubagentDetailFn(
|
return buildSubagentDetailFn(
|
||||||
|
|
@ -437,7 +440,9 @@ export class ChunkBuilder {
|
||||||
subagentId,
|
subagentId,
|
||||||
sessionParser,
|
sessionParser,
|
||||||
subagentResolver,
|
subagentResolver,
|
||||||
(messages, subagents) => this.buildChunks(messages, subagents)
|
(messages, subagents) => this.buildChunks(messages, subagents),
|
||||||
|
fsProvider,
|
||||||
|
projectsDir
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,14 @@ import {
|
||||||
} from '@main/types';
|
} from '@main/types';
|
||||||
import { countTokens } from '@main/utils/tokenizer';
|
import { countTokens } from '@main/utils/tokenizer';
|
||||||
import { createLogger } from '@shared/utils/logger';
|
import { createLogger } from '@shared/utils/logger';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
const logger = createLogger('Service:SubagentDetailBuilder');
|
const logger = createLogger('Service:SubagentDetailBuilder');
|
||||||
|
|
||||||
import { buildSemanticStepGroups } from './SemanticStepGrouper';
|
import { buildSemanticStepGroups } from './SemanticStepGrouper';
|
||||||
|
|
||||||
import type { SubagentResolver } from '../discovery/SubagentResolver';
|
import type { SubagentResolver } from '../discovery/SubagentResolver';
|
||||||
|
import type { FileSystemProvider } from '../infrastructure/FileSystemProvider';
|
||||||
import type { SessionParser } from '../parsing/SessionParser';
|
import type { SessionParser } from '../parsing/SessionParser';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,6 +36,8 @@ import type { SessionParser } from '../parsing/SessionParser';
|
||||||
* @param sessionParser - SessionParser instance for parsing subagent file
|
* @param sessionParser - SessionParser instance for parsing subagent file
|
||||||
* @param subagentResolver - SubagentResolver instance for nested subagents
|
* @param subagentResolver - SubagentResolver instance for nested subagents
|
||||||
* @param buildChunksFn - Function to build chunks from messages and subagents
|
* @param buildChunksFn - Function to build chunks from messages and subagents
|
||||||
|
* @param fsProvider - FileSystemProvider for file existence checks
|
||||||
|
* @param projectsDir - Projects directory path
|
||||||
* @returns SubagentDetail or null if not found
|
* @returns SubagentDetail or null if not found
|
||||||
*/
|
*/
|
||||||
export async function buildSubagentDetail(
|
export async function buildSubagentDetail(
|
||||||
|
|
@ -42,21 +46,21 @@ export async function buildSubagentDetail(
|
||||||
subagentId: string,
|
subagentId: string,
|
||||||
sessionParser: SessionParser,
|
sessionParser: SessionParser,
|
||||||
subagentResolver: SubagentResolver,
|
subagentResolver: SubagentResolver,
|
||||||
buildChunksFn: (messages: ParsedMessage[], subagents: Process[]) => EnhancedChunk[]
|
buildChunksFn: (messages: ParsedMessage[], subagents: Process[]) => EnhancedChunk[],
|
||||||
|
fsProvider: FileSystemProvider,
|
||||||
|
projectsDir: string
|
||||||
): Promise<SubagentDetail | null> {
|
): Promise<SubagentDetail | null> {
|
||||||
try {
|
try {
|
||||||
const fs = await import('fs/promises');
|
|
||||||
const path = await import('path');
|
|
||||||
const os = await import('os');
|
|
||||||
|
|
||||||
// Construct path to subagent JSONL file
|
// Construct path to subagent JSONL file
|
||||||
const claudeDir = path.join(os.homedir(), '.claude', 'projects');
|
const subagentPath = path.join(
|
||||||
const subagentPath = path.join(claudeDir, projectId, 'subagents', `agent-${subagentId}.jsonl`);
|
projectsDir,
|
||||||
|
projectId,
|
||||||
|
'subagents',
|
||||||
|
`agent-${subagentId}.jsonl`
|
||||||
|
);
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
try {
|
if (!(await fsProvider.exists(subagentPath))) {
|
||||||
await fs.access(subagentPath);
|
|
||||||
} catch {
|
|
||||||
logger.warn(`Subagent file not found: ${subagentPath}`);
|
logger.warn(`Subagent file not found: ${subagentPath}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue