Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 56 additions & 2 deletions scripts/main/Start-ClaudeOS.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ $ScriptRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
Import-Module (Join-Path $ScriptRoot 'scripts\lib\LauncherCommon.psm1') -Force -DisableNameChecking
Import-Module (Join-Path $ScriptRoot 'scripts\lib\Config.psm1') -Force
Import-Module (Join-Path $ScriptRoot 'scripts\lib\AgentTeams.psm1') -Force
Import-Module (Join-Path $ScriptRoot 'scripts\lib\McpHealthCheck.psm1') -Force

function Write-BootStep {
param(
Expand Down Expand Up @@ -132,6 +133,60 @@ function Invoke-StepSystemInit {
}
}

function Invoke-StepMemoryRestore {
param([string]$Root)
Write-BootStep 3 'Memory Restore'
try {
Comment on lines +136 to +139

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script header comment still states that Step 3 is a placeholder that emits SKIP (it lists steps 3/5/6/7/8 as placeholders). Since Step 3 is now implemented via Invoke-StepMemoryRestore, please update the top-of-file description to avoid misleading users and future maintainers.

Copilot uses AI. Check for mistakes.
$report = Get-McpHealthReport -ProjectRoot $Root
if (-not $report.configured) {
Write-Host ' [SKIP] .mcp.json not found' -ForegroundColor DarkGray
Write-Host ''
return @{ Step = 3; Name = 'Memory Restore'; Status = 'SKIP'; Detail = 'no mcp config' }
}

$memoryConn = @($report.connections | Where-Object { $_.kind -eq 'memory' }) | Select-Object -First 1
if (-not $memoryConn) {
Write-Host ' [SKIP] memory server not configured in .mcp.json' -ForegroundColor DarkGray
Comment on lines +141 to +149

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SKIP message hard-codes “.mcp.json not found”, but Get-McpHealthReport can be configured to look at a different config path via AI_STARTUP_MCP_CONFIG_PATH. Consider printing/reporting the actual $report.configPath (or similar) so the message remains accurate when a custom config path is used.

Suggested change
if (-not $report.configured) {
Write-Host ' [SKIP] .mcp.json not found' -ForegroundColor DarkGray
Write-Host ''
return @{ Step = 3; Name = 'Memory Restore'; Status = 'SKIP'; Detail = 'no mcp config' }
}
$memoryConn = @($report.connections | Where-Object { $_.kind -eq 'memory' }) | Select-Object -First 1
if (-not $memoryConn) {
Write-Host ' [SKIP] memory server not configured in .mcp.json' -ForegroundColor DarkGray
$configLabel = if ($report.configPath) { $report.configPath } else { '.mcp.json' }
if (-not $report.configured) {
Write-Host (' [SKIP] {0} not found' -f $configLabel) -ForegroundColor DarkGray
Write-Host ''
return @{ Step = 3; Name = 'Memory Restore'; Status = 'SKIP'; Detail = 'no mcp config' }
}
$memoryConn = @($report.connections | Where-Object { $_.kind -eq 'memory' }) | Select-Object -First 1
if (-not $memoryConn) {
Write-Host (' [SKIP] memory server not configured in {0}' -f $configLabel) -ForegroundColor DarkGray

Copilot uses AI. Check for mistakes.
Write-Host ''
return @{ Step = 3; Name = 'Memory Restore'; Status = 'SKIP'; Detail = 'no memory server' }
}
Comment on lines +147 to +152

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invoke-StepMemoryRestore returns Status='OK' as long as a memory server entry exists in .mcp.json, even if that server is unavailable/unhealthy (e.g., command missing on Linux, or runtime probe/health status indicates failure). This can lead to a misleading boot summary where Memory Restore reports OK when it cannot actually run. Consider basing the status on the selected memory server’s availability/health (e.g., skip or fail with a clear detail when unavailable) and include the connection/server status in the returned Detail for diagnostics.

Copilot uses AI. Check for mistakes.

$filePath = $env:CLAUDE_MEMORY_FILE_PATH
$entryCount = 0
if ($filePath -and (Test-Path $filePath)) {
try {
$data = Get-Content $filePath -Raw -Encoding UTF8 | ConvertFrom-Json -ErrorAction Stop
$entryCount = if ($data.entities) { @($data.entities).Count } else { 0 }
}
catch { $entryCount = 0 }
}

$fileLabel = if ($filePath -and (Test-Path $filePath)) {
'found ({0} entries)' -f $entryCount
}
Comment on lines +154 to +166

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The memory file existence checks use Test-Path $filePath (twice) without -LiteralPath / -PathType Leaf. Using -LiteralPath avoids wildcard expansion, and PathType Leaf avoids treating a directory as a valid “memory file”; also consider computing a single $fileExists flag to avoid repeating Test-Path.

Copilot uses AI. Check for mistakes.
elseif ($filePath) {
'configured (file not yet created)'
}
else {
'CLAUDE_MEMORY_FILE_PATH not set'
}
Comment on lines +167 to +172

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description says that when CLAUDE_MEMORY_FILE_PATH is unset the output should show something like “configured (file not yet created)” as a normal case, but the implementation labels it “CLAUDE_MEMORY_FILE_PATH not set”. Please align the output behavior with the PR description (either adjust the message/logic or update the PR description).

Copilot uses AI. Check for mistakes.
Write-Host (' [OK] Memory MCP : configured' ) -ForegroundColor Green
Write-Host (' Memory file : {0}' -f $fileLabel) -ForegroundColor Cyan
Write-Host ''
return @{
Step = 3
Name = 'Memory Restore'
Status = 'OK'
Detail = @{ entryCount = $entryCount; filePath = $filePath; configured = $true }
}
}
catch {
Write-Host (' [FAIL] Memory Restore: {0}' -f $_.Exception.Message) -ForegroundColor Red
Write-Host ''
return @{ Step = 3; Name = 'Memory Restore'; Status = 'FAIL'; Detail = $_.Exception.Message }
}
}

function Invoke-StepPlaceholder {
param([int]$Number, [string]$Name, [string]$Reason)
Write-BootStep $Number $Name 'SKIP'
Expand Down Expand Up @@ -190,8 +245,7 @@ Write-BootBanner
$results = @()
$results += Invoke-StepEnvironmentCheck
$results += Invoke-StepProjectDetection -Root $ScriptRoot
$results += Invoke-StepPlaceholder -Number 3 -Name 'Memory Restore' `
-Reason 'Memory MCP persistence not yet integrated'
$results += Invoke-StepMemoryRestore -Root $ScriptRoot
$results += Invoke-StepSystemInit
$results += Invoke-StepPlaceholder -Number 5 -Name 'Executive Init' `
-Reason 'Runtime CTO / Strategy Engine is a conceptual layer (Claude itself)'
Expand Down
11 changes: 9 additions & 2 deletions tests/StartScripts.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,23 @@ Describe 'Start-*.ps1 dry-run flows' {
$output | Should -Match '\[DRY RUN\] No side effects will be applied'
}

It 'Start-ClaudeOS.ps1 の Step 3/5/6/8 がプレースホルダー SKIP になること' {
It 'Start-ClaudeOS.ps1 の Step 5/6/8 がプレースホルダー SKIP になること' {
$scriptPath = Join-Path $script:RepoRoot 'scripts\main\Start-ClaudeOS.ps1'
$output = & $script:PowerShellExe -NoProfile -File $scriptPath -NonInteractive 2>&1 | Out-String
$LASTEXITCODE | Should -Be 0
$output | Should -Match '\[Step 3\].*Memory Restore.*SKIP'
$output | Should -Match '\[Step 5\].*Executive Init.*SKIP'
$output | Should -Match '\[Step 6\].*Management Init.*SKIP'
$output | Should -Match '\[Step 8\].*Loop Engine Start.*SKIP'
}

It 'Start-ClaudeOS.ps1 の Step 3 が Memory Restore として実行されること (Issue #70)' {
$scriptPath = Join-Path $script:RepoRoot 'scripts\main\Start-ClaudeOS.ps1'
$output = & $script:PowerShellExe -NoProfile -File $scriptPath -NonInteractive 2>&1 | Out-String
$LASTEXITCODE | Should -Be 0
$output | Should -Match '\[Step 3\].*Memory Restore'
$output | Should -Not -Match '\[Step 3\].*Memory Restore.*SKIP'
}

It 'Start-ClaudeOS.ps1 の Step 7 が Agent Init として実行されること (PR-B)' {
$scriptPath = Join-Path $script:RepoRoot 'scripts\main\Start-ClaudeOS.ps1'
$output = & $script:PowerShellExe -NoProfile -File $scriptPath -NonInteractive 2>&1 | Out-String
Expand Down
Loading