Compare commits

..
9 Commits
Author SHA1 Message Date
fraujulian c2bf5888d0 test(telemetry): use Git Bash on Windows
CI / Capabilities and shell quality (push) Successful in 11s
CI / Python tests and compilation (push) Successful in 11s
CI / PowerShell tests on Ubuntu (push) Failing after 9s
CI / CI configuration security checks (push) Successful in 3s
CI / Build and inspect generated packages (push) Successful in 6s
CI / Qwen retrieval integration (push) Failing after 15m1s
CI / Bash integration and installation guards (push) Successful in 16s
CI / Installed client configuration smoke tests (push) Failing after 26s
2026-09-18 11:59:06 +02:00
fraujulian 43e1487bb3 test(session): stage command helpers 2026-09-18 11:59:05 +02:00
fraujulian b6f111977d test(update): stage command fixture 2026-09-18 11:59:05 +02:00
fraujulian efec24a4eb test(inventory): load relocated helper 2026-09-18 11:59:05 +02:00
fraujulian 797e53ff3e test(extensions): load relocated helper 2026-09-18 11:59:05 +02:00
fraujulian 28a8bd70eb test(install): use relocated command paths 2026-09-18 11:59:04 +02:00
fraujulian dffc956f27 fix(extensions): preserve foreign skill files 2026-09-18 11:59:04 +02:00
fraujulian 72338270d0 fix(capabilities): fall back to python3 2026-09-18 11:59:04 +02:00
fraujulian 25a9579eee fix(build): locate session check 2026-09-18 11:59:04 +02:00
9 changed files with 50 additions and 16 deletions

No files matched your search

