feat: Phase F-1 — Plexum-fabric-channel-plugin foundation
Ports the foundation of Fabric.OpenclawPlugin to a native Plexum channel plugin (Go). F-2+ phases (socket.io inbound, wakeup gate, tools, presence, etc.) follow. Layout: internal/identity/ — fabric-identity.json registry (agent → API key) internal/fabric/ — REST client (Center auth + Guild messaging) internal/config/ — channels/<name>.json fabric extension parser cmd/plexum-fabric-register/ — agent registration CLI cmd/plexum-fabric-channel-plugin/— Plexum SDK plugin entry scripts/install.sh — build + install + manifest generator Plugin behavior (F-1): - Reads <profile>/channels/*.json, filters plugin=plexum-fabric-channel, builds (plexum-channel-name → fabric channel-id) index - Validates each bound agent's API key against Center at init (warmSessions); logs warning but doesn't refuse init on bad keys - `send` MCP tool: POST plain text to the bound Fabric channel as the agent user; selects guild endpoint+token from cached session - Manifest channels[] is generated by install.sh from current channels/*.json — re-run with --reset-manifest after adding bindings - Plugin-private config at <profile>/plugins/plexum-fabric-channel/config.json (center_api_base, default http://localhost:7001/api) Live smoke verified: - plexum-fabric-register against running Fabric Center (port 7001): validated fak_..., wrote identity file with user_id + email captured Tests: identity (5) + config (6) = 11 unit tests. F-2 will hook socket.io for inbound + wakeup gating + token refresh. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
115
scripts/install.sh
Executable file
115
scripts/install.sh
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env bash
|
||||
# Plexum-fabric-channel-plugin local installer.
|
||||
#
|
||||
# Builds + installs:
|
||||
# ~/.plexum/plugins/plexum-fabric-channel/plexum-fabric-channel-plugin
|
||||
# ~/.plexum/plugins/plexum-fabric-channel/manifest.json (initial; empty channels list)
|
||||
# ~/.local/bin/plexum-fabric-register (CLI for binding agents)
|
||||
#
|
||||
# Re-runnable: rebuilds binaries; overwrites manifest only if --reset-manifest.
|
||||
# Profile data (identity registry, channel configs) is never touched.
|
||||
#
|
||||
# Flags:
|
||||
# --profile <p> Override profile root (default ~/.plexum)
|
||||
# --reset-manifest Overwrite the manifest's channels list with one
|
||||
# derived from current channels/*.json (matches what
|
||||
# the plugin advertises at runtime). Useful after
|
||||
# adding/removing channels.
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PROFILE_DIR="${HOME}/.plexum"
|
||||
USER_BIN="${HOME}/.local/bin"
|
||||
RESET_MANIFEST=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--profile) PROFILE_DIR="$2"; shift 2 ;;
|
||||
--reset-manifest) RESET_MANIFEST=1; shift ;;
|
||||
-h|--help) sed -n '2,/^set -euo/p' "$0" | sed -n '/^#/p' | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) echo "unknown flag: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
log() { printf '\033[1;34m[fabric-install]\033[0m %s\n' "$*"; }
|
||||
|
||||
command -v go >/dev/null || { echo "go not found on PATH" >&2; exit 1; }
|
||||
|
||||
PLUGIN_DIR="${PROFILE_DIR}/plugins/plexum-fabric-channel"
|
||||
mkdir -p "${PLUGIN_DIR}" "${USER_BIN}"
|
||||
|
||||
cd "${REPO}"
|
||||
VERSION="$(git describe --tags --always 2>/dev/null || echo dev)"
|
||||
LDFLAGS="-X main.Version=${VERSION}"
|
||||
log "building plexum-fabric-channel-plugin (v=${VERSION})"
|
||||
CGO_ENABLED=0 go build -ldflags="${LDFLAGS}" \
|
||||
-o "${PLUGIN_DIR}/plexum-fabric-channel-plugin" ./cmd/plexum-fabric-channel-plugin
|
||||
log "building plexum-fabric-register"
|
||||
CGO_ENABLED=0 go build -ldflags="${LDFLAGS}" \
|
||||
-o "${USER_BIN}/plexum-fabric-register" ./cmd/plexum-fabric-register
|
||||
|
||||
MANIFEST_PATH="${PLUGIN_DIR}/manifest.json"
|
||||
if [[ ! -f "${MANIFEST_PATH}" || ${RESET_MANIFEST} -eq 1 ]]; then
|
||||
log "writing initial manifest at ${MANIFEST_PATH}"
|
||||
# Build channels[] from any channels/*.json that name our plugin.
|
||||
CHANNELS_DIR="${PROFILE_DIR}/channels"
|
||||
CHANNELS_JSON='[]'
|
||||
if [[ -d "${CHANNELS_DIR}" ]]; then
|
||||
CHANNELS_JSON=$(python3 -c "
|
||||
import json, os, sys
|
||||
out = []
|
||||
for f in sorted(os.listdir('${CHANNELS_DIR}')):
|
||||
if not f.endswith('.json'): continue
|
||||
try:
|
||||
d = json.load(open(os.path.join('${CHANNELS_DIR}', f)))
|
||||
except Exception:
|
||||
continue
|
||||
if d.get('plugin') == 'plexum-fabric-channel':
|
||||
out.append({'name': f[:-5], 'outboundTool': 'send'})
|
||||
print(json.dumps(out))
|
||||
")
|
||||
fi
|
||||
cat > "${MANIFEST_PATH}" <<EOF
|
||||
{
|
||||
"name": "plexum-fabric-channel",
|
||||
"version": "${VERSION}",
|
||||
"activation": "lazy",
|
||||
"executable": "plexum-fabric-channel-plugin",
|
||||
"contracts": {
|
||||
"channels": ${CHANNELS_JSON},
|
||||
"tools": [
|
||||
{
|
||||
"name": "send",
|
||||
"description": "Post a plain-text message to the bound Fabric channel as the agent user.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"channel_name": {"type": "string"},
|
||||
"session_id": {"type": "string"},
|
||||
"message": {"type": "string"}
|
||||
},
|
||||
"required": ["channel_name", "message"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
[fabric-install] done.
|
||||
plugin binary: ${PLUGIN_DIR}/plexum-fabric-channel-plugin
|
||||
manifest: ${MANIFEST_PATH}
|
||||
register CLI: ${USER_BIN}/plexum-fabric-register
|
||||
|
||||
Next steps:
|
||||
1. Bind agents: plexum-fabric-register --agent-id <agent> --api-key fak_...
|
||||
2. Bind channels: write \`${PROFILE_DIR}/channels/<plexum-name>.json\`
|
||||
(see README); re-run install.sh --reset-manifest after
|
||||
adding/removing channels.
|
||||
3. Allow plugin: add "plexum-fabric-channel" to \`${PROFILE_DIR}/plexum.json\`
|
||||
under .plugins.allow.
|
||||
4. Restart: systemctl --user restart plexum
|
||||
EOF
|
||||
Reference in New Issue
Block a user