feat: gated project experience & prompt intelligence
Implements the full gated session flow and prompt intelligence system: - Prisma schema: add gated, priority, summary, chapters, linkTarget fields - Session gate: state machine (gated → begin_session → ungated) with LLM-powered tool selection based on prompt index - Tag matcher: intelligent prompt-to-tool matching with project/server/action tags - LLM selector: tiered provider selection (fast for gating, heavy for complex tasks) - Link resolver: cross-project MCP resource references (project/server:uri format) - Prompt summary service: LLM-generated summaries and chapter extraction - System project bootstrap: ensures default project exists on startup - Structural link health checks: enrichWithLinkStatus on prompt GET endpoints - CLI: create prompt --priority/--link, create project --gated/--no-gated, describe project shows prompts section, get prompts shows PRI/LINK/STATUS - Apply/edit: priority, linkTarget, gated fields supported - Shell completions: fish updated with new flags - 1,253 tests passing across all packages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
# Erase any stale completions from previous versions
|
||||
complete -c mcpctl -e
|
||||
|
||||
set -l commands status login logout config get describe delete logs create edit apply backup restore mcp approve help
|
||||
set -l commands status login logout config get describe delete logs create edit apply patch backup restore mcp approve help
|
||||
set -l project_commands attach-server detach-server get describe delete logs create edit help
|
||||
|
||||
# Disable file completions by default
|
||||
@@ -29,18 +29,20 @@ end
|
||||
|
||||
# Helper: check if a resource type has been selected after get/describe/delete/edit
|
||||
set -l resources servers instances secrets templates projects users groups rbac prompts promptrequests
|
||||
# All accepted resource aliases (plural + singular + short forms)
|
||||
set -l resource_aliases servers server srv instances instance inst secrets secret sec templates template tpl projects project proj users user groups group rbac rbac-definition rbac-binding prompts prompt promptrequests promptrequest pr
|
||||
|
||||
function __mcpctl_needs_resource_type
|
||||
set -l tokens (commandline -opc)
|
||||
set -l found_cmd false
|
||||
for tok in $tokens
|
||||
if $found_cmd
|
||||
# Check if next token after get/describe/delete/edit is a resource type
|
||||
if contains -- $tok servers instances secrets templates projects users groups rbac prompts promptrequests
|
||||
# Check if next token after get/describe/delete/edit is a resource type or alias
|
||||
if contains -- $tok $resource_aliases
|
||||
return 1 # resource type already present
|
||||
end
|
||||
end
|
||||
if contains -- $tok get describe delete edit approve
|
||||
if contains -- $tok get describe delete edit patch
|
||||
set found_cmd true
|
||||
end
|
||||
end
|
||||
@@ -50,17 +52,34 @@ function __mcpctl_needs_resource_type
|
||||
return 1
|
||||
end
|
||||
|
||||
# Map any resource alias to the canonical plural form for API calls
|
||||
function __mcpctl_resolve_resource
|
||||
switch $argv[1]
|
||||
case server srv servers; echo servers
|
||||
case instance inst instances; echo instances
|
||||
case secret sec secrets; echo secrets
|
||||
case template tpl templates; echo templates
|
||||
case project proj projects; echo projects
|
||||
case user users; echo users
|
||||
case group groups; echo groups
|
||||
case rbac rbac-definition rbac-binding; echo rbac
|
||||
case prompt prompts; echo prompts
|
||||
case promptrequest promptrequests pr; echo promptrequests
|
||||
case '*'; echo $argv[1]
|
||||
end
|
||||
end
|
||||
|
||||
function __mcpctl_get_resource_type
|
||||
set -l tokens (commandline -opc)
|
||||
set -l found_cmd false
|
||||
for tok in $tokens
|
||||
if $found_cmd
|
||||
if contains -- $tok servers instances secrets templates projects users groups rbac prompts promptrequests
|
||||
echo $tok
|
||||
if contains -- $tok $resource_aliases
|
||||
__mcpctl_resolve_resource $tok
|
||||
return
|
||||
end
|
||||
end
|
||||
if contains -- $tok get describe delete edit approve
|
||||
if contains -- $tok get describe delete edit patch
|
||||
set found_cmd true
|
||||
end
|
||||
end
|
||||
@@ -75,6 +94,9 @@ function __mcpctl_resource_names
|
||||
# Instances don't have a name field — use server.name instead
|
||||
if test "$resource" = "instances"
|
||||
mcpctl get instances -o json 2>/dev/null | jq -r '.[][].server.name' 2>/dev/null
|
||||
else if test "$resource" = "prompts" -o "$resource" = "promptrequests"
|
||||
# Use -A to include all projects, not just global
|
||||
mcpctl get $resource -A -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null
|
||||
else
|
||||
mcpctl get $resource -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null
|
||||
end
|
||||
@@ -139,6 +161,7 @@ complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_
|
||||
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a apply -d 'Apply configuration from file'
|
||||
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a backup -d 'Backup configuration'
|
||||
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a restore -d 'Restore from backup'
|
||||
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a patch -d 'Patch a resource field'
|
||||
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a approve -d 'Approve a prompt request'
|
||||
complete -c mcpctl -n "not __mcpctl_has_project; and not __fish_seen_subcommand_from $commands" -a help -d 'Show help'
|
||||
|
||||
@@ -154,11 +177,11 @@ complete -c mcpctl -n "__mcpctl_has_project; and not __fish_seen_subcommand_from
|
||||
complete -c mcpctl -n "__mcpctl_has_project; and not __fish_seen_subcommand_from $project_commands" -a help -d 'Show help'
|
||||
|
||||
# Resource types — only when resource type not yet selected
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from get describe delete; and __mcpctl_needs_resource_type" -a "$resources" -d 'Resource type'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from edit; and __mcpctl_needs_resource_type" -a 'servers projects' -d 'Resource type'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from get describe delete patch; and __mcpctl_needs_resource_type" -a "$resources" -d 'Resource type'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from edit; and __mcpctl_needs_resource_type" -a 'servers secrets projects groups rbac prompts promptrequests' -d 'Resource type'
|
||||
|
||||
# Resource names — after resource type is selected
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from get describe delete edit approve; and not __mcpctl_needs_resource_type" -a '(__mcpctl_resource_names)' -d 'Resource name'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from get describe delete edit patch; and not __mcpctl_needs_resource_type" -a '(__mcpctl_resource_names)' -d 'Resource name'
|
||||
|
||||
# Helper: check if attach-server/detach-server already has a server argument
|
||||
function __mcpctl_needs_server_arg
|
||||
@@ -188,6 +211,8 @@ complete -c mcpctl -n "__fish_seen_subcommand_from detach-server; and __mcpctl_n
|
||||
|
||||
# get/describe options
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from get" -s o -l output -d 'Output format' -xa 'table json yaml'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from get" -l project -d 'Filter by project' -xa '(__mcpctl_project_names)'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from get" -s A -l all -d 'Show all resources across projects'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from describe" -s o -l output -d 'Output format' -xa 'detail json yaml'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from describe" -l show-values -d 'Show secret values'
|
||||
|
||||
@@ -217,7 +242,22 @@ complete -c mcpctl -n "__fish_seen_subcommand_from create; and not __fish_seen_s
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from $create_cmds" -a prompt -d 'Create an approved prompt'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and not __fish_seen_subcommand_from $create_cmds" -a promptrequest -d 'Create a prompt request'
|
||||
|
||||
# logs options
|
||||
# create prompt/promptrequest options
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from prompt promptrequest" -l project -d 'Project name' -xa '(__mcpctl_project_names)'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from prompt promptrequest" -l content -d 'Prompt content text' -x
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from prompt promptrequest" -l content-file -d 'Read content from file' -rF
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from prompt promptrequest" -l priority -d 'Priority 1-10' -xa '(seq 1 10)'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from prompt" -l link -d 'Link to MCP resource (project/server:uri)' -x
|
||||
|
||||
# create project --gated/--no-gated
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from project" -l gated -d 'Enable gated sessions'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from project" -l no-gated -d 'Disable gated sessions'
|
||||
|
||||
# logs: takes a server/instance name, then options
|
||||
function __mcpctl_instance_names
|
||||
mcpctl get instances -o json 2>/dev/null | jq -r '.[][].server.name' 2>/dev/null
|
||||
end
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from logs" -a '(__mcpctl_instance_names)' -d 'Server name'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from logs" -l tail -d 'Number of lines' -x
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from logs" -l since -d 'Since timestamp' -x
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from logs" -s f -l follow -d 'Follow log output'
|
||||
@@ -231,8 +271,52 @@ complete -c mcpctl -n "__fish_seen_subcommand_from restore" -s i -l input -d 'In
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from restore" -s p -l password -d 'Decryption password' -x
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from restore" -s c -l conflict -d 'Conflict strategy' -xa 'skip overwrite fail'
|
||||
|
||||
# approve: first arg is resource type (promptrequest only), second is name
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from approve; and __mcpctl_needs_resource_type" -a 'promptrequest' -d 'Resource type'
|
||||
# approve: first arg is resource type, second is name
|
||||
function __mcpctl_approve_needs_type
|
||||
set -l tokens (commandline -opc)
|
||||
set -l found false
|
||||
for tok in $tokens
|
||||
if $found
|
||||
if contains -- $tok promptrequest promptrequests
|
||||
return 1 # type already given
|
||||
end
|
||||
end
|
||||
if test "$tok" = "approve"
|
||||
set found true
|
||||
end
|
||||
end
|
||||
if $found
|
||||
return 0 # approve found but no type yet
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function __mcpctl_approve_needs_name
|
||||
set -l tokens (commandline -opc)
|
||||
set -l found_type false
|
||||
for tok in $tokens
|
||||
if $found_type
|
||||
# next non-flag token after type is the name
|
||||
if not string match -q -- '-*' $tok
|
||||
return 1 # name already given
|
||||
end
|
||||
end
|
||||
if contains -- $tok promptrequest promptrequests
|
||||
set found_type true
|
||||
end
|
||||
end
|
||||
if $found_type
|
||||
return 0 # type given but no name yet
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function __mcpctl_promptrequest_names
|
||||
mcpctl get promptrequests -A -o json 2>/dev/null | jq -r '.[][].name' 2>/dev/null
|
||||
end
|
||||
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from approve; and __mcpctl_approve_needs_type" -a 'promptrequest' -d 'Resource type'
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from approve; and __mcpctl_approve_needs_name" -a '(__mcpctl_promptrequest_names)' -d 'Prompt request name'
|
||||
|
||||
# apply takes a file
|
||||
complete -c mcpctl -n "__fish_seen_subcommand_from apply" -s f -l file -d 'Configuration file' -rF
|
||||
|
||||
Reference in New Issue
Block a user