From 8c0fc89bac0ee08ae897093e5ee42bdcf8999ad3 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sat, 24 Oct 2026 19:52:36 +0400 Subject: [PATCH] =?UTF-8?q?fix(dsh):=20--openspec=20=D0=B2=D0=BE=D0=B7?= =?UTF-8?q?=D0=B2=D1=80=D0=B0=D1=89=D0=B0=D0=B5=D1=82=201=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=D0=B5=20openspec?= =?UTF-8?q?=20init=20(#42)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: DeepSeek Harness --- dsh/install.sh | 5 ++++- dsh/tests/openspec.test.mjs | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/dsh/install.sh b/dsh/install.sh index 231acbf..093cc16 100755 --- a/dsh/install.sh +++ b/dsh/install.sh @@ -292,7 +292,10 @@ install_openspec() { echo "FAIL: $dir has no openspec/ root; run: openspec init --tools agents" >&2 return 1 fi - ( cd "$dir" && openspec init --tools agents ) + if ! ( cd "$dir" && openspec init --tools agents ); then + echo "FAIL: openspec init --tools agents failed in $dir" >&2 + return 1 + fi echo "ok: openspec agents adapter in $dir" } diff --git a/dsh/tests/openspec.test.mjs b/dsh/tests/openspec.test.mjs index 4477d49..ad71c8b 100644 --- a/dsh/tests/openspec.test.mjs +++ b/dsh/tests/openspec.test.mjs @@ -110,3 +110,44 @@ test('--openspec refuses a project without an openspec root', () => { cleanup(home) } }) + +test('--openspec fails when openspec init fails', () => { + const home = tempDir() + try { + const project = join(home, 'project') + mkdirSync(join(project, 'openspec'), { recursive: true }) + const bin = join(home, 'bin') + write(join(bin, 'openspec'), '#!/bin/sh\nexit 1\n') + chmodSync(join(bin, 'openspec'), 0o755) + const env = { ...process.env, HOME: home, DSH_HOME: join(home, '.dsh'), PATH: `${bin}:${process.env.PATH}` } + const run = spawnSync('bash', [script, '--openspec'], { cwd: project, env, encoding: 'utf8' }) + assert.notEqual(run.status, 0) + assert.doesNotMatch(run.stdout, /ok: openspec agents adapter/) + assert.match(run.stderr, /FAIL/) + } finally { + cleanup(home) + } +}) + +test('--openspec fails without the openspec CLI', () => { + const home = tempDir() + try { + const project = join(home, 'project') + mkdirSync(join(project, 'openspec'), { recursive: true }) + const bin = join(home, 'bin') + mkdirSync(bin, { recursive: true }) + symlinkSync(process.execPath, join(bin, 'node')) + // openspec ставится в /opt/homebrew/bin; здесь только системные каталоги — CLI не найден + const env = { + ...process.env, + HOME: home, + DSH_HOME: join(home, '.dsh'), + PATH: `${bin}:/usr/bin:/bin:/usr/sbin:/sbin`, + } + const run = spawnSync('bash', [script, '--openspec'], { cwd: project, env, encoding: 'utf8' }) + assert.notEqual(run.status, 0) + assert.match(run.stdout + run.stderr, /FAIL: openspec CLI not found/) + } finally { + cleanup(home) + } +})