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
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
# Explicitly mark script and config files as text with LF endings
*.ts text eol=lf
*.js text eol=lf
# Python
*.py text eol=lf

# Shell
*.sh text eol=lf
*.md text eol=lf
*.json text eol=lf
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 1

- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@70a6e5256e9e2366a1ed5c041904a982ba3a328f # v1.0.135
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ jobs:
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@70a6e5256e9e2366a1ed5c041904a982ba3a328f # v1.0.135
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

Expand Down
139 changes: 139 additions & 0 deletions .github/workflows/validate-port.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: Validate Port
on:
push:
branches: [main]
paths:
- 'targets/**'
- 'spec/**'
- 'Releases/Pi/**'
pull_request:
paths:
- 'targets/**'
- 'spec/**'
- 'Releases/Pi/**'

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Check Hermes frontmatter
run: |
e=0
for f in targets/hermes/skills/*/SKILL.md; do
n=$(basename $(dirname $f))
for x in "name:" "description:" "version:" "author:" "license:" "metadata:"; do
grep -q "^$x" "$f" || { echo "MISSING $x in $n"; e=$((e+1)); }
done
grep -q "USE WHEN" "$f" || { echo "MISSING USE WHEN in $n"; e=$((e+1)); }
grep -q "NOT FOR" "$f" || { echo "MISSING NOT FOR in $n"; e=$((e+1)); }
done
[ "$e" -eq 0 ] || { echo "$e frontmatter errors"; exit 1; }

- name: Check Hermes sections
run: |
e=0
for f in targets/hermes/skills/*/SKILL.md; do
n=$(basename $(dirname $f))
for s in "## Gotchas" "## Execution Log"; do
grep -q "$s" "$f" || { echo "MISSING $s in $n"; e=$((e+1)); }
done
done
[ "$e" -eq 0 ] || { echo "$e section errors"; exit 1; }

