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
19 changes: 19 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "trek-plugin-skill",
"interface": {
"displayName": "TREK plugin skill"
},
"plugins": [
{
"name": "trek-plugin-dev",
"source": {
"source": "local",
"path": "./"
},
"policy": {
"installation": "AVAILABLE"
},
"category": "Developer Tools"
}
]
}
1 change: 1 addition & 0 deletions .agents/skills/trek-plugin-dev
1 change: 1 addition & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "trek-plugin-skill",
"description": "Agent skills for building plugins for TREK, the self-hosted travel planner.",
"owner": {
"name": "fbnlrz"
},
Expand Down
4 changes: 2 additions & 2 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"author": {
"name": "fbnlrz"
},
"homepage": "https://github.com/fbnlrz/trek-plugin-skill",
"repository": "https://github.com/fbnlrz/trek-plugin-skill",
"homepage": "https://github.com/liketrek/Plugin-Skill",
"repository": "https://github.com/liketrek/Plugin-Skill",
"license": "MIT",
"keywords": ["trek", "plugin", "skill", "trek-plugin-sdk"]
}
30 changes: 30 additions & 0 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "trek-plugin-dev",
"version": "3.4.0",
"description": "Build, test, sign, and publish plugins for TREK, the self-hosted travel planner.",
"author": {
"name": "fbnlrz",
"url": "https://github.com/fbnlrz"
},
"homepage": "https://github.com/liketrek/Plugin-Skill",
"repository": "https://github.com/liketrek/Plugin-Skill",
"license": "MIT",
"keywords": [
"trek",
"plugin",
"skill",
"trek-plugin-sdk"
],
"skills": "./skills/",
"interface": {
"displayName": "TREK Plugin Dev",
"shortDescription": "Build, test, and publish TREK plugins",
"longDescription": "Covers the trek-plugin.json manifest and its permission catalog, the definePlugin server API and ctx object, the sandboxed iframe postMessage bridge, egress rules, the trek-plugin-sdk CLI, Ed25519 author signing, and the TREK-Plugins registry with every CI gate.",
"developerName": "fbnlrz",
"category": "Developer Tools",
"websiteURL": "https://github.com/liketrek/Plugin-Skill",
"defaultPrompt": [
"Scaffold a TREK plugin and wire up its manifest permissions"
]
}
}
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: TREK app / plugin runtime / trek-plugin-sdk bug
url: https://github.com/mauriceboe/TREK/issues
url: https://github.com/liketrek/TREK/issues
about: For bugs in TREK itself, the plugin runtime, or the SDK — not this skill's docs.
- name: TREK-Plugins registry or CI issue
url: https://github.com/mauriceboe/TREK-Plugins/issues
url: https://github.com/liketrek/TREK-Plugins/issues
about: For the community registry, its CI gates, or a plugin listing problem.
58 changes: 58 additions & 0 deletions .github/scripts/pack-skill.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python3
"""Package the skill for distribution.

Produces dist/<skill>-<version>.zip containing a single top-level directory with
SKILL.md at its root — the layout the Claude Skills API expects on upload, and
what you get by unzipping into ~/.claude/skills or ~/.agents/skills.

A .skill copy is written alongside it. Nothing consumes that extension: neither
Claude Code nor Codex has a handler for it. It is byte-identical to the zip and
exists only as a friendlier download name.

The archive is reproducible — entries are sorted and every timestamp is pinned,
so the same input always yields the same sha256.
"""

import json
import shutil
import sys
import zipfile
from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
SKILL = sys.argv[1] if len(sys.argv) > 1 else "trek-plugin-dev"

# Fixed timestamp (2020-01-01) so archive bytes don't drift between builds.
EPOCH = (2020, 1, 1, 0, 0, 0)

src = ROOT / "skills" / SKILL
if not (src / "SKILL.md").is_file():
sys.exit(f"✗ skills/{SKILL}/SKILL.md not found")

version = json.loads((ROOT / ".codex-plugin/plugin.json").read_text())["version"]

dist = ROOT / "dist"
if dist.exists():
shutil.rmtree(dist)
dist.mkdir()

zip_path = dist / f"{SKILL}-{version}.zip"
files = sorted(p for p in src.rglob("*") if p.is_file())

with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as z:
for path in files:
# Store as "<skill>/…" so the archive unpacks into its own directory.
info = zipfile.ZipInfo(str(path.relative_to(src.parent)), date_time=EPOCH)
info.compress_type = zipfile.ZIP_DEFLATED
# Preserve the executable bit on scripts; everything else 644.
mode = 0o755 if path.stat().st_mode & 0o111 else 0o644
info.external_attr = mode << 16
z.writestr(info, path.read_bytes())

skill_path = dist / f"{SKILL}-{version}.skill"
shutil.copyfile(zip_path, skill_path)

print(f"✔ {zip_path.relative_to(ROOT)} ({zip_path.stat().st_size:,} bytes, {len(files)} files)")
print(f"✔ {skill_path.relative_to(ROOT)} (identical bytes; no tool consumes this extension)")
for path in files:
print(f" {path.relative_to(src.parent)}")
25 changes: 25 additions & 0 deletions .github/scripts/release-notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
"""Print the GitHub release notes for the current manifest version to stdout."""

import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
version = json.loads((ROOT / ".codex-plugin/plugin.json").read_text())["version"]

print(f"""Unpack the archive into your skills directory:

```bash
# Claude Code
unzip trek-plugin-dev-{version}.zip -d ~/.claude/skills/

# Codex
unzip trek-plugin-dev-{version}.zip -d ~/.agents/skills/
```

Or skip the download and install from the repo instead — marketplace, vendoring
and per-repo setup are covered in the
[README](https://github.com/liketrek/Plugin-Skill#install).

The `.skill` file is byte-identical to the `.zip`. No tool consumes that
extension; it exists only as a friendlier download name.""")
45 changes: 45 additions & 0 deletions .github/scripts/set-version.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env node
// Set the plugin version. Usage: node .github/scripts/set-version.mjs 3.4.1
//
// Only .codex-plugin/plugin.json carries a version — Codex requires one and
// caches installs per version. .claude-plugin/plugin.json deliberately has no
// version so Claude Code resolves it from the git commit and every session
// picks up the latest main. Do not "fix" that asymmetry here; see README.

import { readFileSync, writeFileSync } from 'node:fs'
import { resolve } from 'node:path'

const version = process.argv[2]
const ROOT = resolve(import.meta.dirname, '../..')
const TARGET = resolve(ROOT, '.codex-plugin/plugin.json')

if (!version) {
console.error('usage: set-version.mjs <semver>')
process.exit(1)
}
if (!/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/.test(version)) {
console.error(`✗ "${version}" is not a valid semver version (expected e.g. 3.4.1)`)
process.exit(1)
}

const raw = readFileSync(TARGET, 'utf8')
const manifest = JSON.parse(raw)
const previous = manifest.version

if (previous === version) {
console.log(`version is already ${version} — nothing to do`)
process.exit(0)
}

// Rewrite in place so field order and formatting survive.
const updated = raw.replace(/("version"\s*:\s*)"[^"]*"/, `$1"${version}"`)

// Guard against a regex that matched nothing or the wrong field.
const check = JSON.parse(updated)
if (check.version !== version) {
console.error('✗ in-place rewrite failed — aborting rather than writing a bad manifest')
process.exit(1)
}

writeFileSync(TARGET, updated)
console.log(`${previous} → ${version}`)
Loading
Loading