2 Commits

Author SHA1 Message Date
hsiegeln
553ecc1490 fix: PowerShell installer fixes for Windows and Logto console login
All checks were successful
CI / build (push) Successful in 1m7s
CI / docker (push) Successful in 18s
Three issues fixed:

1. Docker socket: use /var/run/docker.sock instead of Windows named pipe
   (//./pipe/docker_engine) — Linux containers can't use named pipes.

2. FQDN detection: reverse-DNS lookup on host IPs to find the FQDN
   instead of relying on GetHostEntry which returns bare hostname on
   Windows machines with DNS-registered domain suffixes.

3. Reinstall path duplication: Push-Location/Pop-Location in the
   reinstall handler used try/catch without finally, so Pop-Location
   was skipped when docker compose wrote to stderr under
   ErrorActionPreference=Stop. CWD stayed in the install dir, causing
   the relative ./cameleer default to resolve to cameleer/cameleer.

4. Logto bootstrap: register admin-console redirect URIs and add the
   admin user to Logto's internal organizations (t-default, t-admin)
   with the admin role — both required for console login to work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 22:46:05 +02:00
hsiegeln
dec1c53d30 docs: track AGENTS.md for GitNexus code intelligence instructions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:04:06 +02:00
3 changed files with 151 additions and 11 deletions

101
AGENTS.md Normal file
View File

@@ -0,0 +1,101 @@
<!-- gitnexus:start -->
# GitNexus — Code Intelligence
This project is indexed by GitNexus as **cameleer-saas** (2676 symbols, 5768 relationships, 224 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
## Always Do
- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows.
- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`.
## When Debugging
1. `gitnexus_query({query: "<error or symptom>"})` — find execution flows related to the issue
2. `gitnexus_context({name: "<suspect function>"})` — see all callers, callees, and process participation
3. `READ gitnexus://repo/cameleer-saas/process/{processName}` — trace the full execution flow step by step
4. For regressions: `gitnexus_detect_changes({scope: "compare", base_ref: "main"})` — see what your branch changed
## When Refactoring
- **Renaming**: MUST use `gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})` first. Review the preview — graph edits are safe, text_search edits need manual review. Then run with `dry_run: false`.
- **Extracting/Splitting**: MUST run `gitnexus_context({name: "target"})` to see all incoming/outgoing refs, then `gitnexus_impact({target: "target", direction: "upstream"})` to find all external callers before moving code.
- After any refactor: run `gitnexus_detect_changes({scope: "all"})` to verify only expected files changed.
## Never Do
- NEVER edit a function, class, or method without first running `gitnexus_impact` on it.
- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph.
- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope.
## Tools Quick Reference
| Tool | When to use | Command |
|------|-------------|---------|
| `query` | Find code by concept | `gitnexus_query({query: "auth validation"})` |
| `context` | 360-degree view of one symbol | `gitnexus_context({name: "validateUser"})` |
| `impact` | Blast radius before editing | `gitnexus_impact({target: "X", direction: "upstream"})` |
| `detect_changes` | Pre-commit scope check | `gitnexus_detect_changes({scope: "staged"})` |
| `rename` | Safe multi-file rename | `gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})` |
| `cypher` | Custom graph queries | `gitnexus_cypher({query: "MATCH ..."})` |
## Impact Risk Levels
| Depth | Meaning | Action |
|-------|---------|--------|
| d=1 | WILL BREAK — direct callers/importers | MUST update these |
| d=2 | LIKELY AFFECTED — indirect deps | Should test |
| d=3 | MAY NEED TESTING — transitive | Test if critical path |
## Resources
| Resource | Use for |
|----------|---------|
| `gitnexus://repo/cameleer-saas/context` | Codebase overview, check index freshness |
| `gitnexus://repo/cameleer-saas/clusters` | All functional areas |
| `gitnexus://repo/cameleer-saas/processes` | All execution flows |
| `gitnexus://repo/cameleer-saas/process/{name}` | Step-by-step execution trace |
## Self-Check Before Finishing
Before completing any code modification task, verify:
1. `gitnexus_impact` was run for all modified symbols
2. No HIGH/CRITICAL risk warnings were ignored
3. `gitnexus_detect_changes()` confirms changes match expected scope
4. All d=1 (WILL BREAK) dependents were updated
## Keeping the Index Fresh
After committing code changes, the GitNexus index becomes stale. Re-run analyze to update it:
```bash
npx gitnexus analyze
```
If the index previously included embeddings, preserve them by adding `--embeddings`:
```bash
npx gitnexus analyze --embeddings
```
To check whether embeddings exist, inspect `.gitnexus/meta.json` — the `stats.embeddings` field shows the count (0 means no embeddings). **Running analyze without `--embeddings` will delete any previously generated embeddings.**
> Claude Code users: A PostToolUse hook handles this automatically after `git commit` and `git merge`.
## CLI
| Task | Read this skill file |
|------|---------------------|
| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |
<!-- gitnexus:end -->

View File

@@ -476,6 +476,28 @@ if [ -n "$ADMIN_TENANT_USER_ID" ] && [ "$ADMIN_TENANT_USER_ID" != "null" ]; then
admin_api_patch "/api/sign-in-exp" '{"signInMode": "SignIn"}' >/dev/null 2>&1
log "Set sign-in mode to SignIn."
# Register admin-console redirect URIs (Logto ships with empty URIs)
ADMIN_PUBLIC="${ADMIN_ENDPOINT:-${PROTO}://${HOST}:3002}"
admin_api_patch "/api/applications/admin-console" "{
\"oidcClientMetadata\": {
\"redirectUris\": [\"${ADMIN_PUBLIC}/console/callback\"],
\"postLogoutRedirectUris\": [\"${ADMIN_PUBLIC}/console\"]
}
}" >/dev/null 2>&1
log "Registered admin-console redirect URIs."
# Add admin user to Logto's internal organizations (required for console login)
for ORG_ID in t-default t-admin; do
admin_api_post "/api/organizations/${ORG_ID}/users" "{\"userIds\": [\"$ADMIN_TENANT_USER_ID\"]}" >/dev/null 2>&1
done
ADMIN_ORG_ROLE_ID=$(admin_api_get "/api/organization-roles" | jq -r '.[] | select(.name == "admin") | .id')
if [ -n "$ADMIN_ORG_ROLE_ID" ] && [ "$ADMIN_ORG_ROLE_ID" != "null" ]; then
for ORG_ID in t-default t-admin; do
admin_api_post "/api/organizations/${ORG_ID}/users/${ADMIN_TENANT_USER_ID}/roles" "{\"organizationRoleIds\": [\"$ADMIN_ORG_ROLE_ID\"]}" >/dev/null 2>&1
done
fi
log "Added admin to Logto console organizations."
log "SaaS admin granted Logto console access."
else
log "WARNING: Could not create admin console user"