- name: Check Pi frontmatter
run: |
e=0
for f in Releases/Pi/skills/*/SKILL.md; do
head -1 "$f" | grep -q '^---$' || { echo "NO FRONTMATTER in $(basename $(dirname $f))"; e=$((e+1)); }
done
[ "$e" -eq 0 ] || { echo "$e Pi frontmatter errors"; exit 1; }

- name: Check trailing whitespace
run: |
c=$(grep -rn '[[:space:]]$' targets/ spec/ Releases/Pi/skills/ --include='*.md' --include='*.sh' 2>/dev/null | wc -l)
[ "$c" -eq 0 ] || { echo "$c lines with trailing whitespace"; exit 1; }

- name: Check empty files
run: |
e=$(find targets/ spec/ Releases/Pi/skills/ -type f -empty 2>/dev/null)
[ -z "$e" ] || { echo "Empty files: $e"; exit 1; }

- name: Check install.sh syntax
run: "bash -n targets/hermes/install.sh"

- name: Smoke test — Python syntax check
run: |
e=0
while IFS= read -r f; do
python3 -m py_compile "$f" 2>/dev/null || { echo "SYNTAX ERROR: $f"; e=$((e+1)); }
done < <(find Packs/ -name '*.py' -not -path '*/node_modules/*' 2>/dev/null)
[ "$e" -eq 0 ] || { echo "$e Python file(s) with syntax errors"; exit 1; }
echo "✅ All Python files parse clean"

- name: Smoke test — Shell syntax check
run: |
e=0
while IFS= read -r f; do
bash -n "$f" 2>/dev/null || { echo "SYNTAX ERROR: $f"; e=$((e+1)); }
done < <(find . -name '*.sh' -not -path './.git/*' -not -path '*/node_modules/*' 2>/dev/null)
[ "$e" -eq 0 ] || { echo "$e shell file(s) with syntax errors"; exit 1; }
echo "✅ All shell files parse clean"

- name: Count skills
run: |
h=$(ls -d targets/hermes/skills/*/ 2>/dev/null | wc -l)
p=$(ls -d Releases/Pi/skills/*/ 2>/dev/null | wc -l)
echo "Hermes: $h skills, Pi: $p skills"
[ "$h" -eq 41 ] || { echo "Expected 41 Hermes skills, got $h"; exit 1; }

typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 1

- name: Install Bun
uses: oven-sh/setup-bun@4bc047ad3df7e0c20dc644119cb3719ab01106c4 # v2.0.2
with:
bun-version: latest

- name: TypeScript type-check — Packs
run: |
pass=0
fail=0
for dir in \
Packs/Apify/src \
Packs/Art/src/Tools \
Packs/Evals/src \
Packs/Media/src/Art/Tools \
Packs/Media/src/Remotion/Tools \
Packs/Remotion/src/Tools \
Packs/Scraping/src/Apify; do
if [ ! -f "$dir/tsconfig.json" ]; then
echo "⚠️ $dir — no tsconfig.json (skipping)"
continue
fi
echo "Checking $dir..."
if (cd "$dir" && bun install --frozen-lockfile 2>/dev/null && bunx tsc --noEmit 2>/dev/null); then
echo " ✅ PASS"
pass=$((pass+1))
else
echo " ❌ HAS ERRORS (pre-existing)"
fail=$((fail+1))
fi
done
echo ""
echo "Type-check summary: $pass passed, $fail with pre-existing errors"
echo "Note: Only the core port packs (Apify, Remotion) are expected to be clean."
echo "Art/Media packs have pre-existing issues from upstream duplication."

- name: Check duplicate tsconfig dirs (next.js apps skip)
run: |
for dir in Packs/Telos/src/DashboardTemplate Packs/Telos/src/ReportTemplate; do
if [ -f "$dir/tsconfig.json" ]; then
echo "Skipping $dir (Next.js app — has own build step)"
fi
done
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Python
__pycache__/
*.py[cod]
*.egg-info/
.coverage
.coverage.*
coverage/
htmlcov/
.venv/
venv/

# Windows
Thumbs.db

# macOS
.DS_Store
.AppleDouble
Expand Down Expand Up @@ -69,6 +83,9 @@ private/
secrets/
credentials/

# Agentic artifacts
.hermes/

# PAI Update System (sideloading)
.claude/pai_updates/
.claude/pai_backups/
Expand Down
81 changes: 81 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Contributing to PAI v5.0 Port

This fork ports the PAI v5.0 Life Operating System to Hermes Agent, Pi-mono, and OpenCode. Contributions are welcome.

## What Needs Help

| Area | Skills Needed | Difficulty |
|------|--------------|------------|
| **New skill packs** | Porting upstream PAI packs to Hermes SKILL.md format | Medium |
| **Pi-mono** | Expanding skill packs, testing with different LLM providers | Medium |
| **OpenCode** | Improving context files, testing with Codex CLI | Easy |
| **Documentation** | READMEs, examples, tutorials | Easy |
| **Testing** | Verifying skills work end-to-end | Medium |
| **Pulse daemon** | Building a lightweight Hermes-compatible Pulse | Hard |

## Porting a PAI Pack to Hermes

Each Hermes skill is a SKILL.md file in `targets/hermes/skills/<name>/`:

```markdown
---
name: pai-<name>
description: "What it does. USE WHEN <trigger conditions>. NOT FOR <exclusions>."
version: 5.0.0
author: PAI v5.0 → Hermes Port
license: MIT
metadata:
hermes:
tags: [pai, <category>, <tags>]
related_skills: [<related skills>]
---

# Skill Name

## Overview

Brief description.

## Workflow Routing

| Trigger | Workflow |
|---------|----------|
| "action" | What to do |

## Procedure

### Step 1 — Voice notification
curl command to localhost:31337/notify

### Step N — Action
Step-by-step instructions using Hermes tools

## Gotchas

Known pitfalls.

## Execution Log

JSONL append command.
```

## Standards

- **Descriptions** must include `USE WHEN` and `NOT FOR`
- **All skills** need: Gotchas, Execution Log, voice notification curl
- **Frontmatter** must have: name, description, version, author, license, metadata
- **Version** is always `5.0.0`
- **Author** is always `PAI v5.0 → Hermes Port`
- **One concern per commit** — isolate fixes from features

## Pull Request Process

1. Fork the repo
2. Create a branch: `feat/<skill-name>` or `fix/<description>`
3. Run the CI checks locally: `bash .github/workflows/validate-port.yml` (or use `act`)
4. Open a PR against `main`
5. CI must pass before merge

## Spec / Documentation

Spec changes go in `spec/`. If you change behavior, update the parity matrix at `spec/port-complete/parity-matrix.md`.
Loading