Compare commits

...
12 Commits
Author SHA1 Message Date
Julian lechnerandClaude Sonnet 5 e88d27ac43 docs(configuration): document the multi_agent_v2 decision
CI / linux (push) Successful in 12s
CI / windows (push) Canceled after 0s
Recorded why it is not configured: it does not appear in the current
documented Codex schema, only in upstream issue titles describing an
internal/experimental flag. [agents].enabled already covers enabling
multi-agent tools; the schema's separate [features].multi_agent toggle
would be redundant alongside it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:07:51 +02:00
Julian lechnerandClaude Sonnet 5 03d44e1d71 docs(configuration): correct the max_depth claim
The previous wording implied a global max_depth-style setting had been
considered generically; the only such key in Codex's schema is
network_proxy.glob_scan_max_depth, which bounds glob expansion for the
network proxy feature and has nothing to do with agents. Claude Code
exposes no comparable key either.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:07:37 +02:00
Julian lechnerandClaude Sonnet 5 4e7056e821 ci: bump actions/checkout to v6
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:07:32 +02:00
Julian lechnerandClaude Sonnet 5 0ae373c202 fix(installer): tolerate BOM, CRLF, and uppercase in older manifests (Bash)
Bash's manifest reader stripped only the trailing newline, so a
CRLF-terminated manifest left a stray \r on every hash, a UTF-8 BOM on the
header line was folded into the "path" field, and an uppercase hash never
matched sha256sum's lowercase output. Reproduced against a real
manifest written by an earlier version of the PowerShell installer, where
every single managed file was misreported as locally modified.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:07:27 +02:00
Julian lechnerandClaude Sonnet 5 1c2d155fcc fix(installer): write manifest hashes lowercase and without a BOM (PowerShell)
Windows PowerShell 5.1's -Encoding UTF8 always prepends a BOM, and
Get-FileHash returns uppercase hex. Bash's manifest reader expects neither,
so a manifest written by this module and later read by the Bash
equivalent (or vice versa) mismatched on every single entry: the BOM
folded into the header's first field, and every hash comparison failed on
case alone. Hashes are now lowercased on read and write, and the manifest
file itself is written UTF-8 without a BOM.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:07:17 +02:00
Julian lechnerandClaude Sonnet 5 e143f9d087 fix(tests): add explicit exit 0 on success (PowerShell build validation)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:07:06 +02:00
Julian lechnerandClaude Sonnet 5 a4ea912b60 fix(tests): add explicit exit 0 on success (PowerShell managed install)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:07:02 +02:00
Julian lechnerandClaude Sonnet 5 c866fe44f0 fix(tests): add explicit exit 0 on success (PowerShell platform packages)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:06:57 +02:00
Julian lechnerandClaude Sonnet 5 c89aa4885c fix(installer): add explicit exit 0 on success (PowerShell)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:06:52 +02:00
Julian lechnerandClaude Sonnet 5 c9ef92e424 fix(doctor): add explicit exit 0 on success (PowerShell)
doctor.ps1 already exited 1 on failure but relied on the implicit process
exit code on success, which a stale $LASTEXITCODE from an earlier native
call (e.g. codex --version) could turn into a false failure in CI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:06:48 +02:00
Julian lechnerandClaude Sonnet 5 6314b408b3 fix(build): add explicit exit 0 on success (PowerShell)
Without it, a stale $LASTEXITCODE left over from an earlier native
command in the same PowerShell session could cause a CI step to be
reported as failed even though the script itself completed successfully.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:06:42 +02:00
Julian lechnerandClaude Sonnet 5 1163f6d96e fix: mark shell scripts executable in git
All tracked .sh files were stored as mode 100644 (non-executable), even
though the CI workflow and normal usage invoke several of them directly
(./scripts/build.sh) rather than through `bash`. On a fresh Linux
checkout this fails with a permission error.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:06:37 +02:00
22 changed files with 30 additions and 8 deletions

No files matched your search

