docs(02-02): complete registry integration plan
- Created 02-02-SUMMARY.md with implementation details - Updated STATE.md: Plan 2 of 3 complete, 50% progress - Added decisions: onContextSwitched callback, SSH context ID format - Updated metrics: 3 plans completed, 5 min average - No deviations from plan
This commit is contained in:
parent
24051acac8
commit
d10c56adb7
2 changed files with 273 additions and 12 deletions
|
|
@ -10,29 +10,29 @@ See: .planning/PROJECT.md (updated 2026-02-12)
|
|||
## Current Position
|
||||
|
||||
Phase: 2 of 4 (Service Infrastructure)
|
||||
Plan: 1 of 3
|
||||
Status: Plan 02-01 complete
|
||||
Last activity: 2026-02-12 - Completed 02-01 (ServiceContext infrastructure)
|
||||
Plan: 2 of 3
|
||||
Status: Plan 02-02 complete
|
||||
Last activity: 2026-02-12 - Completed 02-02 (Registry integration)
|
||||
|
||||
Progress: [███░░░░░░░] 37.5% (1.5/4 phases)
|
||||
Progress: [████░░░░░░] 50.0% (2.0/4 phases)
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
**Velocity:**
|
||||
- Total plans completed: 2
|
||||
- Average duration: 4 min
|
||||
- Total execution time: 0.13 hours
|
||||
- Total plans completed: 3
|
||||
- Average duration: 5 min
|
||||
- Total execution time: 0.23 hours
|
||||
|
||||
**By Phase:**
|
||||
|
||||
| Phase | Plans | Total | Avg/Plan |
|
||||
|-------|-------|-------|----------|
|
||||
| 01 Provider Plumbing | 1 | 4 min | 4 min |
|
||||
| 02 Service Infrastructure | 1 | 4 min | 4 min |
|
||||
| 02 Service Infrastructure | 2 | 10 min | 5 min |
|
||||
|
||||
**Recent Trend:**
|
||||
- Last 5 plans: 4, 4
|
||||
- Trend: Consistent velocity
|
||||
- Last 5 plans: 4, 4, 6
|
||||
- Trend: Slight increase (registry integration more complex)
|
||||
|
||||
*Updated after each plan completion*
|
||||
|
||||
|
|
@ -53,6 +53,10 @@ Recent decisions affecting current work:
|
|||
- ServiceContext bundles all session-data services for single workspace isolation (02-01)
|
||||
- dispose() separate from stop() - stop pauses (reversible), dispose destroys (permanent) (02-01)
|
||||
- removeAllListeners() called LAST in dispose() to prevent events during cleanup (02-01)
|
||||
- File watcher event rewiring via exported onContextSwitched callback from index.ts (02-02)
|
||||
- SSH handler dynamically imports onContextSwitched to avoid circular dependencies (02-02)
|
||||
- Context ID for SSH uses simple format: ssh-{host} (02-02)
|
||||
- Destroy existing SSH context on reconnection to same host (02-02)
|
||||
|
||||
### Pending Todos
|
||||
|
||||
|
|
@ -78,9 +82,9 @@ None yet.
|
|||
## Session Continuity
|
||||
|
||||
Last session: 2026-02-12
|
||||
Stopped at: Completed 02-01 (ServiceContext and ServiceContextRegistry) — ready for 02-02
|
||||
Stopped at: Completed 02-02 (Registry integration) — ready for 02-03
|
||||
Resume file: None
|
||||
|
||||
---
|
||||
*Created: 2026-02-12*
|
||||
*Last updated: 2026-02-12 after completing 02-01-PLAN.md*
|
||||
*Last updated: 2026-02-12 after completing 02-02-PLAN.md*
|
||||
|
|
|
|||
257
.planning/phases/02-service-infrastructure/02-02-SUMMARY.md
Normal file
257
.planning/phases/02-service-infrastructure/02-02-SUMMARY.md
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
---
|
||||
phase: 02-service-infrastructure
|
||||
plan: 02
|
||||
subsystem: main-process
|
||||
tags: [registry-integration, ipc-refactoring, ssh-context-management]
|
||||
dependency-graph:
|
||||
requires: [02-01]
|
||||
provides: [registry-based-service-routing]
|
||||
affects: [all-ipc-handlers, ssh-connect-flow]
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: [registry-routing, dynamic-service-resolution, context-switching]
|
||||
key-files:
|
||||
created: []
|
||||
modified:
|
||||
- src/main/index.ts
|
||||
- src/main/ipc/handlers.ts
|
||||
- src/main/ipc/projects.ts
|
||||
- src/main/ipc/sessions.ts
|
||||
- src/main/ipc/search.ts
|
||||
- src/main/ipc/subagents.ts
|
||||
- src/main/ipc/ssh.ts
|
||||
decisions:
|
||||
- "File watcher event rewiring handled by exported onContextSwitched callback from index.ts"
|
||||
- "SSH handler imports onContextSwitched dynamically to avoid circular dependencies"
|
||||
- "Context ID for SSH uses simple format: ssh-{host}"
|
||||
- "Destroy existing SSH context on reconnection to same host"
|
||||
metrics:
|
||||
duration: 6
|
||||
completed: 2026-02-12
|
||||
---
|
||||
|
||||
# Phase 02 Plan 02: Registry Integration Summary
|
||||
|
||||
**Registry-based service routing with multi-context SSH support**
|
||||
|
||||
## Objective Achieved
|
||||
|
||||
Replaced global service variables in main/index.ts with ServiceContextRegistry, updated all IPC handlers to route through registry.getActive(), and implemented SSH context creation/destruction flow.
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
### Task 1: Refactor main/index.ts to use ServiceContextRegistry
|
||||
|
||||
**Changed:**
|
||||
- Removed global service variables (projectScanner, sessionParser, subagentResolver, chunkBuilder, dataCache, fileWatcher, cleanupInterval)
|
||||
- Added `contextRegistry: ServiceContextRegistry`
|
||||
- Removed `handleModeSwitch` callback entirely
|
||||
- Created `wireFileWatcherEvents(context)` helper to manage event listener cleanup
|
||||
- Created `onContextSwitched(context)` export for SSH handler to call
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
// Create ServiceContextRegistry
|
||||
contextRegistry = new ServiceContextRegistry();
|
||||
|
||||
// Create local context
|
||||
const localContext = new ServiceContext({
|
||||
id: 'local',
|
||||
type: 'local',
|
||||
fsProvider: new LocalFileSystemProvider(),
|
||||
});
|
||||
|
||||
// Register and start
|
||||
contextRegistry.registerContext(localContext);
|
||||
localContext.start();
|
||||
|
||||
// Wire file watcher events
|
||||
wireFileWatcherEvents(localContext);
|
||||
|
||||
// Initialize IPC handlers with registry
|
||||
initializeIpcHandlers(contextRegistry, updaterService, sshConnectionManager);
|
||||
```
|
||||
|
||||
**handlers.ts changes:**
|
||||
- Changed `initializeIpcHandlers` to accept `ServiceContextRegistry` instead of individual services
|
||||
- Removed `reinitializeServiceHandlers` entirely (no longer needed)
|
||||
- Updated all domain handler initialize calls to pass registry
|
||||
|
||||
**Files modified:**
|
||||
- src/main/index.ts (111 insertions, 161 deletions)
|
||||
- src/main/ipc/handlers.ts
|
||||
|
||||
**Commit:** 5bf41c6
|
||||
|
||||
### Task 2: Update domain IPC handlers to route via registry
|
||||
|
||||
**Pattern applied to all handlers:**
|
||||
```typescript
|
||||
let registry: ServiceContextRegistry;
|
||||
|
||||
export function initialize{Domain}Handlers(contextRegistry: ServiceContextRegistry): void {
|
||||
registry = contextRegistry;
|
||||
}
|
||||
|
||||
async function handleXxx(...): Promise<...> {
|
||||
const { projectScanner, sessionParser, ... } = registry.getActive();
|
||||
// Use services
|
||||
}
|
||||
```
|
||||
|
||||
**projects.ts:**
|
||||
- Changed signature to `initializeProjectHandlers(registry: ServiceContextRegistry)`
|
||||
- Resolve `projectScanner` via `registry.getActive()` in each handler
|
||||
- 3 handlers updated
|
||||
|
||||
**sessions.ts:**
|
||||
- Changed signature to `initializeSessionHandlers(registry: ServiceContextRegistry)`
|
||||
- Destructure all services from `registry.getActive()` at invocation time
|
||||
- 6 handlers updated
|
||||
|
||||
**search.ts:**
|
||||
- Changed signature to `initializeSearchHandlers(registry: ServiceContextRegistry)`
|
||||
- Resolve `projectScanner` via `registry.getActive()`
|
||||
- 1 handler updated
|
||||
|
||||
**subagents.ts:**
|
||||
- Changed signature to `initializeSubagentHandlers(registry: ServiceContextRegistry)`
|
||||
- Resolve all services from `registry.getActive()`
|
||||
- Still passes fsProvider and projectsDir to buildSubagentDetail as before
|
||||
- 1 handler updated
|
||||
|
||||
**ssh.ts:**
|
||||
- Changed signature to `initializeSshHandlers(manager, registry)`
|
||||
- Removed `onModeSwitch` callback parameter
|
||||
- **SSH_CONNECT handler:**
|
||||
- Creates new `ServiceContext` with SSH provider
|
||||
- Registers in registry
|
||||
- Starts context
|
||||
- Switches registry to new context
|
||||
- Dynamically imports `onContextSwitched` from index.ts and calls it
|
||||
- **SSH_DISCONNECT handler:**
|
||||
- Switches registry back to 'local'
|
||||
- Destroys SSH context
|
||||
- Calls `onContextSwitched` with local context
|
||||
- All other SSH handlers unchanged (test, getConfigHosts, etc.)
|
||||
|
||||
**Files modified:**
|
||||
- src/main/ipc/projects.ts
|
||||
- src/main/ipc/sessions.ts
|
||||
- src/main/ipc/search.ts
|
||||
- src/main/ipc/subagents.ts
|
||||
- src/main/ipc/ssh.ts (100 insertions, 70 deletions)
|
||||
|
||||
**Commit:** 24051ac
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None - plan executed exactly as written.
|
||||
|
||||
## Verification Results
|
||||
|
||||
**Type checking:** ✅ Pass
|
||||
```
|
||||
pnpm typecheck — zero errors
|
||||
```
|
||||
|
||||
**Tests:** ✅ Pass
|
||||
```
|
||||
Test Files: 31 passed
|
||||
Tests: 494 passed
|
||||
Duration: 4.88s
|
||||
```
|
||||
|
||||
**Code inspection:** ✅ Pass
|
||||
- main/index.ts has `contextRegistry` instead of individual service globals
|
||||
- `reinitializeServiceHandlers` no longer exists in handlers.ts
|
||||
- All IPC handlers use `registry.getActive()` pattern (12 occurrences)
|
||||
- SSH connect creates ServiceContext and registers it
|
||||
- SSH disconnect destroys SSH context and switches to local
|
||||
- File watcher events rewired via onContextSwitched callback
|
||||
|
||||
## Architecture Impact
|
||||
|
||||
**Before (single-context):**
|
||||
```
|
||||
main/index.ts:
|
||||
let projectScanner: ProjectScanner
|
||||
let sessionParser: SessionParser
|
||||
...
|
||||
|
||||
IPC handlers:
|
||||
let projectScanner = /* set at init */
|
||||
function handleXxx() {
|
||||
projectScanner.scan() // always uses same instance
|
||||
}
|
||||
|
||||
SSH connect:
|
||||
recreate all services with new provider
|
||||
call reinitializeServiceHandlers()
|
||||
```
|
||||
|
||||
**After (multi-context):**
|
||||
```
|
||||
main/index.ts:
|
||||
let contextRegistry: ServiceContextRegistry
|
||||
contextRegistry.registerContext(localContext)
|
||||
|
||||
IPC handlers:
|
||||
let registry: ServiceContextRegistry
|
||||
function handleXxx() {
|
||||
const { projectScanner } = registry.getActive()
|
||||
projectScanner.scan() // dynamically resolved
|
||||
}
|
||||
|
||||
SSH connect:
|
||||
create new ServiceContext
|
||||
registry.registerContext(sshContext)
|
||||
registry.switch('ssh-host')
|
||||
// local context stays alive in background
|
||||
```
|
||||
|
||||
**Key improvements:**
|
||||
1. **No service recreation** - contexts are isolated, switching is instant
|
||||
2. **Local context persists** - can switch back without re-initialization
|
||||
3. **No reinitializeServiceHandlers** - dynamic routing eliminates the need
|
||||
4. **Clean separation** - SSH connection management vs. service context management
|
||||
5. **File watcher stays alive** - only pause/resume on switch
|
||||
|
||||
## Next Steps
|
||||
|
||||
**Phase 02 Plan 03 (SSH notification manager integration):**
|
||||
- Set NotificationManager on SSH context's FileWatcher
|
||||
- Ensure error detection works for SSH sessions
|
||||
- Wire up SSH context file watcher to NotificationManager
|
||||
|
||||
**Phase 03 (Renderer state management):**
|
||||
- Snapshot/restore Zustand state on context switch
|
||||
- Validate tab restoration against current context
|
||||
- Update workspace indicators in sidebar
|
||||
|
||||
## Self-Check
|
||||
|
||||
**Created files exist:** N/A (no new files created)
|
||||
|
||||
**Modified files verified:**
|
||||
```
|
||||
✓ src/main/index.ts — uses contextRegistry
|
||||
✓ src/main/ipc/handlers.ts — accepts registry, no reinitialize function
|
||||
✓ src/main/ipc/projects.ts — routes via registry.getActive()
|
||||
✓ src/main/ipc/sessions.ts — routes via registry.getActive()
|
||||
✓ src/main/ipc/search.ts — routes via registry.getActive()
|
||||
✓ src/main/ipc/subagents.ts — routes via registry.getActive()
|
||||
✓ src/main/ipc/ssh.ts — creates/destroys ServiceContext
|
||||
```
|
||||
|
||||
**Commits exist:**
|
||||
```
|
||||
✓ 5bf41c6 — refactor(02-02): main/index.ts to use ServiceContextRegistry
|
||||
✓ 24051ac — refactor(02-02): IPC handlers route via ServiceContextRegistry
|
||||
```
|
||||
|
||||
**Self-Check: PASSED**
|
||||
|
||||
---
|
||||
*Completed: 2026-02-12*
|
||||
*Duration: 6 minutes*
|
||||
Loading…
Reference in a new issue