From e6c362e5609b15ec3bc7d6806469c1012904be71 Mon Sep 17 00:00:00 2001 From: Michael Dieringer <65093775+MichaelDieringer@users.noreply.github.com> Date: Fri, 3 Jul 2026 17:08:36 +0200 Subject: [PATCH] AL MCP cwd-agnostisk: walk-up + auto-projektopdagelse (setup v18) Efter genstart var al stadig Failed. MCP-loggen gav beviskaeden: cwd = .apps\PrebenZ (app-mappen - one-workspace-standarden binder sessionen dertil), og CLAUDE_PROJECT_DIR er IKKE sat for MCP-launches, saa ${CLAUDE_PROJECT_DIR:-.} faldt tilbage til app-mappen hvor .vscode ikke findes. Workspace-standarden og .mcp.json-antagelsen var i konflikt. Fix - og en forbedring af standarden: - find-altool.ps1 v3: cwd-agnostisk anker ($PSScriptRoot), og nyt auto-argument der selv opdager alle AL-projektmapper (app.json under .apps/Apps/apps) og substituerer dem i launchmcpserver-kaldet - Setup v18, 4b: al-entryen er nu BYTE-IDENTISK paa tvaers af alle repos - -Command med walk-up fra cwd til .vscode\find-altool.ps1 + launchmcpserver auto. Ingen {APP_FOLDER}-substitution. - Mode B check 4: aeldre former erstattes stille med den universelle Live-testet fra praecis den cwd der fejlede (.apps\PrebenZ): serveren overlever. PrebenZ + JP haandrettet paa Michaels maskine. Co-Authored-By: Claude Fable 5 --- custom/setup/curabis-standard.agent.md | 44 ++++++++++++++------------ custom/setup/templates/find-altool.ps1 | 39 +++++++++++++++++++---- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/custom/setup/curabis-standard.agent.md b/custom/setup/curabis-standard.agent.md index a4f8684..ba73b19 100644 --- a/custom/setup/curabis-standard.agent.md +++ b/custom/setup/curabis-standard.agent.md @@ -1,7 +1,7 @@ --- kind: action-skill id: curabis-standard-setup -version: 17 +version: 18 title: CURABIS Standard — Project Setup description: > Configures a new or existing repository to the CURABIS Standard development @@ -356,10 +356,16 @@ MCP Server" referenced a command that does not exist). 1. If `.vscode/find-altool.ps1` is missing: fetch `{BASE}/templates/find-altool.ps1` AS RAW BYTES → `.vscode/find-altool.ps1` (create `.vscode/` if needed) and stage it for commit. -2. Write `.mcp.json` — ALWAYS with both entries. **`launchmcpserver` REQUIRES - the project folders as arguments** (`altool launchmcpserver `); - without them the server exits immediately and `/mcp` shows `al` as Failed. - Substitute the actual app folders from Step 2: +2. Write `.mcp.json` — ALWAYS with both entries, and the `al` entry is + **byte-identical for every repo** (no substitution). Two facts force the + shape: (a) `altool launchmcpserver ` REQUIRES project folders or + the server dies instantly; (b) sessions bind to the apps-workspace folder + (one-workspace standard), so the MCP server's cwd is an APP folder, not + the repo root — and `${CLAUDE_PROJECT_DIR}` is NOT available to MCP + launches (verified from logs: the fallback `.` resolved to + `.apps\` and `-File` failed). The entry therefore walks up from cwd + to the repo's `.vscode\find-altool.ps1`, and the script resolves the + project folders itself via the `auto` argument: ```json { @@ -368,12 +374,9 @@ MCP Server" referenced a command that does not exist). "type": "stdio", "command": "powershell", "args": [ - "-ExecutionPolicy", "Bypass", - "-File", "${CLAUDE_PROJECT_DIR:-.}\\.vscode\\find-altool.ps1", - "launchmcpserver", - "${CLAUDE_PROJECT_DIR:-.}\\.apps\\{APP_FOLDER}", - "${CLAUDE_PROJECT_DIR:-.}\\.apps\\{APP_FOLDER}.Test", - "--transport", "stdio" + "-NoProfile", "-ExecutionPolicy", "Bypass", + "-Command", + "$d=(Get-Location).Path; while(-not(Test-Path(Join-Path $d '.vscode\\find-altool.ps1')) -and $d.Length -gt 3){$d=Split-Path $d}; $f=Join-Path $d '.vscode\\find-altool.ps1'; if(-not(Test-Path $f)){Write-Error 'find-altool.ps1 ikke fundet i nogen overliggende mappe'; exit 1}; & $f launchmcpserver auto --transport stdio" ] }, "businesscentral": { @@ -384,9 +387,6 @@ MCP Server" referenced a command that does not exist). } ``` -(One `${CLAUDE_PROJECT_DIR:-.}\...`-line per app project — a repo with only a -main app has one; main + test has two.) - Use Claude Code's built-in environment-variable expansion — `${CLAUDE_PROJECT_DIR:-.}` and `${USERPROFILE}` — instead of substituting literal detected paths. `.mcp.json` is git-committed and shared; a path baked in for one developer's machine or username @@ -626,13 +626,15 @@ literal username or drive path: 2. Check the `-File` value is `${CLAUDE_PROJECT_DIR:-.}\.vscode\find-altool.ps1` 3. If it is a literal absolute path (e.g. `C:\Curabis\ProjectX\.vscode\find-altool.ps1` or any drive-letter path): **correct it silently** to use `${CLAUDE_PROJECT_DIR:-.}` -4. Check that at least one project path stands between `launchmcpserver` and - `--transport` — `altool launchmcpserver ` REQUIRES the app - folders, or the server exits immediately (`/mcp` shows `al` as Failed). - If missing: **correct silently** by inserting one - `${CLAUDE_PROJECT_DIR:-.}\`-argument per AL app project in the - repo, then report the correction and remind the developer to restart - Claude Code. +4. Check that the `al` entry uses the universal cwd-agnostic form from + Mode A 4b (`-Command` with walk-up + `launchmcpserver auto`). OLDER forms + fail predictably: `-File ${CLAUDE_PROJECT_DIR:-.}\...` breaks because + sessions bind to the apps-workspace folder (cwd = app folder, no + `${CLAUDE_PROJECT_DIR}` in MCP launches); explicit project paths with the + same prefix break identically. If the entry deviates: **replace it + silently** with the universal form (byte-identical across repos), ensure + `find-altool.ps1` is current (it must support `auto`), then report the + correction and remind the developer to restart Claude Code. Report any correction made: ``` diff --git a/custom/setup/templates/find-altool.ps1 b/custom/setup/templates/find-altool.ps1 index 3c37235..f0de6c4 100644 --- a/custom/setup/templates/find-altool.ps1 +++ b/custom/setup/templates/find-altool.ps1 @@ -1,11 +1,16 @@ # find-altool.ps1 - CURABIS-artefakt (deployes fra BCQuality, ikke genereret # af AL-extensionen - der findes ingen VS Code-kommando til dette). # -# Finder altool.exe dynamisk i den NYESTE installerede AL Language extension, -# uanset version, og videresender alle argumenter. Bruges af .mcp.json til at -# starte AL MCP-serveren - BEMÆRK: launchmcpserver KRÆVER projektstierne som -# argumenter, ellers dør serveren straks: -# powershell -ExecutionPolicy Bypass -File .vscode/find-altool.ps1 launchmcpserver .apps/MinApp .apps/MinApp.Test --transport stdio +# Finder altool.exe dynamisk i den NYESTE installerede AL Language extension +# og videresender alle argumenter. Scriptet er cwd-agnostisk: det ligger i +# \.vscode\ og kan derfor selv udlede repo-roden ($PSScriptRoot\..). +# +# Specialargument 'auto': erstattes med alle AL-projektmapper fundet under +# repoets apps-mappe (.apps/Apps/apps - mapper med app.json). Dermed er +# .mcp.json-entryen identisk paa tvaers af alle repos: +# ... find-altool.ps1 launchmcpserver auto --transport stdio +# +# BEMAERK: altool launchmcpserver KRAEVER projektstier - uden doer serveren. $ext = Get-ChildItem "$env:USERPROFILE\.vscode\extensions" -Filter "ms-dynamics-smb.al-*" -Directory | Sort-Object { [version]($_.Name -replace '^ms-dynamics-smb\.al-', '' -replace '-.*$', '') } -Descending | @@ -23,4 +28,26 @@ if (-not (Test-Path $altool)) { exit 1 } -& $altool @args +if ($args -contains 'auto') { + $repo = Split-Path $PSScriptRoot + $projects = @() + foreach ($appsName in @('.apps', 'Apps', 'apps')) { + $appsDir = Join-Path $repo $appsName + if (Test-Path $appsDir) { + $projects += Get-ChildItem $appsDir -Directory | + Where-Object { Test-Path (Join-Path $_.FullName 'app.json') } | + ForEach-Object { $_.FullName } + } + } + if (-not $projects) { + Write-Error "Ingen AL-projektmapper (med app.json) fundet under $repo\.apps|Apps|apps." + exit 1 + } + $resolved = @() + foreach ($a in $args) { + if ($a -eq 'auto') { $resolved += $projects } else { $resolved += $a } + } + & $altool @resolved +} else { + & $altool @args +}