Skip to content

Commit a6336c0

Browse files
feat: Synapse Universal Context Broker (#1)
* Add Synapse design doc and update CLAUDE.md for feature handoff - docs/synapse-design.md: Full architecture spec for Universal Context Broker - CLAUDE.md: Synapse section with new key files, resource classes, and conventions - Branch: feature/synapse Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Synapse phases 1-3: schema, resource classes, and tests - Add SynapseEntry table to schema.graphql with HNSW vector index - Add SynapseEntry, SynapseSearch, SynapseIngest, SynapseEmit to resources.js - Add classifySynapseEntry, synapseparsers, synapseEmitters helpers - Update existing tests to include SynapseEntry in harperdb mock - Add 4 new Synapse test files (77 tests total, all pass) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Synapse CLI (bin/synapse.js) with sync, emit, search, watch, status - Zero-dependency Node.js CLI using process.argv and fetch - sync: discovers CLAUDE.md, .cursor/rules/*.mdc, .windsurf/ and POSTs to SynapseIngest - emit: queries SynapseEmit and prints or writes files (--write flag) - search: semantic search via SynapseSearch with --limit and --type filters - watch: fs.watch with 2s debounce for auto-sync on file changes - status: shows entry counts by type and source from a search sample - Add "bin" field to package.json - Add SYNAPSE_ENDPOINT, SYNAPSE_PROJECT, SYNAPSE_AUTH to .env.example Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Synapse documentation (Phase 5) - README.md: add Synapse section with architecture diagram, context types, CLI examples, API endpoints table, project structure, and env vars - docs/architecture.md: add Synapse data flow diagram and SynapseEntry schema table - CLAUDE.md: update key files list, test count (35 → 77), remove branch qualifier Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add linting, formatting, and release tooling - dprint: code formatter (tabs, single quotes, useBraces:always) for JS, JSON, Markdown, GraphQL - oxlint: fast linter with test-file overrides for no-new-array and require-yield - semantic-release: automated versioning and GitHub releases from conventional commits - commitlint: enforce conventional commit format - GitHub Actions: ci.yml (lint+test on all branches) and release.yml (release on main) - New scripts: format:check, format:fix, format:staged, lint:check, lint:fix, test:watch, test:coverage, commitlint - Fix lint warnings in resources.js: prefix unused embedding and projectId params with _ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address Synapse review issues - Add VALID_EMIT_TARGETS set; reject slack/manual as emit targets, accept markdown - Push single-type filter to server-side search conditions in SynapseEmit - Deduplicate ingested entries using deterministic content hash as record ID - Fix parseClaudeCode/parseWindsurf to preserve preamble before first ## heading - Update engines.node to >=22.0.0 (required for --experimental-test-module-mocks) - Combine table destructures into single line - Add beforeEach mock resets to synapse-search and synapse-emit test files - Broaden CLI status command query; document as approximate Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b8f78df commit a6336c0

27 files changed

Lines changed: 10332 additions & 669 deletions

.env.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,9 @@ VOYAGE_API_KEY=pa-xxxxx
2424
# See docs/slack-app-setup.md for step-by-step instructions
2525
SLACK_SIGNING_SECRET=xxxxx
2626
SLACK_BOT_TOKEN=xoxb-xxxxx
27+
28+
# --- Synapse CLI (for context broker commands) ---
29+
# See docs/synapse-design.md for usage instructions
30+
SYNAPSE_ENDPOINT=https://your-cluster.your-org.harperfabric.com
31+
SYNAPSE_PROJECT=your-project-name
32+
SYNAPSE_AUTH=Basic dXNlcjpwYXNz

.github/workflows/ci.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ['**']
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
name: Lint & Test
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version-file: .nvmrc
19+
cache: npm
20+
21+
- run: npm ci
22+
23+
- name: Format check
24+
run: npm run format:check
25+
26+
- name: Lint
27+
run: npm run lint:check
28+
29+
- name: Test
30+
run: npm test

.github/workflows/release.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
issues: write
10+
pull-requests: write
11+
12+
jobs:
13+
release:
14+
name: Release
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
persist-credentials: false
21+
22+
- uses: actions/setup-node@v4
23+
with:
24+
node-version-file: .nvmrc
25+
cache: npm
26+
27+
- run: npm ci
28+
29+
- name: Test
30+
run: npm test
31+
32+
- name: Release
33+
env:
34+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35+
run: npx semantic-release

.oxlintrc.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "./node_modules/oxlint/configuration_schema.json",
3+
"ignorePatterns": [
4+
"node_modules/"
5+
],
6+
"rules": {},
7+
"overrides": [
8+
{
9+
"files": ["test/**"],
10+
"rules": {
11+
"unicorn/no-new-array": "off",
12+
"require-yield": "off"
13+
}
14+
}
15+
]
16+
}

.releaserc.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"branches": [
3+
"main"
4+
],
5+
"plugins": [
6+
[
7+
"@semantic-release/commit-analyzer",
8+
{
9+
"preset": "conventionalcommits",
10+
"releaseRules": [
11+
{ "breaking": true, "release": "major" },
12+
{ "type": "feat", "release": "minor" },
13+
{ "type": "*", "release": "patch" }
14+
],
15+
"parserOpts": {
16+
"noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"]
17+
}
18+
}
19+
],
20+
"@semantic-release/release-notes-generator",
21+
[
22+
"@semantic-release/npm",
23+
{ "npmPublish": false }
24+
],
25+
[
26+
"@semantic-release/git",
27+
{
28+
"assets": ["package.json", "package-lock.json"]
29+
}
30+
],
31+
"@semantic-release/github"
32+
]
33+
}

CLAUDE.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,47 @@ An agent-agnostic AI memory system using Harper Fabric as the vector database an
1414

1515
## Key Files
1616

17-
- `resources.js` - Core application: SlackWebhook, MemorySearch, MemoryTable classes + classifyMessage, generateEmbedding, verifySlackSignature helpers
18-
- `schema.graphql` - Memory table with HNSW vector index (no @export since we extend it)
17+
- `resources.js` - Core application: SlackWebhook, MemorySearch, MemoryTable + all Synapse resource classes + helpers
18+
- `schema.graphql` - Memory and SynapseEntry tables with HNSW vector indexes (no @export since we extend them)
1919
- `config.yaml` - Harper app config (loadEnv, REST, schema, resource files)
2020
- `.env.example` - All required environment variables documented
21+
- `bin/synapse.js` - Synapse CLI: sync, emit, search, watch, status commands
2122

2223
## Development
2324

2425
```bash
2526
npm run dev # Start locally on port 9926
26-
npm test # Run all 35 tests
27+
npm test # Run all 77 tests
2728
npm run deploy # Deploy to Harper Fabric
2829
```
2930

3031
## Architecture
3132

3233
Slack webhook -> classify (Claude) + embed (Voyage AI) -> store in Memory table -> query via MCP from Claude Desktop/Cursor.
3334

35+
## Synapse
36+
37+
Universal Context Broker — ingests development context from any AI tool (Claude Code, Cursor, Windsurf, Copilot) and emits it in any other tool's native format. Full design spec: `docs/synapse-design.md`.
38+
39+
### New Key Files
40+
41+
- `bin/synapse.js` - CLI: sync, emit, search, watch, status commands
42+
- `test/synapse-*.test.js` - Tests for classify, search, ingest, emit
43+
44+
### New Resource Classes (in resources.js)
45+
46+
- `SynapseEntry` - Table extension (strips embeddings, same pattern as MemoryTable)
47+
- `SynapseSearch` - Semantic search with mandatory `projectId` scoping
48+
- `SynapseIngest` - Parses tool-native formats into SynapseEntry records
49+
- `SynapseEmit` - Formats SynapseEntry records into tool-native output
50+
51+
### Conventions
52+
53+
- SynapseEntry table follows same patterns as Memory (HNSW vector index, classification via Claude Haiku, embeddings via Voyage AI)
54+
- Use renamed import: `const { SynapseEntry: SynapseEntryBase } = tables;`
55+
- All Synapse queries must filter on `projectId`
56+
- Default status filter is `active` (excludes superseded/archived)
57+
3458
## Agent Skills
3559

3660
Skills from `harperfast/skills` are tracked in `skills-lock.json` and installed into `.agents/skills/` (git-ignored). Refer to the relevant skill rules when making changes:

CONTRIBUTING.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ npm test
5757

5858
Tests live in `test/` alongside the code they cover:
5959

60-
| File | Covers |
61-
|------|--------|
62-
| `classify.test.js` | `classifyMessage()` |
63-
| `embedding.test.js` | `generateEmbedding()` |
64-
| `webhook.test.js` | `SlackWebhook`, `verifySlackSignature()` |
65-
| `search.test.js` | `MemorySearch` |
60+
| File | Covers |
61+
| ------------------- | ---------------------------------------- |
62+
| `classify.test.js` | `classifyMessage()` |
63+
| `embedding.test.js` | `generateEmbedding()` |
64+
| `webhook.test.js` | `SlackWebhook`, `verifySlackSignature()` |
65+
| `search.test.js` | `MemorySearch` |
6666

6767
## Submitting a Pull Request
6868

@@ -76,6 +76,7 @@ Please keep PRs focused — one feature or fix per PR.
7676
## Reporting Issues
7777

7878
Open an issue on GitHub with:
79+
7980
- A clear description of the problem
8081
- Steps to reproduce
8182
- Your Node.js version (`node --version`)

0 commit comments

Comments
 (0)