diff --git a/dsh/install.sh b/dsh/install.sh index 53f1b7a..cf97ab3 100755 --- a/dsh/install.sh +++ b/dsh/install.sh @@ -120,6 +120,16 @@ check() { else echo "WARN: subagent maxDepth is not 2 in any profile patch; SDD mode 2 is unavailable" >&2 fi + if command -v openspec >/dev/null 2>&1; then + echo "ok: openspec $(openspec --version 2>/dev/null | head -1)" + else + echo "WARN: openspec not found; OpenSpec workflows are unavailable" >&2 + fi + if [ -f "$ROOT/.agents/skills/openspec-propose/SKILL.md" ]; then + echo "ok: openspec agents skills ($ROOT/.agents/skills)" + else + echo "WARN: .agents/skills missing; run --openspec in the project" >&2 + fi if [ -f "$DSH_HOME/skills/using-superpowers/SKILL.md" ]; then echo "ok: dsh skills ($DSH_HOME/skills)" elif superpowers_skills >/dev/null 2>&1; then diff --git a/dsh/tests/openspec.test.mjs b/dsh/tests/openspec.test.mjs index 3e7ca88..1399f34 100644 --- a/dsh/tests/openspec.test.mjs +++ b/dsh/tests/openspec.test.mjs @@ -1,10 +1,13 @@ import assert from 'node:assert/strict' -import { existsSync, readFileSync } from 'node:fs' +import { spawnSync } from 'node:child_process' +import { chmodSync, existsSync, readFileSync } from 'node:fs' import { dirname, join } from 'node:path' import test from 'node:test' import { fileURLToPath } from 'node:url' +import { cleanup, tempDir, write } from './helpers.mjs' const here = dirname(fileURLToPath(import.meta.url)) +const script = join(here, '..', 'install.sh') const root = join(here, '..', '..') const agentsSkills = join(root, '.agents', 'skills') const NAMES = [ @@ -26,3 +29,32 @@ test('repository ships six agents skills for DSH', () => { assert.match(text, /description: .*openspec/i, `${name}: description must mention openspec`) } }) + +test('install.sh --check reports the openspec CLI and the agents skills', () => { + const home = tempDir() + try { + const bin = join(home, 'bin') + write(join(bin, 'openspec'), '#!/bin/sh\n[ "$1" = "--version" ] && echo 1.13.1\nexit 0\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, '--check'], { env, encoding: 'utf8' }) + assert.equal(run.status, 0, run.stderr) + assert.match(run.stdout, /ok: openspec 1\.13\.1/) + assert.match(run.stdout, /ok: openspec agents skills \(/) + } finally { + cleanup(home) + } +}) + +test('install.sh --check warns but does not fail without the openspec CLI', () => { + const home = tempDir() + try { + const bin = join(home, 'bin') + const env = { ...process.env, HOME: home, DSH_HOME: join(home, '.dsh'), PATH: bin } + const run = spawnSync('bash', [script, '--check'], { env, encoding: 'utf8' }) + assert.match(run.stdout + run.stderr, /WARN: openspec not found/) + assert.equal(run.status, 0) + } finally { + cleanup(home) + } +})