feat(plugin): ship the Scribe Claude Code plugin in-repo (marketplace + plugin)
Per operator: the plugin lives in the app repo so it ships and versions in
lockstep with the app and the /api/plugin/context contract it targets (same
co-location rationale as the former in-repo MCP). A git-cloned marketplace
supports relative plugin sources, so the FabledScribe repo IS the marketplace.
- .claude-plugin/marketplace.json — source ./plugin
- plugin/.claude-plugin/plugin.json — userConfig (base URL, api key, project id)
- plugin/.mcp.json — http scribe server, ${user_config.*} substitution
- plugin/hooks/ — SessionStart push-channel hook (fail-open)
- plugin/skills/using-scribe — bootstrap skill
- plugin/README.md — install via the FabledScribe repo marketplace
Phase 2 of plan #755. Install/userConfig-substitution test pending.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "SCRIBE_URL=\"${user_config.api_endpoint}\" SCRIBE_TOKEN=\"${user_config.api_token}\" SCRIBE_PROJECT_ID=\"${user_config.project_id}\" bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scribe_session_context.sh\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Scribe plugin — SessionStart push channel.
|
||||
#
|
||||
# Curls the operator's Scribe instance for always-on rules + active-project
|
||||
# context and emits it as SessionStart `additionalContext`. Config comes from
|
||||
# plugin userConfig, passed in as env by hooks/hooks.json:
|
||||
# SCRIBE_URL base URL, no trailing slash (user_config.api_endpoint)
|
||||
# SCRIBE_TOKEN fmcp_ API key (user_config.api_token)
|
||||
# SCRIBE_PROJECT_ID optional numeric project id (user_config.project_id)
|
||||
#
|
||||
# FAIL-OPEN: any missing tool/config, network error, or unreachable instance
|
||||
# injects nothing and exits 0. A session must never be blocked by Scribe.
|
||||
set -uo pipefail
|
||||
|
||||
command -v jq >/dev/null 2>&1 || exit 0
|
||||
command -v curl >/dev/null 2>&1 || exit 0
|
||||
|
||||
url=${SCRIBE_URL:-}
|
||||
token=${SCRIBE_TOKEN:-}
|
||||
project_id=${SCRIBE_PROJECT_ID:-}
|
||||
[ -n "$url" ] && [ -n "$token" ] || exit 0
|
||||
|
||||
q=""
|
||||
[ -n "$project_id" ] && q="?project_id=${project_id}"
|
||||
|
||||
body=$(curl -fsS --max-time 8 \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
"${url%/}/api/plugin/context${q}" 2>/dev/null) || exit 0
|
||||
|
||||
text=$(printf '%s' "$body" | jq -r '.context // empty' 2>/dev/null) || exit 0
|
||||
[ -n "$text" ] || exit 0
|
||||
|
||||
jq -n --arg c "$text" \
|
||||
'{hookSpecificOutput: {hookEventName: "SessionStart", additionalContext: $c}}'
|
||||
exit 0
|
||||
Reference in New Issue
Block a user