+2 -2
View File
@@ -9,7 +9,7 @@ jobs:
linux: linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Build - name: Build
run: ./scripts/build.sh run: ./scripts/build.sh
- name: Doctor - name: Doctor
@@ -29,7 +29,7 @@ jobs:
windows: windows:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Build - name: Build
shell: powershell shell: powershell
run: .\scripts\build.ps1 run: .\scripts\build.ps1
+3 -1
View File
@@ -4,7 +4,9 @@ Codex receives a generated global `AGENTS.md`, agent TOML files, skills, rule fi
Claude's rule loading differs from Codex's by design: `general.md` is the only rule shipped as a plain, always-applied file (its text is also embedded directly in `CLAUDE.md`). Every technology- or situation-specific rule in `shared/rules/` is instead generated as a skill under `skills/rules/`, driven by `adapters/claude/rule-skills.tsv` (rule file, skill name, trigger description). Only a skill's name and description are ever permanently in context; Claude loads the full rule text only when it invokes the skill. Codex is unaffected — it keeps receiving every rule as a plain file and is told to load the matching one by path, exactly as before. Claude's rule loading differs from Codex's by design: `general.md` is the only rule shipped as a plain, always-applied file (its text is also embedded directly in `CLAUDE.md`). Every technology- or situation-specific rule in `shared/rules/` is instead generated as a skill under `skills/rules/`, driven by `adapters/claude/rule-skills.tsv` (rule file, skill name, trigger description). Only a skill's name and description are ever permanently in context; Claude loads the full rule text only when it invokes the skill. Codex is unaffected — it keeps receiving every rule as a plain file and is told to load the matching one by path, exactly as before.
Neither current client configuration model exposes a supported global `max_depth` setting. The repository does not emit an unsupported key that would be ignored or cause configuration validation errors. Codex's current configuration schema has no `agents.max_depth` or other agent-recursion-depth key. The only `max_depth`-shaped setting in the schema is `network_proxy.glob_scan_max_depth`, which bounds glob-pattern expansion for the network proxy feature and is unrelated to agents; Claude Code's settings likewise expose no comparable key. The repository does not emit either as an invented key.
`[agents].enabled = true` (set explicitly, matching its own documented default) is the current, documented way to enable Codex's multi-agent tools. A separate `[features].multi_agent` toggle exists in the schema but is not set here, since `[agents].enabled` already covers it and setting both would be redundant. `multi_agent_v2` does not appear in the current documented schema at all — it surfaced only in upstream issue titles describing an internal/experimental flag — so it is deliberately not configured.
Client settings remain thin adapters. Shared semantics remain in `shared/`. Client settings remain thin adapters. Shared semantics remain in `shared/`.
+1
View File
@@ -173,3 +173,4 @@ $leftoverPlaceholders = @(Get-ChildItem $output -File -Recurse | ForEach-Object
if ($leftoverPlaceholders.Count) { throw "Unresolved template placeholders in: $($leftoverPlaceholders -join ', ')" } if ($leftoverPlaceholders.Count) { throw "Unresolved template placeholders in: $($leftoverPlaceholders -join ', ')" }
Write-Output 'PASS build: codex-windows, claude-windows, codex-linux, claude-linux' Write-Output 'PASS build: codex-windows, claude-windows, codex-linux, claude-linux'
exit 0
Regular → Executable
View File
File mode changed.
+1
View File
@@ -66,3 +66,4 @@ foreach ($path in @('shared/rules','shared/skills','shared/agents','shared/hooks
if ($fail) { exit 1 } if ($fail) { exit 1 }
Write-Output 'PASS doctor' Write-Output 'PASS doctor'
exit 0
Regular → Executable
View File
File mode changed.
+1
View File
@@ -50,3 +50,4 @@ foreach ($item in $targets) {
Install-ConfiguredPlugins -RepositoryRoot $root -Client $Client -DryRun:$DryRun -Update:$UpdatePlugins Install-ConfiguredPlugins -RepositoryRoot $root -Client $Client -DryRun:$DryRun -Update:$UpdatePlugins
Write-Output ($(if ($DryRun) { 'PASS install dry-run' } else { 'PASS install' })) Write-Output ($(if ($DryRun) { 'PASS install dry-run' } else { 'PASS install' }))
exit 0
Regular → Executable
View File
File mode changed.
+12 -4
View File
@@ -5,13 +5,15 @@ function Get-ManagedManifestPath {
function Get-Sha256Hash { function Get-Sha256Hash {
param([Parameter(Mandatory=$true)][string]$Path) param([Parameter(Mandatory=$true)][string]$Path)
return (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash # Lowercase to match sha256sum's output, since the manifest must be readable by
# both this module and its Bash equivalent regardless of which one wrote it.
return (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant()
} }
function Get-Sha256HashOfBytes { function Get-Sha256HashOfBytes {
param([Parameter(Mandatory=$true)][byte[]]$Bytes) param([Parameter(Mandatory=$true)][byte[]]$Bytes)
$sha256 = [System.Security.Cryptography.SHA256]::Create() $sha256 = [System.Security.Cryptography.SHA256]::Create()
try { return ([System.BitConverter]::ToString($sha256.ComputeHash($Bytes))).Replace('-', '') } try { return ([System.BitConverter]::ToString($sha256.ComputeHash($Bytes))).Replace('-', '').ToLowerInvariant() }
finally { $sha256.Dispose() } finally { $sha256.Dispose() }
} }
@@ -19,7 +21,8 @@ function Read-ManagedManifest {
param([Parameter(Mandatory=$true)][string]$ManifestPath) param([Parameter(Mandatory=$true)][string]$ManifestPath)
$entries = @{} $entries = @{}
if (Test-Path -LiteralPath $ManifestPath) { if (Test-Path -LiteralPath $ManifestPath) {
Import-Csv -LiteralPath $ManifestPath -Delimiter ([char]9) | ForEach-Object { $entries[$_.path] = $_.sha256 } # Lowercase to tolerate an older manifest written before hashes were normalized.
Import-Csv -LiteralPath $ManifestPath -Delimiter ([char]9) | ForEach-Object { $entries[$_.path] = $_.sha256.ToLowerInvariant() }
} }
return $entries return $entries
} }
@@ -29,7 +32,12 @@ function Write-ManagedManifest {
$lines = @("path`tsha256") $lines = @("path`tsha256")
foreach ($path in ($Entries.Keys | Sort-Object)) { $lines += "$path`t$($Entries[$path])" } foreach ($path in ($Entries.Keys | Sort-Object)) { $lines += "$path`t$($Entries[$path])" }
New-Item (Split-Path $ManifestPath -Parent) -ItemType Directory -Force | Out-Null New-Item (Split-Path $ManifestPath -Parent) -ItemType Directory -Force | Out-Null
Set-Content -LiteralPath $ManifestPath -Value $lines -Encoding UTF8 # Windows PowerShell 5.1's -Encoding UTF8 always prepends a BOM, which Bash's plain
# `read` would otherwise fold into the first field of the header line. Write UTF-8
# without BOM and with LF line endings so either implementation can read the file
# regardless of which one wrote it.
$content = ($lines -join "`n") + "`n"
[System.IO.File]::WriteAllText($ManifestPath, $content, (New-Object System.Text.UTF8Encoding($false)))
} }
function Sync-ManagedDestination { function Sync-ManagedDestination {
Regular → Executable
+7 -1
View File
@@ -24,8 +24,14 @@ read_managed_manifest() {
[ -f "$path" ] || return 0 [ -f "$path" ] || return 0
local rel hash first=1 local rel hash first=1
while IFS=$'\t' read -r rel hash; do while IFS=$'\t' read -r rel hash; do
if [ "$first" = 1 ]; then first=0; [ "$rel" = path ] && continue; fi hash=${hash%$'\r'} # tolerate a CRLF-terminated manifest (read only strips the trailing \n)
if [ "$first" = 1 ]; then
first=0
rel=${rel#$'\xef\xbb\xbf'} # tolerate a UTF-8 BOM on the header line
[ "$rel" = path ] && continue
fi
[ -n "$rel" ] || continue [ -n "$rel" ] || continue
hash=$(printf '%s' "$hash" | tr '[:upper:]' '[:lower:]') # tolerate uppercase hashes from older manifests
out_ref[$rel]=$hash out_ref[$rel]=$hash
done < "$path" done < "$path"
} }
Regular → Executable
View File
File mode changed.
+1
View File
@@ -49,3 +49,4 @@ Test-BuildFails 'leftover template placeholder' {
Remove-Item $work -Recurse -Force -ErrorAction SilentlyContinue Remove-Item $work -Recurse -Force -ErrorAction SilentlyContinue
Write-Output 'PASS build validation: invalid JSON, duplicate agent, duplicate plugin, and leftover placeholders are all rejected' Write-Output 'PASS build validation: invalid JSON, duplicate agent, duplicate plugin, and leftover placeholders are all rejected'
exit 0
Regular → Executable
View File
File mode changed.
+1
View File
@@ -48,3 +48,4 @@ try {
} finally { } finally {
Remove-Item $work -Recurse -Force -ErrorAction SilentlyContinue Remove-Item $work -Recurse -Force -ErrorAction SilentlyContinue
} }
exit 0
Regular → Executable
View File
File mode changed.
+1
View File
@@ -49,4 +49,5 @@ foreach ($platformSelection in @('1','2')) {
} }
} }
Write-Output 'PASS four platform packages and six PowerShell selections' Write-Output 'PASS four platform packages and six PowerShell selections'
exit 0
View File
File mode changed.
Regular → Executable
View File
File mode changed.
View File
File mode changed.
View File
File mode changed.
View File
File mode changed.
Regular → Executable
View File
File mode changed.