Skip to content
Merged
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
123 changes: 123 additions & 0 deletions .github/workflows/sync-extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Sync Extension from sentience-chrome

on:
repository_dispatch:
types: [extension-updated]
workflow_dispatch:
inputs:
release_tag:
description: 'Release tag from sentience-chrome (e.g., v1.0.0)'
required: true
type: string
schedule:
# Check for new releases daily at 2 AM UTC
- cron: '0 2 * * *'

jobs:
sync-extension:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

steps:
- name: Checkout sdk-ts
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Determine release tag
id: release
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
TAG="${{ github.event.inputs.release_tag }}"
elif [ "${{ github.event_name }}" == "repository_dispatch" ]; then
TAG="${{ github.event.client_payload.release_tag }}"
else
# Scheduled check - get latest release
TAG=$(curl -s https://api.github.com/repos/${{ secrets.SENTIENCE_CHROME_REPO }}/releases/latest | jq -r '.tag_name // empty')
fi

if [ -z "$TAG" ] || [ "$TAG" == "null" ]; then
echo "No release found, skipping"
echo "skip=true" >> $GITHUB_OUTPUT
exit 0
fi

echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "Release tag: $TAG"

- name: Download extension files
if: steps.release.outputs.skip != 'true'
run: |
TAG="${{ steps.release.outputs.tag }}"
REPO="${{ secrets.SENTIENCE_CHROME_REPO }}"

# Download release assets
mkdir -p extension-temp
cd extension-temp

# Download each file from release
curl -L -H "Authorization: token ${{ secrets.SENTIENCE_CHROME_TOKEN }}" \
"https://api.github.com/repos/$REPO/releases/tags/$TAG" | \
jq -r '.assets[] | select(.name | endswith(".js") or endswith(".wasm") or endswith(".json") or endswith(".d.ts")) | .browser_download_url' | \
while read url; do
filename=$(basename "$url")
curl -L -H "Authorization: token ${{ secrets.SENTIENCE_CHROME_TOKEN }}" "$url" -o "$filename"
done

- name: Copy extension files
if: steps.release.outputs.skip != 'true'
run: |
# Create extension directory structure
mkdir -p src/extension/pkg

# Copy extension files
cp extension-temp/manifest.json src/extension/ 2>/dev/null || echo "manifest.json not found in release"
cp extension-temp/content.js src/extension/ 2>/dev/null || echo "content.js not found in release"
cp extension-temp/background.js src/extension/ 2>/dev/null || echo "background.js not found in release"
cp extension-temp/injected_api.js src/extension/ 2>/dev/null || echo "injected_api.js not found in release"

# Copy WASM files
cp extension-temp/pkg/sentience_core.js src/extension/pkg/ 2>/dev/null || echo "sentience_core.js not found"
cp extension-temp/pkg/sentience_core_bg.wasm src/extension/pkg/ 2>/dev/null || echo "sentience_core_bg.wasm not found"
cp extension-temp/pkg/*.d.ts src/extension/pkg/ 2>/dev/null || echo "Type definitions not found"

- name: Check for changes
if: steps.release.outputs.skip != 'true'
id: changes
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add src/extension/ || true
if git diff --staged --quiet; then
echo "changed=false" >> $GITHUB_OUTPUT
echo "No changes detected"
else
echo "changed=true" >> $GITHUB_OUTPUT
echo "Changes detected"
fi

- name: Create Pull Request
if: steps.release.outputs.skip != 'true' && steps.changes.outputs.changed == 'true'
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore: sync extension files from sentience-chrome ${{ steps.release.outputs.tag }}"
title: "Sync Extension: ${{ steps.release.outputs.tag }}"
body: |
This PR syncs extension files from sentience-chrome release ${{ steps.release.outputs.tag }}.

**Files updated:**
- Extension manifest and scripts
- WASM binary and bindings

**Source:** [sentience-chrome release ${{ steps.release.outputs.tag }}](${{ secrets.SENTIENCE_CHROME_REPO }}/releases/tag/${{ steps.release.outputs.tag }})
branch: sync-extension-${{ steps.release.outputs.tag }}
delete-branch: true

48 changes: 36 additions & 12 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,44 @@ export class SentienceBrowser {
}

async start(): Promise<void> {
// Get extension source path (relative to project root)
// Try to find extension in multiple locations:
// 1. Embedded extension (src/extension/) - for production/CI
// 2. Development mode (../sentience-chrome/) - for local development

// Handle both ts-node (src/) and compiled (dist/src/) cases
let sdkRoot: string;
let repoRoot: string;
if (__dirname.includes('dist')) {
// Compiled: dist/src/ -> go up 3 levels to project root (Sentience/)
repoRoot = path.resolve(__dirname, '../../..');
// Compiled: dist/src/ -> go up 2 levels to sdk-ts/
sdkRoot = path.resolve(__dirname, '../..');
// Go up 1 more level to project root (Sentience/)
repoRoot = path.resolve(sdkRoot, '..');
} else {
// ts-node: src/ -> go up 2 levels to project root (Sentience/)
repoRoot = path.resolve(__dirname, '../..');
// ts-node: src/ -> go up 1 level to sdk-ts/
sdkRoot = path.resolve(__dirname, '..');
// Go up 1 more level to project root (Sentience/)
repoRoot = path.resolve(sdkRoot, '..');
}
const extensionSource = path.join(repoRoot, 'sentience-chrome');

if (!fs.existsSync(extensionSource)) {

// Check for embedded extension first (production/CI)
const embeddedExtension = path.join(sdkRoot, 'src', 'extension');

// Check for development extension (local development)
const devExtension = path.join(repoRoot, 'sentience-chrome');

// Prefer embedded extension, fall back to dev extension
let extensionSource: string;
if (fs.existsSync(embeddedExtension) && fs.existsSync(path.join(embeddedExtension, 'manifest.json'))) {
extensionSource = embeddedExtension;
} else if (fs.existsSync(devExtension) && fs.existsSync(path.join(devExtension, 'manifest.json'))) {
extensionSource = devExtension;
} else {
throw new Error(
`Extension not found at ${extensionSource}. ` +
'Make sure sentience-chrome directory exists.'
`Extension not found. Checked:\n` +
` 1. ${embeddedExtension}\n` +
` 2. ${devExtension}\n` +
'Make sure extension files are available. ' +
'For development: cd ../sentience-chrome && ./build.sh'
);
}

Expand Down Expand Up @@ -87,7 +109,8 @@ export class SentienceBrowser {
if (!fs.existsSync(pkgSource)) {
throw new Error(
`WASM package directory not found at ${pkgSource}\n` +
'Make sure to build the extension: cd sentience-chrome && ./build.sh'
'Make sure extension files are available. ' +
'For development: cd ../sentience-chrome && ./build.sh'
);
}

Expand All @@ -99,7 +122,8 @@ export class SentienceBrowser {
`WASM files not found. Expected:\n` +
` - ${wasmJs}\n` +
` - ${wasmBinary}\n` +
'Make sure to build the extension: cd sentience-chrome && ./build.sh'
'Make sure extension files are available. ' +
'For development: cd ../sentience-chrome && ./build.sh'
);
}

Expand Down
Loading