Skills engine v0.1 + multi-channel infrastructure (#307)
* 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>
This commit is contained in:
84
.github/workflows/skill-tests.yml
vendored
Normal file
84
.github/workflows/skill-tests.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
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
|
||||
Reference in New Issue
Block a user