View File

@@ -347,19 +347,36 @@ function Check-Prerequisites {
function Auto-Detect {
if (-not $script:cfg.PublicHost) {
$detectedHost = $null
# Try reverse DNS on each host IP — picks up FQDN from DNS server
try {
$fqdn = [System.Net.Dns]::GetHostEntry([System.Net.Dns]::GetHostName()).HostName
$script:cfg.PublicHost = $fqdn.ToLower()
} catch {
$script:cfg.PublicHost = [System.Net.Dns]::GetHostName().ToLower()
foreach ($addr in [System.Net.Dns]::GetHostAddresses([System.Net.Dns]::GetHostName())) {
if ($addr.AddressFamily -ne 'InterNetwork') { continue } # IPv4 only
if ($addr.ToString().StartsWith('127.')) { continue }
try {
$rev = [System.Net.Dns]::GetHostEntry($addr).HostName
if ($rev -and $rev.Contains('.')) {
$detectedHost = $rev
break
}
} catch {}
}
} catch {}
if (-not $detectedHost) {
# Fallback: .NET forward lookup, then bare hostname
try {
$detectedHost = [System.Net.Dns]::GetHostEntry([System.Net.Dns]::GetHostName()).HostName
} catch {
$detectedHost = [System.Net.Dns]::GetHostName()
}
}
$script:cfg.PublicHost = $detectedHost.ToLower()
}
if (-not $script:cfg.DockerSocket) {
if ($env:OS -eq 'Windows_NT') {
$script:cfg.DockerSocket = '//./pipe/docker_engine'
} else {
$script:cfg.DockerSocket = $DEFAULT_DOCKER_SOCKET
}
# Always use /var/run/docker.sock — containers are Linux and Docker Desktop
# maps the host socket into the VM automatically. The Windows named pipe
# (//./pipe/docker_engine) does NOT work as a volume mount for Linux containers.
$script:cfg.DockerSocket = $DEFAULT_DOCKER_SOCKET
}
}
@@ -1720,12 +1737,12 @@ function Handle-Rerun {
}
Log-Info 'Reinstalling...'
try { Invoke-ComposeDown } catch {}
Push-Location $c.InstallDir
try {
Push-Location $c.InstallDir
$proj = Coalesce $c.ComposeProject 'cameleer-saas'
docker compose -p $proj down -v 2>$null
Pop-Location
} catch {}
finally { Pop-Location }
foreach ($fname in @('.env','.env.bak','docker-compose.yml','cameleer.conf','credentials.txt','INSTALL.md','traefik-dynamic.yml')) {
$fp = Join-Path $c.InstallDir $fname
if (Test-Path $fp) { Remove-Item $fp -Force }