Re-engineer the maister-copilot generator into a runnable Copilot CLI plugin - #10
Open
robmar-net wants to merge 9 commits into
Open
Re-engineer the maister-copilot generator into a runnable Copilot CLI plugin#10robmar-net wants to merge 9 commits into
robmar-net wants to merge 9 commits into
Conversation
…est/branding Replace the flat s/maister:/maister-/g with a registry-driven, kind-aware reference rewrite: agent refs -> maister-copilot:<name> (plugin-id namespaced), skill/command refs -> bare <name>. Fail-loud on unknown tokens; compound illustrative tokens (maister:x:y) handled in-generator so the Claude source stays 100% untouched. Stop deleting hooks/ (Claude-format hooks.json fires as-is on Copilot). Fix plugin.json description, the ask_user ordering tautology, the .claude/CLAUDE.md path garble, and Claude-Code branding residue. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extend validate with checks for wrong maister-<word> refs, string argument-hint, hooks/ presence, and Claude-Code residue. Add check-deterministic (byte-identical rebuild) and test-copilot (runs the WS7 harness) targets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Load the freshly-built plugin into a live Copilot CLI and assert 7 runtime contracts (plugin/skills/agents register, task+skill delegation, hooks fire, mcp loads). Emits a version-stamped report; supports an auth-free subset. Side-effect-free (isolation trap restores the operator config). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a compat job that runs the harness when a Copilot seat is provisioned (fails on any red contract, uploads the report), else skips with build+validate still gating. Purely additive; the build job is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 23, 2026
Merged
…residual in validate The committed maister-copilot output carried un-converted AskUserQuestion in 8 skill files (a non-existent tool on Copilot) — the regenerate commit captured a stale tree. A clean rebuild converts them to ask_user. Add a validate check (WS5.9) forbidding AskUserQuestion residual in skills/commands/agents so this class of staleness fails the build instead of shipping. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot's PreToolUse hook payload carries no agent identifier (verified live on 1.0.73 — not in stdin, not in any Copilot env var), so the Claude guard's subagent-scoped agent_type gating is a silent no-op there. Ship a Copilot-specific override that asks the user to confirm any destructive command (permissionDecision "ask") — Copilot honors it and does NOT bypass it under --allow-all-tools (held in headless = fail-closed). Better than the no-op (no protection) and than a blanket deny (which would block the main agent's legitimate destructive commands). build.sh (WS2b) overlays platforms/copilot-cli/hooks-overrides/ over the output hook; the Claude source hook stays untouched. make validate WS5.10 guards it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
L0 proves the three maister hooks fire; L1 verifies each hook's EFFECT and honestly reports no-ops. Findings on Copilot CLI 1.0.73: - skill-invocation-reminder: PASS (additionalContext injected). - post-compact-reminder: env dep satisfied — Copilot sets $CLAUDE_PROJECT_DIR in the hook env (verified under a sanitized env); compact matcher unverified. - block-destructive-commands: LIMITATION — Copilot's PreToolUse payload omits any agent identifier, so the subagent-scoped guard never triggers (deny IS honored and tool_input.command matches; only the agent gating is inert). Detection only — hooks unchanged. Side-effect-free; --no-live subset for CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uirement) Pin actions/upload-artifact@v4 -> @ea165f8d65b6e75b540449e92b4886f43607fa02 (v4.6.2) so the repo can enforce sha_pinning_required in Actions settings without breaking this workflow. Supply-chain hardening: a moved/compromised v4 tag can no longer silently change what runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DxhRYoDBTTtWoKG1h7sH5t
Author
|
Update — three commits added to this PR (all still Copilot-only; the Claude
All verified against Copilot CLI 1.0.73: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Re-engineers the
maister-copilotgenerator (platforms/copilot-cli/build.sh+Makefile+ CI) so the generated plugin is a runnable, coherent GitHub Copilot CLI plugin — not just an installable one. All changes are generator-side; the Claudeplugins/maister/source is 100% untouched.Why
An initial documentation-based analysis (see #8) concluded the port "was not faithfully runnable and needed re-engineering of the orchestration layer." Live testing against a real GitHub Copilot CLI 1.0.73 overturned that:
maister-copilotis runnable, and maister's orchestration maps onto Copilot's primitives almost 1:1:Task(subagent_type: "maister:X")task(agent_type: "maister-copilot:X")Skill("X")skill("X")task mode:"background"+read_agent/list_agentsAskUserQuestionask_userhooks/hooks.json(${CLAUDE_PLUGIN_ROOT})hooks.json, same format.mcp.json,agents/*.md,skills/*/SKILL.mdmaister-copilot:<name>)So the real defects were narrow and all generator-side: wrong reference naming and the generator deleting
hooks/.What changed
s/maister:/maister-/g— which mangled every reference — is replaced by a registry-driven, kind-aware rewrite: agent refs →maister-copilot:<name>(plugin-id namespaced), skill/command refs → bare<name>. Name-set registries are built from the source tree with a pairwise-disjointness assertion, and the pass fails loud on any unknown token. Illustrative compound tokens (maister:x:y, e.g. product-design's/maister:feature:new"does-not-exist" example) are handled in-generator, so the Claude source needs no edit.rm -rf "$OUT/hooks". The Claude-formathooks.json(incl.${CLAUDE_PLUGIN_ROOT},SessionStart+PreToolUse) fires unchanged on Copilot — dropping it was a needless functional + safety regression (it includes the destructive-command guard).plugin.jsondescription → "…for GitHub Copilot CLI" (targeted string edit, no JSON round-trip); fixed the "Useask_userinstead ofask_user" ordering tautology; hardened the.claude/CLAUDE.mdpath rewrite; scrubbed "Claude Code" branding/URLs.make validatehardening: new static checks (no wrongmaister-<word>refs, stringargument-hint,hooks/present, no Claude-Code residue) + acheck-deterministictarget (byte-identical rebuild).platforms/copilot-cli/compat-tests/,make test-copilot): loads the freshly-built plugin into a live Copilot CLI and asserts 7 runtime contracts (plugin/skills/agents register,task+skilldelegation, hooks fire, MCP loads); emits a version-stamped report; side-effect-free; supports an auth-free subset.compatjob runs the harness when a Copilot seat is provisioned (fails on any red contract), else skips withbuild+validatestill gating. Purely additive — the existingbuildjob is unchanged.How it was tested
On GitHub Copilot CLI 1.0.73:
make build✅ ·make validate✅ (existing 6 + new checks) ·make check-deterministic✅ (byte-identical rebuild) · provenance: onlybuild.sh/Makefile/build-copilot.yml+ newcompat-tests/are source edits.make test-copilot→ GREEN, 7 PASS · 0 FAIL (plugin loads; 17 skills register, 0 failures; 25 agents resolve asmaister-copilot:<name>;task(agent_type)delegation executes;skill(<name>)executes;SessionStart+PreToolUsehooks fire with${CLAUDE_PLUGIN_ROOT};.mcp.jsonloads).Notes
plugins/maister/(the Claude plugin) has zero changes; rebuilds are byte-identical, so the existing CI auto-commit stays a no-op.plugins/maister-copilot/**is included so the branch is self-consistent (matches the repo's "Rebuild Copilot CLI variant" convention).task/skill); capability and addressability are proven, determinism is inherently softer than Claude's Task tool.Refs #8, #9
🤖 Generated with Claude Code