* refactor: multi-channel infrastructure with explicit channel/is_group tracking - Add channels[] array and findChannel() routing in index.ts, replacing hardcoded whatsapp.* calls with channel-agnostic callbacks - Add channel TEXT and is_group INTEGER columns to chats table with COALESCE upsert to protect existing values from null overwrites - is_group defaults to 0 (safe: unknown chats excluded from groups) - WhatsApp passes explicit channel='whatsapp' and isGroup to onChatMetadata - getAvailableGroups filters on is_group instead of JID pattern matching - findChannel logs warnings instead of silently dropping unroutable JIDs - Migration backfills channel/is_group from JID patterns for existing DBs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: skills engine v0.1 — deterministic skill packages with rerere resolution Three-way merge engine for applying skill packages on top of a core codebase. Skills declare which files they add/modify, and the engine uses git merge-file for conflict detection with git rerere for automatic resolution of previously-seen conflicts. Key components: - apply: three-way merge with backup/rollback safety net - replay: clean-slate replay for uninstall and rebase - update: core version updates with deletion detection - rebase: bake applied skills into base (one-way) - manifest: validation with path traversal protection - resolution-cache: pre-computed rerere resolutions - structured: npm deps, env vars, docker-compose merging - CI: per-skill test matrix with conflict detection 151 unit tests covering merge, rerere, backup, replay, uninstall, update, rebase, structured ops, and edge cases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add Discord and Telegram skill packages Skill packages for adding Discord and Telegram channels to NanoClaw. Each package includes: - Channel implementation (add/src/channels/) - Three-way merge targets for index.ts, config.ts, routing.test.ts - Intent docs explaining merge invariants - Standalone integration tests - manifest.yaml with dependency/conflict declarations Applied via: npx tsx scripts/apply-skill.ts .claude/skills/add-discord These are inert until applied — no runtime impact. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * remove unused docs (skills-system-status, implementation-guide) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
85 lines
2.4 KiB
YAML
85 lines
2.4 KiB
YAML
name: Skill Combination Tests
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
paths:
|
|
- 'skills-engine/**'
|
|
- '.claude/skills/**'
|
|
- 'src/**'
|
|
|
|
jobs:
|
|
generate-matrix:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
matrix: ${{ steps.matrix.outputs.matrix }}
|
|
has_entries: ${{ steps.matrix.outputs.has_entries }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 20
|
|
cache: npm
|
|
- run: npm ci
|
|
- name: Generate overlap matrix
|
|
id: matrix
|
|
run: |
|
|
MATRIX=$(npx tsx scripts/generate-ci-matrix.ts)
|
|
{
|
|
echo "matrix<<MATRIX_EOF"
|
|
echo "$MATRIX"
|
|
echo "MATRIX_EOF"
|
|
} >> "$GITHUB_OUTPUT"
|
|
if [ "$MATRIX" = "[]" ]; then
|
|
echo "has_entries=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "has_entries=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
test-combinations:
|
|
needs: generate-matrix
|
|
if: needs.generate-matrix.outputs.has_entries == 'true'
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
entry: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 20
|
|
cache: npm
|
|
- run: npm ci
|
|
|
|
- name: Initialize nanoclaw dir
|
|
run: npx tsx -e "import { initNanoclawDir } from './skills-engine/index.js'; initNanoclawDir();"
|
|
|
|
- name: Apply skills in sequence
|
|
run: |
|
|
for skill in $(echo '${{ toJson(matrix.entry.skills) }}' | jq -r '.[]'); do
|
|
echo "Applying skill: $skill"
|
|
npx tsx scripts/apply-skill.ts ".claude/skills/$skill"
|
|
done
|
|
|
|
- name: Run skill tests
|
|
run: npx vitest run --config vitest.skills.config.ts
|
|
|
|
skill-tests-summary:
|
|
needs: [generate-matrix, test-combinations]
|
|
if: always()
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Report result
|
|
run: |
|
|
if [ "${{ needs.generate-matrix.outputs.has_entries }}" = "false" ]; then
|
|
echo "No overlapping skills found. Skipped combination tests."
|
|
exit 0
|
|
fi
|
|
if [ "${{ needs.test-combinations.result }}" = "success" ]; then
|
|
echo "All skill combination tests passed."
|
|
else
|
|
echo "Some skill combination tests failed."
|
|
exit 1
|
|
fi
|