Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.claude
CLAUDE.md

# Node
node_modules
dist
*.tsbuildinfo

# Env / credentials
.env
.env.*
!.env.example
198 changes: 198 additions & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# Alignbase Plugin Spec (v0.1, draft)

This is the contract between Alignbase and a plugin. If you are building a
plugin, this document is everything you need to know about how Alignbase
expects you to behave.

---

## 1. What a Plugin Is

A plugin is a standalone process — CLI, worker, scheduled job, or hosted
service — that:

1. Authenticates to Alignbase as a distinct identity.
2. Reads and/or writes context documents through Alignbase's MCP server.
3. Operates only within the tags and permissions a user has granted it.
4. Emits an audit event for every write.

A plugin is **not** a separate context store. It must not cache published
context as its own source of truth. State a plugin needs to remember
(cursors, last-synced commit SHAs, dedupe hashes) lives in the plugin's own
storage, not in Alignbase context documents.

---

## 2. Plugin Manifest

Every plugin ships a `plugin.json` at its package root.

```json
{
"spec_version": 1,
"name": "github-sync",
"version": "0.1.0",
"display_name": "GitHub Sync",
"description": "Drafts repo README and /docs markdown into Alignbase.",
"publisher": "alignbase",
"homepage": "https://github.com/Sunpeak-AI/alignbase-platform",
"icons": {
"48": "./icons/icon-48.png",
"128": "./icons/icon-128.png"
},
"entry": "dist/index.js",
"runtime": "node>=20",
"permissions": ["create_context", "edit_context", "create_tags"],
"tag_scopes": ["github", "docs"],
"config_schema": "./config.schema.json",
"triggers": ["manual", "schedule", "webhook"]
}
```

- `spec_version` pins the manifest schema. The host uses this to apply
the right validation rules. Bump only when the schema changes in a
breaking way.
- `icons` is optional but recommended. Multiple sizes let the dashboard
pick the right one for install screens, list views, and consent
dialogs.
- `permissions` lists the **capabilities** the plugin needs:
`read_context` (implicit), `edit_context`, `create_context`,
`publish_context`, `create_tags`. Modeled on Chrome's `permissions`.
- `tag_scopes` is the **maximum** set of tags the plugin will touch.
The installing user can narrow at consent time but cannot widen.
Modeled on Chrome's `host_permissions` — capabilities and scope are
separate so the consent screen can present them independently.
- Most plugins should not request `publish_context`. Humans approve
publication.
- `triggers` declares how the plugin runs. The host picks one at install
time.

---

## 3. MCP Tools

A plugin may call any of these tools on `https://app.alignbase.ai/mcp`,
subject to the permissions in its grant:

- `get_current_context`
- `list_context_documents`
- `read_context_document`
- `create_context_document`
- `write_context_document`
- `publish_context_document`

### Document shape

```ts
type ContextDocument = {
id: string;
title: string;
tags: string[];
content: string;

current_version: number;
latest_version: number;
published_version: number | null;

publication_status: "draft" | "published";
has_unpublished_changes: boolean;
status: "live" | "stale" | "expired";

expires_at: string | null;
review_by: string | null;

can_read: boolean;
can_edit: boolean;
can_publish: boolean;

created_at: string;
updated_at: string;
};
```

### Versioning rules

- Every edit produces a new `latest_version`. Other clients do not see
edits until a `published_version` is promoted.
- Always read `latest` before editing; pass the returned version as
`expected_version` on write to avoid clobbering concurrent edits.

---

## 4. Authentication

Plugins authenticate via OAuth 2.1 + PKCE against `app.alignbase.ai`. This
is the same flow Alignbase uses for connected agents today.

1. The plugin registers (or is registered) and receives an OAuth client ID
of the form `ab_client_<base64url>`.
2. On first run, the plugin opens a browser, the user consents, and the
plugin receives an access token + refresh token.
3. The plugin attaches the access token on every MCP call.
4. The server validates the token against the grant (actions × tags) on
every request.
5. The user can revoke the grant from the Alignbase dashboard; subsequent
calls return `401`.

Tokens are stored at `~/.alignbase/<plugin-name>/credentials.json` (or the
platform equivalent) and refreshed without user interaction.

---

## 5. Audit Events

Every write a plugin performs emits an audit event:

```ts
type AuditEvent = {
event_id: string;
occurred_at: string;
plugin: { name: string; version: string };
client_id: string;
action: "create" | "edit" | "publish" | "create_tag";
document_id: string | null;
document_version: number | null;
tags: string[];
reason: string;
source: {
kind: "github" | "notion" | "manual" | "schedule" | "other";
ref: string;
};
};
```

**Rule:** a write without a `reason` and a `source` is rejected. This is
how "every write should explain itself" becomes enforceable rather than
aspirational.

Reads are not audited per-call; they are aggregated.

---

## 6. Plugin Lifecycle

```
register → install → authorize → configure → run → (revoke | uninstall)
```

- **register** — published to the Alignbase registry (first-party
bundled, third-party submitted, or custom installed by URL).
- **install** — user picks the plugin from the dashboard or an MCP tool.
- **authorize** — OAuth+PKCE flow. User narrows tags and approves
actions.
- **configure** — the plugin renders its `config_schema` as a form.
- **run** — manual, scheduled, or webhook-triggered.
- **revoke** — user removes the grant from the dashboard.
- **uninstall** — full removal. Audit history is retained.

---

## 7. What's not included in v0.1

- Plugin-to-plugin communication.
- Plugins storing non-context data inside Alignbase.
- Real-time push from Alignbase to plugins (plugins poll or take
webhooks from their source system).
- A plugin builder UI inside the Alignbase dashboard.
- The plugin registry / marketplace itself — this spec defines the
contract a registry would serve, not the registry.
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "alignbase-platform",
"private": true,
"version": "0.0.0",
"description": "Open-source platform layer for Alignbase: SDK and plugins.",
"license": "MIT",
"packageManager": "pnpm@9.15.4",
"engines": {
"node": ">=20"
},
"scripts": {
"build": "pnpm -r build",
"typecheck": "pnpm -r typecheck",
"test": "pnpm -r test",
"clean": "pnpm -r clean",
"get-token": "tsx scripts/get-token.ts"
},
"devDependencies": {
"tsx": "^4.22.4"
}
}
Loading