+1 -1
View File
@@ -85,7 +85,7 @@ quote_toml() {
printf '"%s"' "$value"
}
session_output=$(bash "$shared/hooks/scripts/tests/test-session-config.sh" "$root") || { printf '%s\n' "$session_output" >&2; exit 1; }
session_output=$(bash "$shared/hooks/scripts/test-session-config.sh" "$root") || { printf '%s\n' "$session_output" >&2; exit 1; }
if [ "$summary" = true ]; then
printf '%s\n' "$session_output" | sed '/^PASS session configuration$/d'
else
+7 -4
View File
@@ -9,11 +9,14 @@ function Version-AtLeast([string]$version, [version]$minimum) { try { return ([v
function Check-Version([string]$name, [string]$version, [version]$minimum) { if (Version-AtLeast $version $minimum) { Pass "$name $version (minimum $minimum)" } else { Fail "$name $version is below minimum $minimum" } }
Check-Version 'PowerShell' $PSVersionTable.PSVersion.ToString() ([version]'5.1')
Require-Command jq; Require-Command python
if (Get-Command python -ErrorAction SilentlyContinue) {
$pythonVersion = (& python --version 2>$null | Select-Object -First 1) -replace '^Python\s+', ''
if ($LASTEXITCODE -eq 0) { Check-Version 'Python' $pythonVersion ([version]'3.11') } else { Fail 'Python 3.11 or newer is required' }
Require-Command jq
$pythonVersion = $null
foreach ($python in @('python', 'python3')) {
if (-not (Get-Command $python -ErrorAction SilentlyContinue)) { continue }
$candidate = (& $python --version 2>$null | Select-Object -First 1) -replace '^Python\s+', ''
if ($LASTEXITCODE -eq 0) { $pythonVersion = $candidate; break }
}
if ($null -ne $pythonVersion) { Check-Version 'Python' $pythonVersion ([version]'3.11') } else { Fail 'Python 3.11 or newer is required' }
if ($failed) { Write-Error 'Capability check: FAIL'; exit 1 }
Write-Output 'Capability check: PASS'
+27 -1
View File
@@ -229,9 +229,35 @@ class Manager:
self.command(arguments)
self.cache[client].pop(selector, None)
elif record['kind'] == 'skill':
empty_candidates = set()
for relative, expected in list(record['files'].items()):
path = safe_path(self.home, relative)
if path.exists():
if not path.is_file() or digest(path) != expected:
print(f'WARN Preserving modified skill file: {relative}')
continue
path.unlink()
parent = path.parent
directory = safe_path(self.home, record['directory'])
while parent != directory.parent:
empty_candidates.add(parent)
parent = parent.parent
del record['files'][relative]
self.save()
directory = safe_path(self.home, record['directory'])
if directory.exists():
shutil.rmtree(directory)
for path in sorted(empty_candidates, key=lambda p: len(p.parts), reverse=True):
if path.is_dir() and not path.is_symlink():
try:
path.rmdir()
except OSError:
pass
try:
directory.rmdir()
except OSError:
pass
if record['files']:
return
else:
package = record['package']
self.command(['npm', 'uninstall', '--global', package])
+6 -4
View File
@@ -154,6 +154,8 @@ class InstallOptionsTests(unittest.TestCase):
with self.subTest(shell=kind), tempfile.TemporaryDirectory() as directory:
root = Path(directory) / 'repo'
scripts = root / 'scripts'
commands = scripts / 'commands'
commands.mkdir(parents=True)
shutil.copytree(ROOT / 'scripts/lib', scripts / 'lib', ignore=shutil.ignore_patterns('__pycache__'))
home = Path(directory) / 'home'
home.mkdir()
@@ -168,10 +170,10 @@ class InstallOptionsTests(unittest.TestCase):
(package / ('config.toml' if client == 'codex' else 'settings.json')).write_text(config)
suffix = 'ps1' if kind == 'powershell' else 'sh'
for name in ('install', 'update'):
content = (ROOT / 'scripts' / (name + '.' + suffix)).read_text(encoding='utf-8-sig')
content = (ROOT / 'scripts/commands' / (name + '.' + suffix)).read_text(encoding='utf-8-sig')
content = content.replace("[Environment]::GetFolderPath('UserProfile')", '$env:TEST_INSTALL_HOME')
(scripts / (name + '.' + suffix)).write_text(content)
(scripts / ('build.' + suffix)).write_text('param([switch]$Summary)' if kind == 'powershell' else 'exit 0\n')
(commands / (name + '.' + suffix)).write_text(content)
(commands / ('build.' + suffix)).write_text('param([switch]$Summary)' if kind == 'powershell' else 'exit 0\n')
if kind == 'powershell':
(scripts / 'lib/plugins.ps1').write_text(
'function Select-ConfiguredPlugins { @{Selected=@(); Deselected=@()} }\n'
@@ -185,7 +187,7 @@ class InstallOptionsTests(unittest.TestCase):
'run_plugin_command() { printf "CLI-MOCK %s\\n" "$2"; }\n')
environment = dict(os.environ, HOME=home.as_posix(), TEST_INSTALL_HOME=str(home))
for name, quick, answers in [('install', False, 'y\nn\nn\nn\n'), ('update', True, '')]:
entry = str(scripts / (name + '.' + suffix))
entry = str(commands / (name + '.' + suffix))
command = ([executable, '-NoProfile', '-File', entry, '-Shell', 'Bash', '-Client', 'Both', '-Summary']
if kind == 'powershell' else [executable, entry, '--shell', 'bash', '--client', 'both', '--summary'])
if quick:
+1 -1
View File
@@ -9,7 +9,7 @@ import unittest
from unittest.mock import patch
spec = importlib.util.spec_from_file_location('extensions', Path(__file__).parent / 'lib' / 'managed-extensions.py')
spec = importlib.util.spec_from_file_location('extensions', Path(__file__).parents[2] / 'scripts/lib/managed-extensions.py')
extensions = importlib.util.module_from_spec(spec)
spec.loader.exec_module(extensions)
+1 -1
View File
@@ -4,7 +4,7 @@ from tempfile import TemporaryDirectory
import unittest
SPEC = importlib.util.spec_from_file_location('prompt_inventory', Path(__file__).parent / 'lib/prompt-inventory.py')
SPEC = importlib.util.spec_from_file_location('prompt_inventory', Path(__file__).parents[2] / 'scripts/lib/prompt-inventory.py')
MODULE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MODULE)
+1 -1
View File
@@ -114,7 +114,7 @@ class SelectionTests(unittest.TestCase):
original = self.path.read_bytes()
source = (ROOT / 'scripts/commands/update.ps1').read_text(encoding='utf-8-sig')
source = source.replace("[Environment]::GetFolderPath('UserProfile')", '$env:TEST_SELECTION_HOME')
with tempfile.NamedTemporaryFile(mode='w', suffix='.tmp.ps1', dir=ROOT / 'scripts',
with tempfile.NamedTemporaryFile(mode='w', suffix='.tmp.ps1', dir=ROOT / 'scripts/commands',
encoding='utf-8', delete=False) as stream:
stream.write(source)
entry = Path(stream.name)
+2 -2
View File
@@ -78,9 +78,9 @@ class SessionStateHookTests(unittest.TestCase):
base = Path(directory)
repository = base / 'repository'
shutil.copytree(ROOT / 'shared/hooks/scripts', repository / 'shared/hooks/scripts')
(repository / 'scripts').mkdir()
(repository / 'scripts/commands').mkdir(parents=True)
for filename in ('session-state.ps1', 'session-state.sh'):
shutil.copy(ROOT / 'scripts' / filename, repository / 'scripts' / filename)
shutil.copy(ROOT / 'scripts/commands' / filename, repository / 'scripts/commands' / filename)
workspace = base / 'workspace ü'
workspace.mkdir()
environment = dict(os.environ, TASK_WORKSPACE=str(workspace),
+4 -1
View File
@@ -13,12 +13,15 @@ ROOT = Path(__file__).resolve().parent.parent.parent
class TelemetryTests(unittest.TestCase):
def test_bash_record_disable_and_summary(self):
bash = shutil.which('bash')
if os.name == 'nt':
candidate = Path(os.environ.get('ProgramFiles', 'C:/Program Files')) / 'Git/bin/bash.exe'
bash = str(candidate) if candidate.exists() else None
if not bash:
self.skipTest('Bash unavailable')
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
script = root / 'scripts/commands/telemetry.sh'
script.parent.mkdir()
script.parent.mkdir(parents=True)
shutil.copy(ROOT / 'scripts/commands/telemetry.sh', script)
env = dict(os.environ, AI_CONFIG_TELEMETRY='1')
result = subprocess.run([bash, str(script), 'record', 'subagent-stop', '--role', 'reviewer', '--filesRead', '3', '--outcome', 'findings'], env=env, capture_output=True, text=True)