diff --git a/.github/workflows/explorer-release.yml b/.github/workflows/explorer-release.yml index d5ca8707..052bb0b9 100644 --- a/.github/workflows/explorer-release.yml +++ b/.github/workflows/explorer-release.yml @@ -22,44 +22,104 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 + - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 9 + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: 'pnpm' cache-dependency-path: sensibledb-explorer/src/frontend/pnpm-lock.yaml + - name: Install Rust uses: dtolnay/rust-toolchain@stable with: targets: aarch64-apple-darwin + - name: Install frontend dependencies run: | cd sensibledb-explorer/src/frontend pnpm install + - name: Install Tauri CLI run: cargo install tauri-cli --version "^2" + - name: Build .app and .dmg run: | cd sensibledb-explorer cargo tauri build --bundles app,dmg --target aarch64-apple-darwin - - name: Re-sign app bundle + + - name: Import Apple Certificate (if secrets available) + if: env.APPLE_CERTIFICATE != '' + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + run: | + # Create temporary keychain + security create-keychain -p "" build.keychain + security set-keychain-settings build.keychain + + # Decode and import certificate + echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12 + security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 + + # Fix keychain partition list + security set-key-partition-list -S apple-tool:,apple: -k "" build.keychain + + - name: Sign and Notarize App (if secrets available) + if: env.APPLE_ID != '' + env: + APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + APP_DIR="target/aarch64-apple-darwin/release/bundle/macos/SensibleDB Explorer.app" + + # Sign with hardened runtime and entitlements + codesign --deep --force --verify \ + --sign "$APPLE_SIGNING_IDENTITY" \ + --options runtime \ + --entitlements sensibledb-explorer/entitlements.plist \ + "$APP_DIR" + + # Create DMG + hdiutil create -volname "SensibleDB Explorer" \ + -srcfolder "$APP_DIR" \ + -ov -format UDZO \ + "target/aarch64-apple-darwin/release/bundle/dmg/SensibleDB-Explorer.dmg" + + # Notarize (requires Apple Developer account) + xcrun notarytool submit "target/aarch64-apple-darwin/release/bundle/dmg/SensibleDB-Explorer.dmg" \ + --apple-id "$APPLE_ID" \ + --password "$APPLE_PASSWORD" \ + --team-id "$APPLE_TEAM_ID" \ + --wait + + # Staple the notarization ticket + xcrun stapler staple "target/aarch64-apple-darwin/release/bundle/dmg/SensibleDB-Explorer.dmg" + + - name: Re-sign app bundle (fallback without signing) + if: env.APPLE_SIGNING_IDENTITY == '' run: | APP_DIR="target/aarch64-apple-darwin/release/bundle/macos/SensibleDB Explorer.app" codesign --force --deep --sign - --preserve-metadata=entitlements,identifier,flags "$APP_DIR" + - name: Zip .app bundle run: | APP_DIR="target/aarch64-apple-darwin/release/bundle/macos/SensibleDB Explorer.app" zip -r -y "target/aarch64-apple-darwin/release/bundle/macos/SensibleDB-Explorer-aarch64.app.zip" "$APP_DIR" + - name: Release uses: softprops/action-gh-release@v2 with: files: | target/aarch64-apple-darwin/release/bundle/macos/SensibleDB-Explorer-aarch64.app.zip - target/aarch64-apple-darwin/release/bundle/dmg/SensibleDB Explorer_*.dmg + target/aarch64-apple-darwin/release/bundle/dmg/SensibleDB-Explorer.dmg draft: false prerelease: false - generate_release_notes: true + generate_release_notes: true \ No newline at end of file diff --git a/README.md b/README.md index 39e18c30..b336941d 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ If you're looking for a personal app to help you organize and search through you ### Quick Start (Explorer UI) -1. Download SensibleDB Explorer for macOS +1. [Download SensibleDB Explorer for macOS](https://github.com/Sensible-Analytics/SensibleDB/releases) 2. Launch the app 3. Click "Add Folder" and select your documents folder 4. Start chatting with your documents diff --git a/docs/getting-started/agent-guide.md b/docs/getting-started/agent-guide.md new file mode 100644 index 00000000..73ec142f --- /dev/null +++ b/docs/getting-started/agent-guide.md @@ -0,0 +1,181 @@ +# AI Agent Integration Guide + +SensibleDB can serve as a knowledge base and memory store for AI agents. This guide shows how to connect agents to your local SensibleDB instance. + +## Why Use SensibleDB for AI Agents? + +- **Local-First**: No data leaves your machine +- **Graph + Vectors**: Combine relationship reasoning with semantic search +- **Type-Safe Queries**: Catch errors at compile time +- **No External APIs**: Works completely offline + +## Architecture Overview + +``` +┌─────────────────────────────────────────────────────┐ +│ Your AI Agent │ +│ (Claude, GPT, etc.) │ +└────────────────────────┬────────────────────────────┘ + │ HTTP + ▼ +┌─────────────────────────────────────────────────────┐ +│ SensibleDB (localhost:6969) │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Graph │ │ Vector │ │ Query │ │ +│ │ Storage │ │ Storage │ │ Engine │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +└─────────────────────────────────────────────────────┘ +``` + +## Setup + +### 1. Start SensibleDB + +```bash +nexus push dev +``` + +The API is now available at `http://localhost:6969` + +### 2. Define Your Schema + +In `db/schema.hx`: + +```sensibleql +N::Memory { + INDEX id: String, + content: String, + created_at: Date +} + +N::Context { + INDEX id: String, + summary: String +} + +E::RELATED_TO { + From: Memory, + To: Memory +} + +E::PART_OF { + From: Memory, + To: Context +} +``` + +### 3. Write Query Functions + +In `db/queries.hx`: + +```sensibleql +QUERY storeMemory(memory_id: String, content: String) => + mem <- AddN({id: memory_id, content: content, created_at: NOW()}) + RETURN mem + +QUERY storeContext(context_id: String, summary: String) => + ctx <- AddN({id: context_id, summary: summary}) + RETURN ctx + +QUERY linkMemories(from_id: String, to_id: String) => + edge <- AddE({})::From(from_id)::To(to_id) + RETURN edge + +QUERY findRelatedMemories(memory_id: String) => + memory <- N({id: memory_id}) + related <- TRAVERSE memory -[RELATED_TO]-> m + RETURN related + +QUERY semanticSearch(query: String, limit: U32) => + results <- SearchV({vector: Embed(query), limit: limit}) + RETURN results +``` + +## Integration Examples + +### Python Agent + +```python +import requests + +class SensibleDBAgent: + def __init__(self, base_url="http://localhost:6969"): + self.base_url = base_url + + def store_context(self, memory_id: str, content: str): + response = requests.post( + f"{self.base_url}/storeMemory", + json={"memory_id": memory_id, "content": content} + ) + return response.json() + + def retrieve_context(self, query: str, limit: int = 5): + response = requests.post( + f"{self.base_url}/semanticSearch", + json={"query": query, "limit": limit} + ) + return response.json() + + def find_related(self, memory_id: str): + response = requests.post( + f"{self.base_url}/findRelatedMemories", + json={"memory_id": memory_id} + ) + return response.json() + +# Usage +agent = SensibleDBAgent() +agent.store_context("session-001", "User prefers dark mode UI") +results = agent.retrieve_context("user preferences") +``` + +### TypeScript Agent + +```typescript +class SensibleDBAgent { + private baseUrl: string; + + constructor(baseUrl = "http://localhost:6969") { + this.baseUrl = baseUrl; + } + + async storeMemory(memoryId: string, content: string) { + const response = await fetch(`${this.baseUrl}/storeMemory`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ memory_id: memoryId, content }) + }); + return response.json(); + } + + async search(query: string, limit = 5) { + const response = await fetch(`${this.baseUrl}/semanticSearch`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query, limit }) + }); + return response.json(); + } +} + +// Usage +const agent = new SensibleDBAgent(); +await agent.storeMemory("conversation-001", "User asked about pricing"); +const results = await agent.search("pricing information"); +``` + +## MCP Integration *(Coming Soon)* + +The MCP (Model Context Protocol) server integration is coming soon. This will allow direct agent-to-database communication through the MCP protocol. + +## Best Practices + +1. **Batch writes** — Store multiple memories in one request +2. **Use indexes** — Index frequently queried fields +3. **Link related items** — Use edges for relationship tracking +4. **Semantic search** — Combine vector search with graph traversal + +--- + +**Need Help?** +[Open an issue](https://github.com/Sensible-Analytics/SensibleDB/issues) \ No newline at end of file diff --git a/docs/getting-started/developer-guide.md b/docs/getting-started/developer-guide.md new file mode 100644 index 00000000..f92e8cb8 --- /dev/null +++ b/docs/getting-started/developer-guide.md @@ -0,0 +1,124 @@ +# Developer Quick Start Guide + +This guide walks you through setting up SensibleDB for building AI applications. + +## Prerequisites + +- macOS, Linux, or Windows +- Rust 1.75+ (for building from source) +- Basic familiarity with terminal/command line + +## Step 1: Install the CLI + +```bash +# Clone the repository +git clone https://github.com/Sensible-Analytics/SensibleDB.git +cd SensibleDB + +# Build and install the CLI +cargo install --path sensibledb-cli +``` + +Verify installation: +```bash +nexus --version +``` + +## Step 2: Initialize a Project + +```bash +mkdir my-app && cd my-app +nexus init +``` + +This creates: +``` +my-app/ +├── sensibledb.toml # Project config +└── db/ + ├── schema.hx # Define your data schema + └── queries.hx # Write your queries +``` + +## Step 3: Define Your Schema + +Open `db/schema.hx` and define your data model: + +```sensibleql +N::User { + INDEX name: String, + email: String +} + +N::Document { + INDEX title: String, + content: String +} + +E::OWNS { + From: User, + To: Document +} +``` + +## Step 4: Write Queries + +Open `db/queries.hx`: + +```sensibleql +QUERY addUser(name: String, email: String) => + user <- AddN({name: name, email: email}) + RETURN user + +QUERY getUser(name: String) => + user <- N({name: name}) + RETURN user + +QUERY addDocument(title: String, content: String) => + doc <- AddN({title: title, content: content}) + RETURN doc +``` + +## Step 5: Deploy Locally + +```bash +nexus check # Validate schema & queries +nexus push dev # Deploy to local instance +``` + +Your API is now running at `http://localhost:6969` + +## Step 6: Query from Your App + +Use HTTP directly (SDKs coming soon): + +```typescript +// TypeScript +const response = await fetch("http://localhost:6969/addUser", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ name: "John", email: "john@example.com" }) +}); +const result = await response.json(); +``` + +```python +# Python +import requests +response = requests.post( + "http://localhost:6969/getUser", + json={"name": "John"} +) +print(response.json()) +``` + +## Next Steps + +- Learn [SensibleQL syntax](../sensibleql/overview.md) +- Explore [graph traversals](../sensibleql/traversals.md) +- Add [vector search](../sensibleql/vector-operations.md) for semantic queries + +--- + +**Need Help?** +[Open an issue](https://github.com/Sensible-Analytics/SensibleDB/issues) \ No newline at end of file diff --git a/docs/getting-started/explorer-guide.md b/docs/getting-started/explorer-guide.md new file mode 100644 index 00000000..2863bbf6 --- /dev/null +++ b/docs/getting-started/explorer-guide.md @@ -0,0 +1,86 @@ +# SensibleDB Explorer Quick Start + +A step-by-step guide to get started with SensibleDB Explorer — your personal knowledge assistant. + +## What You'll Need + +- A Mac computer (macOS 12.0 or later) +- [SensibleDB Explorer app](https://github.com/Sensible-Analytics/SensibleDB/releases) + +## Step 1: Download and Install + +1. Visit the [Releases page](https://github.com/Sensible-Analytics/SensibleDB/releases) +2. Find the latest `explorer-v*` release +3. Download the `.dmg` file +4. Open the `.dmg` file +5. Drag "SensibleDB Explorer" to your Applications folder +6. Open the app from Applications + +## Step 2: Add Your Documents + +![SensibleDB Explorer Home](assets/explorer-home.png) + +When you first open the app, you'll see the home screen. Follow these steps: + +1. Click **"Add Folder"** button +2. Navigate to the folder containing your documents +3. Select the folder and click **"Open"** + +### Supported Documents + +SensibleDB Explorer can process: +- 📄 PDF files +- 📝 Text files (.txt) +- 📋 Markdown files (.md) +- 📃 Word documents (.doc, .docx) + +## Step 3: Wait for Processing + +![SensibleDB Explorer Graph View](assets/explorer-graph.png) + +After adding a folder, the app will: +1. Scan all documents in the folder +2. Extract text and key information +3. Create embeddings (vector representations) +4. Build a knowledge graph + +This may take a few minutes depending on folder size. You'll see progress in the app. + +## Step 4: Chat with Your Documents + +![SensibleDB Explorer Chat](assets/explorer-chat.png) + +Now you can ask questions about your documents! + +**Example questions to try:** + +- "What is this document about?" +- "Summarize the main points in the meeting notes" +- "Find all mentions of [topic]" +- "What decisions were made in the project folder?" + +## Step 5: Explore Your Knowledge Graph + +![SensibleDB Explorer Report View](assets/explorer-report.png) + +The graph view shows connections between concepts across your documents. You can: +- Click on nodes to see related information +- Zoom in/out to explore different areas +- Click on any item to see more details + +## Tips for Best Results + +1. **Organize your files** — Put related documents in the same folder +2. **Be patient** — First-time indexing takes time +3. **Ask specific questions** — "What did John say about X?" works better than vague queries + +## Offline and Private + +✅ **100% Local-First**: All your data stays on your computer +✅ **Works Offline**: No internet required after installation +✅ **No Cloud**: Nothing is sent to external servers + +--- + +**Need Help?** +[Open an issue](https://github.com/Sensible-Analytics/SensibleDB/issues) or email founders@sensibledb-db.com \ No newline at end of file diff --git a/docs/getting-started/intro.md b/docs/getting-started/intro.md index 97ba4d65..3e99e5f8 100644 --- a/docs/getting-started/intro.md +++ b/docs/getting-started/intro.md @@ -12,7 +12,7 @@ SensibleDB makes it easy to build all components needed for an AI application in Download the desktop app to turn your documents into a searchable knowledge base: -1. Download for macOS +1. [Download SensibleDB Explorer for macOS](https://github.com/Sensible-Analytics/SensibleDB/releases) 2. Launch and add your documents folder 3. Chat with your documents in plain English diff --git a/docs/index.md b/docs/index.md index 63b484a7..67f4a300 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,7 +31,7 @@ Built in Rust with LMDB as its storage engine — like SQLite for knowledge grap ### Get Started -1. Download SensibleDB Explorer for macOS +1. [Download SensibleDB Explorer for macOS](https://github.com/Sensible-Analytics/SensibleDB/releases) 2. Launch the app 3. Click "Add Folder" → select your documents folder 4. Start chatting! diff --git a/mkdocs.yml b/mkdocs.yml index d4ad8f34..30a562a1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -45,11 +45,13 @@ markdown_extensions: nav: - Home: . - For Non-Technical Users: - - Explorer Quick Start: getting-started/intro.md + - Explorer Quick Start: getting-started/explorer-guide.md - For Developers: - Getting Started: - Overview: getting-started/intro.md - Installation: getting-started/installation.md + - Quick Start: getting-started/developer-guide.md + - AI Agent Integration: getting-started/agent-guide.md - SensibleQL: - Overview: sensibleql/overview.md - Schema Definition: sensibleql/schema-definition.md diff --git a/sensibledb-explorer/entitlements.plist b/sensibledb-explorer/entitlements.plist new file mode 100644 index 00000000..154a7b68 --- /dev/null +++ b/sensibledb-explorer/entitlements.plist @@ -0,0 +1,18 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.network.client + + com.apple.security.files.user-selected.read-write + + com.apple.security.files.bookmarks.app-scope + + + \ No newline at end of file diff --git a/sensibledb-explorer/tauri.conf.json b/sensibledb-explorer/tauri.conf.json index f728bae2..b862aede 100644 --- a/sensibledb-explorer/tauri.conf.json +++ b/sensibledb-explorer/tauri.conf.json @@ -2,7 +2,7 @@ "$schema": "https://schema.tauri.app/config/2", "productName": "SensibleDB Explorer", "version": "0.1.0", - "identifier": "com.sensibledbdb.explorer", + "identifier": "com.sensibledb.explorer", "build": { "beforeDevCommand": "pnpm dev", "beforeBuildCommand": "pnpm build", @@ -26,12 +26,12 @@ } ], "security": { - "csp": "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; connect-src 'self' http://localhost:*" + "csp": "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; connect-src 'self' http://localhost:* https://localhost:*" } }, "bundle": { "active": true, - "targets": "all", + "targets": ["app", "dmg"], "icon": [ "icons/32x32.png", "icons/128x128.png", @@ -41,10 +41,17 @@ ], "macOS": { "frameworks": [], - "minimumSystemVersion": "10.13", + "minimumSystemVersion": "12.0", "exceptionDomain": "", - "signingIdentity": null, - "entitlements": null + "signingIdentity": "-", + "entitlements": "./entitlements.plist", + "providerShortName": null, + "createDmgArtifacts": true + }, + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "" } }, "plugins": {}