feat(plugin): add /api/plugin/context push-channel endpoint + dogfood hook
Phase 1 of plan #755 (Scribe-as-plugin). Gives Scribe its own session-start push channel so always-on rules + active-project context surface without being asked — the gap behind 'I have to prompt for everything'. - services/plugin_context.build_session_context: renders always-on rule titles grouped by topic (under the 10k additionalContext cap; full text stays one list_always_on_rules/get_rule call away) + optional project goal/open-task count + a recall/update-over-create reflex line. Capped at 9000 chars. - routes/plugin GET /api/plugin/context (login_required already accepts Bearer fmcp_ keys; read scope suffices). - tests: titles-not-statements, project scoping, length cap (pure mocks). - scripts/scribe_session_context.sh: dogfood SessionStart hook, fail-open, reads url+token from .mcp.json. Superseded in Phase 2 by the plugin-bundled hook using userConfig. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
"""Scribe-plugin support endpoints.
|
||||
|
||||
Consumed by the Scribe Claude Code plugin (not the web UI). `GET /api/plugin/
|
||||
context` is curled by the plugin's SessionStart hook to push the operator's
|
||||
always-on rules + active-project context into the session — Scribe's own push
|
||||
channel. Auth is the standard `@login_required` path, which accepts a `Bearer
|
||||
fmcp_<key>` API key (a read-scoped key suffices for this GET).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from quart import Blueprint, g, jsonify, request
|
||||
|
||||
from scribe.auth import login_required
|
||||
from scribe.services import plugin_context as plugin_ctx_svc
|
||||
|
||||
plugin_bp = Blueprint("plugin", __name__, url_prefix="/api/plugin")
|
||||
|
||||
|
||||
@plugin_bp.get("/context")
|
||||
@login_required
|
||||
async def session_context():
|
||||
"""Return SessionStart context (always-on rules + optional project).
|
||||
|
||||
Query: project_id (optional int) — when set, includes that project's goal
|
||||
and open-task count. The hook passes the bound project's id here.
|
||||
"""
|
||||
try:
|
||||
project_id = int(request.args.get("project_id", 0) or 0)
|
||||
except (TypeError, ValueError):
|
||||
project_id = 0
|
||||
result = await plugin_ctx_svc.build_session_context(g.user.id, project_id)
|
||||
return jsonify(result)
|
||||
Reference in New Issue
Block a user