feat: add agor-pro commercial plugin crate and dual-repo infrastructure
agor-pro Tauri 2.x plugin (feature-gated via --features pro), commercial Tauri config overlay, asymmetric test setup, CI workflows (leak-check, commercial-build, PAT health), pre-push hook, Makefile, CONTRIBUTING/MAINTENANCE/LICENSE-COMMERCIAL.
This commit is contained in:
parent
a63e6711ac
commit
5fadd1c022
14 changed files with 682 additions and 0 deletions
53
.githooks/pre-push
Executable file
53
.githooks/pre-push
Executable file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pre-push hook: prevent commercial code from leaking to the community remote.
|
||||||
|
#
|
||||||
|
# Git calls pre-push with the remote name and URL as arguments,
|
||||||
|
# and feeds (local_ref local_sha remote_ref remote_sha) lines on stdin.
|
||||||
|
|
||||||
|
remote="$1"
|
||||||
|
url="$2"
|
||||||
|
|
||||||
|
# Only guard pushes to the community origin (DexterFromLab)
|
||||||
|
if ! echo "$url" | grep -qi "DexterFromLab"; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[pre-push] Scanning commits for commercial code before push to community remote..."
|
||||||
|
|
||||||
|
COMMERCIAL_PATTERNS="agor-pro/|src/lib/commercial/"
|
||||||
|
|
||||||
|
while read -r local_ref local_sha remote_ref remote_sha; do
|
||||||
|
# Skip delete pushes
|
||||||
|
if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For new branches, diff against remote HEAD; for updates, diff against remote_sha
|
||||||
|
if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
|
||||||
|
range="$local_sha"
|
||||||
|
else
|
||||||
|
range="$remote_sha..$local_sha"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check file paths in the commits being pushed
|
||||||
|
leaked_files=$(git diff --name-only "$range" 2>/dev/null | grep -E "$COMMERCIAL_PATTERNS" || true)
|
||||||
|
|
||||||
|
if [ -n "$leaked_files" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo " PUSH BLOCKED: Commercial code detected!"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
echo "The following commercial files were found in commits being pushed:"
|
||||||
|
echo "$leaked_files" | sed 's/^/ - /'
|
||||||
|
echo ""
|
||||||
|
echo "You are pushing to the community remote ($url)."
|
||||||
|
echo "Commercial code must NOT be pushed to this remote."
|
||||||
|
echo ""
|
||||||
|
echo "To fix: remove commercial files from these commits or push to the commercial remote instead."
|
||||||
|
echo "=========================================="
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
71
.github/workflows/commercial-build.yml
vendored
Normal file
71
.github/workflows/commercial-build.yml
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
name: Commercial Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'commercial/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
commercial-build:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
libwebkit2gtk-4.1-dev \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libayatana-appindicator3-dev \
|
||||||
|
librsvg2-dev \
|
||||||
|
libssl-dev \
|
||||||
|
build-essential \
|
||||||
|
pkg-config
|
||||||
|
|
||||||
|
- name: Setup Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
|
- name: Cache Cargo
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-cargo-pro-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-cargo-pro-
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Cargo check (pro features)
|
||||||
|
run: cargo check --features pro
|
||||||
|
|
||||||
|
- name: Cargo test (pro features)
|
||||||
|
run: cargo test --features pro
|
||||||
|
|
||||||
|
- name: Vitest (frontend)
|
||||||
|
run: npm run test
|
||||||
|
|
||||||
|
- name: Commercial tests
|
||||||
|
run: |
|
||||||
|
if [ -d "tests/commercial/" ] && ls tests/commercial/*.test.* 2>/dev/null; then
|
||||||
|
npx vitest run tests/commercial/
|
||||||
|
else
|
||||||
|
echo "No commercial tests found, skipping."
|
||||||
|
fi
|
||||||
69
.github/workflows/leak-check.yml
vendored
Normal file
69
.github/workflows/leak-check.yml
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
name: Leak Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
leak-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Check for commercial directories
|
||||||
|
run: |
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
# Check agor-pro/ exists
|
||||||
|
if [ -d "agor-pro/" ]; then
|
||||||
|
echo "::error::Commercial directory 'agor-pro/' found in community repo"
|
||||||
|
failed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check src/lib/commercial/ has actual content (beyond .gitkeep)
|
||||||
|
if [ -d "src/lib/commercial/" ]; then
|
||||||
|
content_count=$(find src/lib/commercial/ -type f ! -name '.gitkeep' | wc -l)
|
||||||
|
if [ "$content_count" -gt 0 ]; then
|
||||||
|
echo "::error::Commercial code found in 'src/lib/commercial/' ($content_count files beyond .gitkeep)"
|
||||||
|
find src/lib/commercial/ -type f ! -name '.gitkeep'
|
||||||
|
failed=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check tests/commercial/ has actual content (beyond .gitkeep)
|
||||||
|
if [ -d "tests/commercial/" ]; then
|
||||||
|
content_count=$(find tests/commercial/ -type f ! -name '.gitkeep' | wc -l)
|
||||||
|
if [ "$content_count" -gt 0 ]; then
|
||||||
|
echo "::error::Commercial test code found in 'tests/commercial/' ($content_count files beyond .gitkeep)"
|
||||||
|
find tests/commercial/ -type f ! -name '.gitkeep'
|
||||||
|
failed=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$failed" -eq 1 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "No commercial directories with content found."
|
||||||
|
|
||||||
|
- name: Grep for commercial references in source
|
||||||
|
run: |
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
for pattern in "LicenseRef-Commercial" "agor-pro" "agor_pro"; do
|
||||||
|
if grep -r --include="*.ts" --include="*.svelte" --include="*.rs" --include="*.toml" \
|
||||||
|
"$pattern" src/ src-tauri/src/ 2>/dev/null; then
|
||||||
|
echo "::error::Found '$pattern' reference in source code"
|
||||||
|
failed=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$failed" -eq 1 ]; then
|
||||||
|
echo "::error::Commercial references detected in community source. See above for details."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "No commercial references found in source."
|
||||||
75
.github/workflows/pat-health.yml
vendored
Normal file
75
.github/workflows/pat-health.yml
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
name: PAT Health Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 9 * * 1' # Every Monday at 9am UTC
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-pat:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check COMMUNITY_PAT validity
|
||||||
|
env:
|
||||||
|
COMMUNITY_PAT: ${{ secrets.COMMUNITY_PAT }}
|
||||||
|
run: |
|
||||||
|
if [ -z "$COMMUNITY_PAT" ]; then
|
||||||
|
echo "::error::COMMUNITY_PAT secret is not set"
|
||||||
|
echo "pat_valid=false" >> "$GITHUB_ENV"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
status=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "Authorization: token $COMMUNITY_PAT" \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
https://api.github.com/user)
|
||||||
|
|
||||||
|
if [ "$status" -eq 200 ]; then
|
||||||
|
echo "COMMUNITY_PAT is valid (HTTP $status)"
|
||||||
|
echo "pat_valid=true" >> "$GITHUB_ENV"
|
||||||
|
else
|
||||||
|
echo "::error::COMMUNITY_PAT returned HTTP $status"
|
||||||
|
echo "pat_valid=false" >> "$GITHUB_ENV"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create issue if PAT is invalid
|
||||||
|
if: env.pat_valid == 'false'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const title = 'COMMUNITY_PAT is invalid or missing';
|
||||||
|
const body = [
|
||||||
|
'## PAT Health Check Failed',
|
||||||
|
'',
|
||||||
|
'The weekly PAT health check detected that `COMMUNITY_PAT` is either missing or returning an error from the GitHub API.',
|
||||||
|
'',
|
||||||
|
'**Action required:** Rotate or re-create the PAT and update the repository secret.',
|
||||||
|
'',
|
||||||
|
`Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
// Avoid duplicate issues
|
||||||
|
const existing = await github.rest.issues.listForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
state: 'open',
|
||||||
|
labels: 'pat-health',
|
||||||
|
per_page: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existing.data.length > 0) {
|
||||||
|
console.log('Open PAT health issue already exists, skipping creation.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await github.rest.issues.create({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
labels: ['pat-health'],
|
||||||
|
});
|
||||||
122
CONTRIBUTING.md
Normal file
122
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
# Contributing to Agent Orchestrator
|
||||||
|
|
||||||
|
## Dual-Repository Model
|
||||||
|
|
||||||
|
This project uses a dual-repo structure:
|
||||||
|
|
||||||
|
| Repository | License | Purpose |
|
||||||
|
|------------|---------|---------|
|
||||||
|
| `DexterFromLab/agent-orchestrator` | MIT | Community edition (open source) |
|
||||||
|
| `agents-orchestrator/agents-orchestrator` | MIT + Commercial | Commercial edition (this repo) |
|
||||||
|
|
||||||
|
Community contributions target the community repo. Commercial development happens
|
||||||
|
exclusively in this repo. The two share a common `main` branch that is synced
|
||||||
|
periodically.
|
||||||
|
|
||||||
|
## Community Contributions
|
||||||
|
|
||||||
|
All community contributions go to **DexterFromLab/agent-orchestrator**. Do not open
|
||||||
|
PRs against this repo for community features.
|
||||||
|
|
||||||
|
### Contributor License Agreement (CLA)
|
||||||
|
|
||||||
|
Every community contributor must sign the CLA before their first PR is merged.
|
||||||
|
CLA signing is automated via [CLA-assistant.io](https://cla-assistant.io/) on
|
||||||
|
the community repository. The bot will prompt you on your first PR.
|
||||||
|
|
||||||
|
The CLA grants the project maintainers a perpetual, irrevocable license to use
|
||||||
|
your contribution in both the community and commercial editions.
|
||||||
|
|
||||||
|
## Commercial Development
|
||||||
|
|
||||||
|
Commercial features are developed only in this repository. Access is restricted
|
||||||
|
to authorized team members.
|
||||||
|
|
||||||
|
### SPDX License Headers
|
||||||
|
|
||||||
|
All commercial source files must include the following header as the first line:
|
||||||
|
|
||||||
|
```
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Commercial
|
||||||
|
```
|
||||||
|
|
||||||
|
For CSS/HTML files:
|
||||||
|
|
||||||
|
```
|
||||||
|
/* SPDX-License-Identifier: LicenseRef-Commercial */
|
||||||
|
```
|
||||||
|
|
||||||
|
For Rust files:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Commercial
|
||||||
|
```
|
||||||
|
|
||||||
|
Community-shared code uses the MIT identifier:
|
||||||
|
|
||||||
|
```
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commercial Directories
|
||||||
|
|
||||||
|
Files under these paths are always commercial-only:
|
||||||
|
|
||||||
|
- `agor-pro/`
|
||||||
|
- `src/lib/commercial/`
|
||||||
|
|
||||||
|
## Branch Model
|
||||||
|
|
||||||
|
| Branch | Purpose |
|
||||||
|
|--------|---------|
|
||||||
|
| `main` | Shared with community edition. Never commit commercial code here. |
|
||||||
|
| `commercial/*` | Commercial-only features. Merged into the commercial release branch. |
|
||||||
|
| `feature/*`, `fix/*` | Standard development branches. |
|
||||||
|
|
||||||
|
### Sync Flow
|
||||||
|
|
||||||
|
The community repo's `main` is merged into this repo's `main` periodically:
|
||||||
|
|
||||||
|
```
|
||||||
|
community/main --> origin/main --> commercial branches
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `make sync` to pull community changes. Never force-push `main`.
|
||||||
|
|
||||||
|
## Commit Conventions
|
||||||
|
|
||||||
|
Use [Conventional Commits](https://www.conventionalcommits.org/):
|
||||||
|
|
||||||
|
```
|
||||||
|
type(scope): description
|
||||||
|
|
||||||
|
feat(dashboard): add team analytics panel
|
||||||
|
fix(sidecar): handle timeout on agent restart
|
||||||
|
docs(api): update webhook payload reference
|
||||||
|
chore(deps): bump tauri to 2.3.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`, `ci`, `build`.
|
||||||
|
|
||||||
|
Breaking changes use `type!:` prefix or include `BREAKING CHANGE:` in the footer.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Both editions must pass their respective test suites before merge:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Community tests (must always pass on main)
|
||||||
|
npm run test:all
|
||||||
|
|
||||||
|
# Commercial tests (includes commercial-specific tests)
|
||||||
|
npm run test:all:commercial
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not merge a PR if either suite is red. If a community sync introduces
|
||||||
|
failures in commercial tests, fix them before merging.
|
||||||
|
|
||||||
|
## Code Review
|
||||||
|
|
||||||
|
- All PRs require at least one approval.
|
||||||
|
- Commercial PRs must be reviewed by a team member with commercial repo access.
|
||||||
|
- Verify no commercial code leaks into community-bound branches before approving.
|
||||||
50
LICENSE-COMMERCIAL
Normal file
50
LICENSE-COMMERCIAL
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
Commercial License
|
||||||
|
|
||||||
|
Copyright (c) 2025-2026 Agents Orchestrator. All rights reserved.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
1. GRANT OF LICENSE
|
||||||
|
|
||||||
|
This software and associated documentation files (the "Software") located
|
||||||
|
under the directories `agor-pro/` and `src/lib/commercial/`, and any other
|
||||||
|
files bearing the SPDX header `LicenseRef-Commercial`, are licensed to
|
||||||
|
authorized users under the terms of a separate commercial agreement.
|
||||||
|
|
||||||
|
2. RESTRICTIONS
|
||||||
|
|
||||||
|
Unless you have a valid commercial license agreement, you may not:
|
||||||
|
|
||||||
|
a. Copy, modify, merge, publish, distribute, sublicense, or sell copies
|
||||||
|
of the Software.
|
||||||
|
b. Reverse engineer, decompile, or disassemble the Software.
|
||||||
|
c. Remove or alter any proprietary notices, labels, or marks on the
|
||||||
|
Software.
|
||||||
|
d. Use the Software to provide a competing product or service.
|
||||||
|
|
||||||
|
3. OWNERSHIP
|
||||||
|
|
||||||
|
The Software is the intellectual property of Agents Orchestrator and is
|
||||||
|
protected by copyright law. This license does not transfer ownership.
|
||||||
|
|
||||||
|
4. NO WARRANTY
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
5. TERMINATION
|
||||||
|
|
||||||
|
This license terminates automatically if you breach any of its terms. Upon
|
||||||
|
termination, you must destroy all copies of the Software in your possession.
|
||||||
|
|
||||||
|
6. GOVERNING LAW
|
||||||
|
|
||||||
|
This license shall be governed by and construed in accordance with the laws
|
||||||
|
of the jurisdiction in which Agents Orchestrator is incorporated.
|
||||||
|
|
||||||
|
For licensing inquiries, contact the Agents Orchestrator organization.
|
||||||
128
MAINTENANCE.md
Normal file
128
MAINTENANCE.md
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
# Maintenance Guide
|
||||||
|
|
||||||
|
Operational procedures for the commercial edition of Agent Orchestrator.
|
||||||
|
|
||||||
|
## PAT Rotation
|
||||||
|
|
||||||
|
The `COMMUNITY_PAT` personal access token is used by CI to sync with the
|
||||||
|
community repository. Rotate it every 90 days.
|
||||||
|
|
||||||
|
### Rotation Procedure
|
||||||
|
|
||||||
|
1. Generate a new fine-grained PAT on GitHub with scope:
|
||||||
|
- Repository: `DexterFromLab/agent-orchestrator`
|
||||||
|
- Permissions: `Contents: Read-only`
|
||||||
|
2. Update the secret in this repo's GitHub Settings > Secrets > Actions:
|
||||||
|
- Name: `COMMUNITY_PAT`
|
||||||
|
- Value: the new token
|
||||||
|
3. Run the sync workflow manually to verify: Actions > Community Sync > Run workflow.
|
||||||
|
4. Record the rotation date. Next rotation due in 90 days.
|
||||||
|
|
||||||
|
### Token Audit
|
||||||
|
|
||||||
|
Check token expiry dates monthly. Set a calendar reminder.
|
||||||
|
|
||||||
|
## Community Sync
|
||||||
|
|
||||||
|
### Automated
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make sync
|
||||||
|
```
|
||||||
|
|
||||||
|
This fetches `community/main`, merges it into `origin/main`, and runs the test
|
||||||
|
suite. Conflicts must be resolved manually.
|
||||||
|
|
||||||
|
### Manual
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git remote add community https://github.com/DexterFromLab/agent-orchestrator.git 2>/dev/null
|
||||||
|
git fetch community main
|
||||||
|
git checkout main
|
||||||
|
git merge community/main --no-edit
|
||||||
|
npm run test:all
|
||||||
|
```
|
||||||
|
|
||||||
|
If tests fail after sync, fix before pushing.
|
||||||
|
|
||||||
|
## Pre-Release Checklist: Community Edition
|
||||||
|
|
||||||
|
Before publishing a community release from `main`:
|
||||||
|
|
||||||
|
- [ ] `git diff main..commercial/main -- agor-pro/ src/lib/commercial/` shows no commercial code on `main`
|
||||||
|
- [ ] Run `grep -r "LicenseRef-Commercial" --include="*.ts" --include="*.rs" --include="*.svelte" src/ src-tauri/` on `main` returns nothing
|
||||||
|
- [ ] Run `npm run test:all` passes
|
||||||
|
- [ ] Run `cargo test --workspace` passes
|
||||||
|
- [ ] CHANGELOG.md updated with release notes
|
||||||
|
- [ ] Tag follows semver: `v{major}.{minor}.{patch}`
|
||||||
|
- [ ] No secrets, API keys, or internal URLs in the diff since last release
|
||||||
|
|
||||||
|
## Pre-Release Checklist: Commercial Edition
|
||||||
|
|
||||||
|
Before publishing a commercial release:
|
||||||
|
|
||||||
|
- [ ] All commercial branches merged into the release branch
|
||||||
|
- [ ] `npm run test:all:commercial` passes
|
||||||
|
- [ ] `cargo test --workspace` passes
|
||||||
|
- [ ] License headers present on all commercial files (`grep -rL "SPDX-License-Identifier" agor-pro/ src/lib/commercial/` returns nothing)
|
||||||
|
- [ ] No hardcoded credentials or internal endpoints
|
||||||
|
- [ ] Database migrations tested against fresh install and upgrade from previous version
|
||||||
|
- [ ] Release notes written for commercial changelog
|
||||||
|
|
||||||
|
## Database Migration Notes
|
||||||
|
|
||||||
|
The commercial edition uses a separate data directory to avoid conflicts:
|
||||||
|
|
||||||
|
| Edition | Data Directory |
|
||||||
|
|---------|---------------|
|
||||||
|
| Community | `~/.local/share/bterminal/` |
|
||||||
|
| Commercial | `~/.local/share/agor/` |
|
||||||
|
|
||||||
|
### Migration Rules
|
||||||
|
|
||||||
|
- Schema migrations run automatically on startup (WAL mode SQLite).
|
||||||
|
- Never modify existing migration SQL. Add new migrations with incrementing version numbers.
|
||||||
|
- Test migrations against: (a) fresh install, (b) upgrade from N-1, (c) upgrade from N-2.
|
||||||
|
- Back up `~/.local/share/agor/` before testing destructive migrations locally.
|
||||||
|
|
||||||
|
### Edition Switching in Development
|
||||||
|
|
||||||
|
When switching between community and commercial editions locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
This clears build artifacts and resets configuration to avoid cross-contamination.
|
||||||
|
The two editions use separate data directories, so user data is not affected.
|
||||||
|
Rebuild after switching:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install && npm run tauri dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quarterly Maintenance
|
||||||
|
|
||||||
|
Perform these tasks every quarter:
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- [ ] Rotate `COMMUNITY_PAT` (if due within the quarter)
|
||||||
|
- [ ] Run `npm audit` and `cargo audit` on both editions
|
||||||
|
- [ ] Review GitHub Dependabot alerts
|
||||||
|
- [ ] Verify no secrets in git history: `git log --all --diff-filter=A -- '*.env' '*.pem' '*.key'`
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- [ ] Update Rust toolchain (`rustup update`)
|
||||||
|
- [ ] Update Node.js to latest LTS if applicable
|
||||||
|
- [ ] Review and update pinned dependency versions
|
||||||
|
- [ ] Run full test suite after updates
|
||||||
|
|
||||||
|
### Repository Health
|
||||||
|
|
||||||
|
- [ ] Prune stale branches (`git branch --merged main | grep -v main`)
|
||||||
|
- [ ] Verify CI workflows are green on main
|
||||||
|
- [ ] Review and close stale issues/PRs
|
||||||
|
- [ ] Sync community changes if not done recently
|
||||||
|
- [ ] Verify backup procedures for commercial data
|
||||||
36
Makefile
Normal file
36
Makefile
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
.PHONY: setup build build-pro test test-pro sync clean
|
||||||
|
|
||||||
|
# --- Community ---
|
||||||
|
|
||||||
|
setup:
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
npm install
|
||||||
|
@echo "Git hooks configured and dependencies installed."
|
||||||
|
|
||||||
|
build:
|
||||||
|
cargo build
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
test:
|
||||||
|
npm run test:all
|
||||||
|
|
||||||
|
# --- Commercial ---
|
||||||
|
|
||||||
|
build-pro:
|
||||||
|
cargo build --features pro
|
||||||
|
npm run build
|
||||||
|
@echo "For Tauri release: cargo tauri build -- --features pro --config src-tauri/tauri.conf.commercial.json"
|
||||||
|
|
||||||
|
test-pro:
|
||||||
|
cargo test --features pro
|
||||||
|
AGOR_EDITION=pro npx vitest run
|
||||||
|
|
||||||
|
# --- Maintenance ---
|
||||||
|
|
||||||
|
sync:
|
||||||
|
git fetch origin
|
||||||
|
git merge origin/main
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cargo clean
|
||||||
|
rm -rf node_modules/.vite
|
||||||
13
agor-pro/Cargo.toml
Normal file
13
agor-pro/Cargo.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "agor-pro"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
description = "Commercial plugin for Agents Orchestrator"
|
||||||
|
license = "LicenseRef-Commercial"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
agor-core = { path = "../agor-core" }
|
||||||
|
tauri = { version = "2.10.3", features = [] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
log = "0.4"
|
||||||
35
agor-pro/src/lib.rs
Normal file
35
agor-pro/src/lib.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// agor-pro — Commercial plugin for Agents Orchestrator.
|
||||||
|
// This crate is NOT open-source. It is distributed only via the
|
||||||
|
// agents-orchestrator/agents-orchestrator private repository.
|
||||||
|
|
||||||
|
use tauri::{
|
||||||
|
plugin::{Builder, TauriPlugin},
|
||||||
|
Runtime,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Initialize the agor-pro Tauri plugin.
|
||||||
|
/// Registers all commercial commands and managed state.
|
||||||
|
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||||
|
Builder::new("agor-pro")
|
||||||
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
pro_status,
|
||||||
|
])
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn pro_status() -> String {
|
||||||
|
"active".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pro_status() {
|
||||||
|
assert_eq!(pro_status(), "active");
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src-tauri/tauri.conf.commercial.json
Normal file
16
src-tauri/tauri.conf.commercial.json
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
|
"productName": "agents-orchestrator-pro",
|
||||||
|
"identifier": "com.agentsorchestrator.pro",
|
||||||
|
"plugins": {
|
||||||
|
"updater": {
|
||||||
|
"endpoints": [
|
||||||
|
"https://github.com/agents-orchestrator/agents-orchestrator/releases/latest/download/latest.json"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bundle": {
|
||||||
|
"shortDescription": "Agents Orchestrator Pro — commercial multi-agent dashboard",
|
||||||
|
"longDescription": "Agents Orchestrator Pro is the commercial edition with advanced features including enterprise agent management, priority support, and extended integrations."
|
||||||
|
}
|
||||||
|
}
|
||||||
0
src/lib/commercial/.gitkeep
Normal file
0
src/lib/commercial/.gitkeep
Normal file
0
tests/commercial/.gitkeep
Normal file
0
tests/commercial/.gitkeep
Normal file
14
tests/commercial/pro-edition.test.ts
Normal file
14
tests/commercial/pro-edition.test.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Commercial
|
||||||
|
// Commercial-only tests — excluded from community test runs.
|
||||||
|
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
|
||||||
|
describe('Pro Edition', () => {
|
||||||
|
it('commercial test suite is reachable', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('AGOR_EDITION env var is set to pro when running commercial tests', () => {
|
||||||
|
expect(process.env.AGOR_EDITION).toBe('pro');
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue