From bf1ed40fbfa0e15d843a108cee81b485495a64c7 Mon Sep 17 00:00:00 2001 From: jsburckhardt Date: Mon, 6 Apr 2026 03:19:46 +0000 Subject: [PATCH 1/3] feat: update Agnostic Prompt Standard skill to v1.2.1 Updates APS agent from v1.1.16 to v1.2.1, adds generic platform adapter, MCP tool bridge composite example, and subagent architecture guide. Refreshes all platform adapters and references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...s-v1.1.16.agent.md => aps-v1.2.1.agent.md} | 4 +- .../skills/agnostic-prompt-standard/SKILL.md | 15 +- .../mcp-tool-bridge-v1.0.0.example.md | 112 +++++++++++++ .../subagent-architecture-v1.0.0.guide.md | 146 +++++++++++++++++ .../platforms/README.md | 37 ++++- .../platforms/_template/adaptor.md | 26 ++- .../platforms/claude-code/adaptor.md | 151 +++++++++++------ .../agents/{aps-v1.1.16.md => aps-v1.2.1.md} | 4 +- .../platforms/generic/adaptor.md | 63 ++++++++ .../platforms/opencode/adaptor.md | 152 ++++++++++++++++- .../platforms/vscode-copilot/adaptor.md | 153 ++++++++++++------ ...s-v1.1.16.agent.md => aps-v1.2.1.agent.md} | 4 +- .../references/03-agentic-control.md | 29 ++++ .../references/04-schemas-and-types.md | 60 +++++++ 14 files changed, 833 insertions(+), 123 deletions(-) rename .github/agents/{aps-v1.1.16.agent.md => aps-v1.2.1.agent.md} (98%) create mode 100644 .github/skills/agnostic-prompt-standard/assets/composites/mcp-tool-bridge-v1.0.0.example.md create mode 100644 .github/skills/agnostic-prompt-standard/guides/subagent-architecture-v1.0.0.guide.md rename .github/skills/agnostic-prompt-standard/platforms/claude-code/templates/.claude/agents/{aps-v1.1.16.md => aps-v1.2.1.md} (98%) create mode 100644 .github/skills/agnostic-prompt-standard/platforms/generic/adaptor.md rename .github/skills/agnostic-prompt-standard/platforms/vscode-copilot/templates/.github/agents/{aps-v1.1.16.agent.md => aps-v1.2.1.agent.md} (98%) diff --git a/.github/agents/aps-v1.1.16.agent.md b/.github/agents/aps-v1.2.1.agent.md similarity index 98% rename from .github/agents/aps-v1.1.16.agent.md rename to .github/agents/aps-v1.2.1.agent.md index 5fe4f29..563daa1 100644 --- a/.github/agents/aps-v1.1.16.agent.md +++ b/.github/agents/aps-v1.2.1.agent.md @@ -1,6 +1,6 @@ --- -name: APS v1.1.16 Agent -description: "Generate APS v1.1.16 .agent.md or .prompt.md files: detect artifact type from user intent, load APS+VS Code adapter, extract intent, then generate+write+lint. Author: Christopher Buckley. Co-authors: Juan Burckhardt, Anastasiya Smirnova. URL: https://github.com/chris-buckley/agnostic-prompt-standard" +name: APS v1.2.1 Agent +description: "Generate APS v1.2.1 .agent.md or .prompt.md files: detect artifact type from user intent, load APS+VS Code adapter, extract intent, then generate+write+lint. Author: Christopher Buckley. Co-authors: Juan Burckhardt, Anastasiya Smirnova. URL: https://github.com/chris-buckley/agnostic-prompt-standard" tools: - execute/runInTerminal - read/readFile diff --git a/.github/skills/agnostic-prompt-standard/SKILL.md b/.github/skills/agnostic-prompt-standard/SKILL.md index a2af341..f471e2d 100644 --- a/.github/skills/agnostic-prompt-standard/SKILL.md +++ b/.github/skills/agnostic-prompt-standard/SKILL.md @@ -7,8 +7,8 @@ metadata: author: "Christopher Buckley" co_authors: "Juan Burckhardt; Anastasiya Smirnova" spec_version: "1.0" - framework_revision: "1.1.16" - last_updated: "2026-02-18" + framework_revision: "1.2.1" + last_updated: "2026-03-12" --- # Agnostic Prompt Standard (APS) v1.0 — Skill Entry @@ -38,6 +38,9 @@ This `SKILL.md` is the **entrypoint** for the Agnostic Prompt Standard (APS) v1. - `constants-json-block-v1.0.0.example.md` - `constants-text-block-v1.0.0.example.md` - `constants-csv-block-v1.0.0.example.md` + - `composites/` — combined reference examples. + - `gui-component-spec-v1.0.0.example.md` + - `mcp-tool-bridge-v1.0.0.example.md` - `formats/` — example format blocks. - `format-code-changes-full-v1.0.0.example.md` - `format-code-map-v1.0.0.example.md` @@ -56,12 +59,16 @@ This `SKILL.md` is the **entrypoint** for the Agnostic Prompt Standard (APS) v1. - `build-skill.md` — process for building new APS-compliant skills. - `guides/` — reference documents for humans and agents. - `skill-authoring-v1.0.0.guide.md` — skill authoring reference. + - `mcp-tool-bridge-v1.0.0.guide.md` — MCP tool bridge integration guide. + - `subagent-architecture-v1.0.0.guide.md` — cross-platform subagent architecture and interface mapping guide. - `platforms/` — **non-normative** platform adapters. Each platform has a single `adaptor.md` file. - `README.md` — platforms overview and contract. - `_template/` — skeleton for new platform adapters. - `adaptor.md` - `claude-code/` — Claude Code CLI adapter. - `adaptor.md` — platform constants, tool registry, and format contracts. + - `generic/` — generic / external tools adapter. + - `adaptor.md` — neutral tool mapping guidance for MCP or other external tool layers. - `opencode/` — OpenCode adapter. - `adaptor.md` — platform constants. - `vscode-copilot/` — VS Code + GitHub Copilot adapter. @@ -72,10 +79,12 @@ This `SKILL.md` is the **entrypoint** for the Agnostic Prompt Standard (APS) v1. ## Platform adapters -Platform-specific details (file discovery, frontmatter dialects, tool naming) are documented in `platforms/`. +Platform-specific details (file discovery, frontmatter dialects, tool naming, and coordinator/worker orchestration) are documented in `platforms/`. → See [platforms/README.md](platforms/README.md) for overview and how to add new adapters. +→ See [guides/subagent-architecture-v1.0.0.guide.md](guides/subagent-architecture-v1.0.0.guide.md) for portable coordinator/worker authoring guidance. + ### VS Code + GitHub Copilot The initial adapter for VS Code + GitHub Copilot is at `platforms/vscode-copilot/`. diff --git a/.github/skills/agnostic-prompt-standard/assets/composites/mcp-tool-bridge-v1.0.0.example.md b/.github/skills/agnostic-prompt-standard/assets/composites/mcp-tool-bridge-v1.0.0.example.md new file mode 100644 index 0000000..00d3b44 --- /dev/null +++ b/.github/skills/agnostic-prompt-standard/assets/composites/mcp-tool-bridge-v1.0.0.example.md @@ -0,0 +1,112 @@ + + +# MCP tool bridge example + +This example shows how to bridge one MCP tool into APS without putting host config in the prompt. + +## 1. Raw MCP Tool (`tools/list` result) + +```json +{ + "name": "search_docs", + "title": "Search Docs", + "description": "Search the documentation site.", + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Search text" + } + }, + "required": ["query"] + }, + "outputSchema": { + "type": "object", + "properties": { + "matches": { + "type": "array" + } + } + }, + "annotations": { + "readOnlyHint": true, + "destructiveHint": false, + "idempotentHint": true, + "openWorldHint": true + } +} +``` + +## 2. Canonical `predefinedTools.json` entry + +```json +[ + { + "name": "search_docs", + "displayName": "Search Docs", + "description": "Search the documentation site.", + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Search text" + } + }, + "required": ["query"] + }, + "outputSchema": { + "type": "object", + "properties": { + "matches": { + "type": "array" + } + } + }, + "hints": { + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "source": { + "kind": "mcp", + "server": "docs", + "toolName": "search_docs" + } + } +] +``` + +## 3. Host alias in `config.json` + +Use `config.json` only when the host exposes a decorated runtime name. + +```json +{ + "alias": { + "mcp__docs__search_docs": "search_docs" + } +} +``` + +## 4. APS process excerpt + +```text + +USE `search_docs` where: query=QUERY +CAPTURE RESULTS from `search_docs` +RETURN: RESULTS + +``` + +## Notes + +- `search_docs` is the canonical APS tool id. +- The prompt stays neutral. It does not include transport or host config. +- The host-specific runtime name stays in external config. +- The engine can resolve the alias before tool execution. diff --git a/.github/skills/agnostic-prompt-standard/guides/subagent-architecture-v1.0.0.guide.md b/.github/skills/agnostic-prompt-standard/guides/subagent-architecture-v1.0.0.guide.md new file mode 100644 index 0000000..173cadb --- /dev/null +++ b/.github/skills/agnostic-prompt-standard/guides/subagent-architecture-v1.0.0.guide.md @@ -0,0 +1,146 @@ + +You MUST load this guide before you author coordinator and worker agents. +You MUST model portable multi-agent systems as one coordinator and one or more leaf workers. +You MUST define the worker block as the public request contract into the worker. +You MUST mirror each worker field in the caller dispatch process arguments. +You MUST define a worker response contract in and capture it in the caller. +You MUST keep platform-specific invocation syntax inside the caller dispatch layer only. +You MUST use explicit allowlists for worker selection and tool access. +You MUST keep worker results task-bounded, typed, and brief. +You SHOULD use handoffs instead of nested worker spawning when a platform supports handoffs. +You SHOULD treat undocumented nested delegation as unsupported for portable APS authoring. +You MUST treat Claude Code workers as leaf workers. +You SHOULD treat VS Code Copilot and OpenCode workers as leaf workers for portable APS authoring. + + + +GUIDE_VERSION: "1.0.0" + +PLATFORM_CAPABILITY_MATRIX: CSV<< +platform,coordinator_role,worker_role,documented_depth_policy,invocation_surface,notes +claude-code,main-thread agent only,markdown subagent,depth-1-only,Agent,"Workers cannot spawn workers." +vscode-copilot,main chat agent or prompt,subagent or custom agent worker,portable-depth-1,agent/runSubagent,"Custom-agent subagents are experimental and nested delegation is not documented." +opencode,primary agent,mode=subagent worker,portable-depth-1,Task,"Primary/subagent roles are documented and nested delegation is not documented." +generic,host-defined or manual APS coordinator,host-defined or external worker,host-defined,host-defined,"Use explicit APS dispatch processes when host behavior is unclear." +>> + +REQUEST_INTERFACE_RULES: TEXT<< +1. The worker block is the public interface into the worker. +2. The caller dispatch process MUST accept the same fields, names, and meanings. +3. If a platform needs renamed fields, keep the rename in the dispatch layer only. +4. Do not hide required worker inputs inside free-form prompt text. +5. Keep request types stable across platforms. +>> + +RESPONSE_INTERFACE_RULES: TEXT<< +1. The worker MUST return a typed result that matches a contract. +2. The caller MUST capture the worker result before the next step starts. +3. Keep summaries brief and task-bounded. +4. Do not leak platform-only metadata unless the caller explicitly asks for it. +>> + +PORTABLE_PATTERNS: JSON<< +{ + "coordinator_worker": { + "description": "One coordinator dispatches one worker and integrates the worker result.", + "best_for": ["single specialty task", "strong contract boundaries"] + }, + "fan_out_review": { + "description": "One coordinator dispatches multiple leaf workers in parallel and then compares typed results.", + "best_for": ["research", "review", "verification"] + }, + "sequential_handoff": { + "description": "One worker finishes, returns a typed result, and the coordinator hands off the next step to a different worker.", + "best_for": ["plan -> implement", "implement -> review"] + } +} +>> + +ANTI_PATTERNS: TEXT<< +- Worker-to-worker recursion without a documented host contract. +- Free-form worker prompts with hidden required fields. +- Caller processes that rename or reshape worker inputs in multiple places. +- Worker outputs that mix summary text, hidden state, and untyped data. +- Broad tool access for narrow workers. +>> + +APS_INTERFACE_EXAMPLE: TEXT<< +Worker contract: + +TICKET_ID: String +TARGET_PATHS: String[] + + +Caller dispatch process: + +USE `Agent` where: description="Review the requested files", prompt="Review the requested files", worker="reviewer" +SET WORKER_REQUEST := { TICKET_ID: TICKET_ID, TARGET_PATHS: TARGET_PATHS } +CAPTURE REVIEW_RESULT from `reviewer` +RETURN: REVIEW_RESULT + + +Rule: +- The caller args are the same interface as the worker input. +- The caller is responsible for the platform-specific call surface. +- The worker returns a typed result that the caller captures. +>> + +BIDIRECTIONAL_CONTRACT_RULE: TEXT<< +Request flow: caller process args -> worker . +Response flow: worker result -> caller capture variables. +The contract is bidirectional only when the caller defines both mappings explicitly. +>> + + + + +# Subagent Architecture Spec: + +## Coordinator +- Role: +- Dispatch surface: +- Depth policy: + +## Workers +| Worker | Role | Input contract | Output contract | Allowed tools | Notes | +|--------|------|----------------|-----------------|---------------|-------| +| | | | | | | + +## Request and response mapping + + +## Failure policy + + +WHERE: +- is String; comma-separated logical or host tool ids allowed for the worker. +- is String; descriptive name for the coordinator/worker design. +- is String; the coordinator responsibility statement. +- is String; one of depth-1-only, portable-depth-1, host-defined. +- is String; host invocation surface such as Agent, agent/runSubagent, Task, or manual APS process. +- is Markdown; what the coordinator does when a worker fails, times out, or returns invalid data. +- is String; id or label of the worker request contract. +- is String; id or label of the worker response contract. +- is Markdown; explicit mapping from caller args to worker input and from worker result to caller capture. +- is String; worker identifier. +- is String; short notes about visibility, allowlists, or platform limits. +- is String; worker responsibility statement. + + + +# Subagent Contract Checklist + +- [ ] The coordinator is the single dispatch owner. +- [ ] Each worker has an explicit APS contract. +- [ ] Each caller dispatch process mirrors the worker input fields one-for-one. +- [ ] Each worker returns a typed result. +- [ ] The caller captures the worker result before the next step starts. +- [ ] Nested delegation is either documented by the host or avoided. +- [ ] Worker tool access uses least privilege. +- [ ] Worker visibility and allowlists are explicit. +- [ ] Platform-only routing details stay outside the portable contract. + +WHERE: +- This checklist is a fixed review format with no placeholders. + + diff --git a/.github/skills/agnostic-prompt-standard/platforms/README.md b/.github/skills/agnostic-prompt-standard/platforms/README.md index ea6173a..e4aeac7 100644 --- a/.github/skills/agnostic-prompt-standard/platforms/README.md +++ b/.github/skills/agnostic-prompt-standard/platforms/README.md @@ -2,10 +2,11 @@ APS is designed to be **platform-agnostic**, but real hosts (IDEs, agent runtimes, CI bots) differ in: -- File discovery conventions (where prompts/agents/skills live) -- YAML frontmatter dialects (which fields exist, required/optional) +- File discovery conventions (where prompts, agents, and skills live) +- YAML frontmatter dialects (which fields exist and which are optional) - Tool availability, naming, and approval UX - Safety constraints (auto-approve settings, restricted file paths) +- Multi-agent orchestration surfaces (how a coordinator invokes workers) This folder contains **platform adapters** that describe those differences *without changing the APS v1.0 spec*. @@ -23,28 +24,50 @@ platforms/ templates/ # optional installable agent files .claude/agents/ # (claude-code) or .github/agents/ # (vscode-copilot) + # no templates/ # (generic / external tools) ``` The `adaptor.md` file contains three APS sections: 1. `` — platform-specific generation instructions -2. `` — all metadata: platform ID, detection markers, file conventions, tool registries, agent versioning +2. `` — metadata such as platform ID, detection markers, file conventions, subagent depth policy, and tool registries 3. `` — frontmatter and output format contracts +The `generic/` adapter is the neutral option for tool-agnostic or external-tool-only workflows. +It has no detection markers and no installable templates. + +## Subagent authoring contract + +Adapters should document the host-specific orchestration surface for coordinator and worker authoring. +At minimum, an adapter should state: + +- which artifact type is the coordinator +- which artifact type is the worker +- which tool or surface invokes the worker +- the documented depth policy +- how APS worker `` maps to caller dispatch args +- how worker outputs are captured back into the caller + +If nested delegation is undocumented, the adapter should default to **portable depth-1 authoring**. +That means one coordinator dispatches leaf workers, and all platform-specific routing stays in the caller dispatch layer. + +→ See [`guides/subagent-architecture-v1.0.0.guide.md`](../guides/subagent-architecture-v1.0.0.guide.md) + ## Add a new platform adapter 1. Copy `platforms/_template/` to `platforms//` 2. Fill in `adaptor.md` with platform-specific constants and formats -3. Optionally add a `templates/` directory with installable agent files -4. Do **not** change `references/` unless you are intentionally publishing an APS spec revision +3. Document coordinator/worker roles, dispatch surface, and depth policy +4. Optionally add a `templates/` directory with installable agent files +5. Do **not** change `references/` unless you are intentionally publishing an APS spec revision ## Contract - Anything under `references/` is **normative** APS. -- Anything under `platforms/` is **non-normative** (documentation/templates/mappings only). +- Anything under `platforms/` is **non-normative** (documentation, templates, and mappings only). - Adapters should prefer **mapping + configuration** over rewriting APS core rules. -## Scope and Philosophy +## Scope and philosophy Adapters are intended to **map** the APS standard to a host platform. They are **not** project generators. We do not provide generic project scaffolding (like `settings.json` or root `CLAUDE.md` templates). diff --git a/.github/skills/agnostic-prompt-standard/platforms/_template/adaptor.md b/.github/skills/agnostic-prompt-standard/platforms/_template/adaptor.md index 9e79355..050c580 100644 --- a/.github/skills/agnostic-prompt-standard/platforms/_template/adaptor.md +++ b/.github/skills/agnostic-prompt-standard/platforms/_template/adaptor.md @@ -1,20 +1,38 @@ Replace this section with platform-specific generation instructions. -Describe tool naming conventions, file locations, and frontmatter rules. +Describe tool naming conventions, file locations, frontmatter rules, and MCP config surfaces when applicable. +Document how a coordinator invokes workers on this host. +Map each worker APS `` field to the caller dispatch args. +If nested delegation is undocumented, default to portable depth-1 authoring. PLATFORM_ID: "your-platform-id" DISPLAY_NAME: "Your Platform" -ADAPTER_VERSION: "0.1.0" +ADAPTER_VERSION: "0.2.0" LAST_UPDATED: "YYYY-MM-DD" -INSTRUCTION_FILE_PATHS: [".github/copilot-instructions.md"] +SUBAGENT_AUTHORING_GUIDE: "guides/subagent-architecture-v1.0.0.guide.md" + +SUBAGENT_ARCHITECTURE: JSON<< +{ + "coordinator_role": "Describe the coordinator artifact or surface.", + "worker_role": "Describe the worker artifact or surface.", + "depth_policy": "host-defined-or-portable-depth-1", + "documented_limit": "Describe documented nesting limits or say not documented.", + "invocation_surface": "Describe the tool, command, handoff, or API that invokes the worker.", + "request_contract_rule": "Worker is the public request interface and the caller mirrors it in dispatch args.", + "response_contract_rule": "Worker returns a typed result and the caller captures it before the next step.", + "portability_rule": "Keep host-specific routing in the caller dispatch layer only." +} +>> +INSTRUCTION_FILE_PATHS: [".github/copilot-instructions.md"] DETECTION_MARKERS: [".github/agents/", "path/to/marker.file"] +MCP_CONFIG_PATHS: [] DOCS_HOME_URL: "https://example.com/docs" - \ No newline at end of file + diff --git a/.github/skills/agnostic-prompt-standard/platforms/claude-code/adaptor.md b/.github/skills/agnostic-prompt-standard/platforms/claude-code/adaptor.md index b6b2343..3024c39 100644 --- a/.github/skills/agnostic-prompt-standard/platforms/claude-code/adaptor.md +++ b/.github/skills/agnostic-prompt-standard/platforms/claude-code/adaptor.md @@ -7,30 +7,70 @@ Rules are stored in .claude/rules/*.md with optional path-scoped YAML frontmatte File imports use @path syntax (e.g., @README.md, @docs/guide.md, @~/.claude/shared-rules.md). Hooks execute shell commands at lifecycle events and are configured in .claude/settings.json. Permissions use Tool(specifier) with allow/deny/ask arrays in .claude/settings.json. +Claude Code stores project-scoped MCP servers in .mcp.json at the project root and user/local MCP servers in ~/.claude.json. Tools in frontmatter are comma-separated strings (e.g., tools: Read, Write, Edit). +You MUST load `guides/subagent-architecture-v1.0.0.guide.md` before authoring coordinator or worker agents. +You MUST treat `.claude/agents/*.md` worker agents as leaf workers because Claude subagents cannot spawn subagents. +You MUST map worker APS `` fields to caller dispatch process args one-for-one. PLATFORM_ID: "claude-code" DISPLAY_NAME: "Claude Code CLI" -ADAPTER_VERSION: "2.0.0" -LAST_UPDATED: "2026-02-19" +ADAPTER_VERSION: "2.1.0" +LAST_UPDATED: "2026-03-12" + +ARTIFACT_TYPES: CSV<< +type,file_pattern,config_format +agent,.claude/agents/*.md,CC_AGENT_FRONTMATTER_V1 +rules,.claude/rules/*.md,CC_RULES_FRONTMATTER_V1 +hooks,.claude/settings.json,CC_HOOKS_CONFIG_V1 +permissions,.claude/settings.json,CC_PERMISSIONS_CONFIG_V1 +>> + +SUBAGENT_AUTHORING_GUIDE: "guides/subagent-architecture-v1.0.0.guide.md" + +SUBAGENT_ARCHITECTURE: JSON<< +{ + "coordinator_role": "Main-thread agent only", + "worker_role": "Markdown-defined subagent in .claude/agents/*.md", + "depth_policy": "depth-1-only", + "documented_limit": "Subagents cannot spawn other subagents.", + "invocation_tool": "Agent", + "invocation_aliases": ["Task"], + "allowlist_surface": "tools: Agent(worker, reviewer)", + "definition_paths": ["./.claude/agents/*.md", "~/.claude/agents/*.md"], + "defaults": { + "model": "inherit when omitted", + "tools": "inherit all tools when omitted", + "skills": "do not inherit; list explicitly", + "permissionMode": "inherits current permission context unless overridden" + }, + "request_contract_rule": "Author each worker as the public request interface and mirror it in the caller dispatch process args.", + "response_contract_rule": "Return a typed result and capture it in the caller before the next step.", + "portability_rule": "Author Claude workers as leaf workers. Keep all platform-specific Agent wiring in the caller dispatch layer." +} +>> INSTRUCTION_FILE_PATHS: ["./CLAUDE.md", "./.claude/CLAUDE.md", "./.claude/rules/*.md", "./CLAUDE.local.md", "~/.claude/CLAUDE.md", "~/.claude/rules/*.md"] AGENT_FILE_PATHS: ["./.claude/agents/*.md", "~/.claude/agents/*.md"] -MCP_CONFIG_PATHS: ["./.mcp.json"] +MCP_CONFIG_PATHS: ["./.mcp.json", "~/.claude.json"] SETTINGS_FILE_PATHS: ["./.claude/settings.json", "./.claude/settings.local.json", "~/.claude/settings.json"] MEMORY_LOAD_ORDER: [INSTRUCTION_FILE_PATHS, AGENT_FILE_PATHS, MCP_CONFIG_PATHS, SETTINGS_FILE_PATHS] DETECTION_MARKERS: [".claude", "CLAUDE.md", "CLAUDE.local.md", ".mcp.json", ".claude/settings.json", ".claude/agents", ".claude/rules"] +CONFIG_SCOPES: ["managed", "user", "project", "local"] +SUBAGENT_MEMORY_SCOPES: ["user", "project", "local"] +SUBAGENT_RUN_MODES: ["foreground", "background"] + MEMORY_LEVEL_ENTERPRISE: "Managed by organization admins." MEMORY_LEVEL_PROJECT: ["./CLAUDE.md", "./.claude/CLAUDE.md"] MEMORY_LEVEL_RULES: ["./.claude/rules/*.md"] MEMORY_LEVEL_USER: ["~/.claude/CLAUDE.md", "./CLAUDE.local.md"] MEMORY_OVERRIDE_ORDER: [MEMORY_LEVEL_ENTERPRISE, MEMORY_LEVEL_PROJECT, MEMORY_LEVEL_RULES, MEMORY_LEVEL_USER] -HOOK_EVENTS: ["PreToolUse", "PostToolUse", "PermissionRequest", "Stop", "SubagentStop", "UserPromptSubmit", "SessionStart", "SessionEnd", "PreCompact", "Notification"] +HOOK_EVENTS: ["PreToolUse", "PostToolUse", "PermissionRequest", "Stop", "SubagentStart", "SubagentStop", "UserPromptSubmit", "SessionStart", "SessionEnd", "PreCompact", "Notification"] HOOK_CONFIG_PATH: ".claude/settings.json" TOOL_NAMING_STYLE: "PascalCase" @@ -40,33 +80,34 @@ TOOL_FRONTMATTER_SYNTAX: "comma-separated strings (e.g., tools: Read, Write, Edi TOOLS: CSV<< name,toolset,risk,side_effects,description,params -Read,filesystem,low,reads,"Read file contents. Supports text/images/PDFs/notebooks.","[file_path:string:required, offset:integer:optional, limit:integer:optional, pages:string:optional]" -Write,filesystem,medium,writes,"Create or overwrite files. Read first if exists. Prefer Edit.","[file_path:string:required, content:string:required]" -Edit,filesystem,medium,writes,"Exact string replacement. old_string must be unique.","[file_path:string:required, old_string:string:required, new_string:string:required, replace_all:boolean:optional]" -Glob,filesystem,low,reads,"Find files by glob pattern. Returns paths sorted by modification time.","[pattern:string:required, path:string:optional]" -Grep,filesystem,low,reads,"Search file contents using regex (ripgrep). Use glob/type for filtering.","[pattern:string:required, path:string:optional, glob:string:optional, type:string:optional, output_mode:enum(content|files_with_matches|count):optional]" -NotebookEdit,filesystem,medium,writes,"Replace/insert/delete cells in Jupyter notebooks.","[notebook_path:string:required, new_source:string:required, cell_id:string:optional, cell_type:enum(code|markdown):optional, edit_mode:enum(replace|insert|delete):optional]" -Bash,execution,high,executes,"Execute bash commands. Use for git/npm/docker. Avoid for file ops.","[command:string:required, description:string:optional, timeout:integer:optional, run_in_background:boolean:optional]" -Task,execution,medium,mixed,"Launch specialized subagents for complex multi-step tasks.","[description:string:required, prompt:string:required, subagent_type:string:required, model:enum(sonnet|opus|haiku):optional, run_in_background:boolean:optional, max_turns:integer:optional]" -TaskOutput,execution,low,reads,"Retrieve output from running or completed background task.","[task_id:string:required, block:boolean:optional, timeout:integer:optional]" +Read,filesystem,low,reads,"Read file contents. Supports text, images, PDFs, and notebooks.","[file_path:string:required, offset:integer:optional, limit:integer:optional, pages:string:optional]" +Write,filesystem,medium,writes,"Create or overwrite files. Read first if the file exists. Prefer Edit for localized changes.","[file_path:string:required, content:string:required]" +Edit,filesystem,medium,writes,"Exact string replacement. old_string must be unique unless replace_all is true.","[file_path:string:required, old_string:string:required, new_string:string:required, replace_all:boolean:optional]" +Glob,filesystem,low,reads,"Find files by glob pattern.","[pattern:string:required, path:string:optional]" +Grep,filesystem,low,reads,"Search file contents using regex.","[pattern:string:required, path:string:optional, glob:string:optional, type:string:optional, output_mode:enum(content|files_with_matches|count):optional]" +NotebookEdit,filesystem,medium,writes,"Replace, insert, or delete notebook cells.","[notebook_path:string:required, new_source:string:required, cell_id:string:optional, cell_type:enum(code|markdown):optional, edit_mode:enum(replace|insert|delete):optional]" +Bash,execution,high,executes,"Execute bash commands. Use for git, npm, docker, and test runs.","[command:string:required, description:string:optional, timeout:integer:optional, run_in_background:boolean:optional]" +Agent,execution,medium,mixed,"Launch specialized subagents from a main-thread agent.","[description:string:required, prompt:string:required, subagent_type:string:required, model:enum(sonnet|opus|haiku|inherit):optional, run_in_background:boolean:optional, max_turns:integer:optional]" +Task,execution,medium,mixed,"Deprecated alias for Agent.","[description:string:required, prompt:string:required, subagent_type:string:required, model:enum(sonnet|opus|haiku|inherit):optional, run_in_background:boolean:optional, max_turns:integer:optional]" +TaskOutput,execution,low,reads,"Retrieve output from a running or completed background task.","[task_id:string:required, block:boolean:optional, timeout:integer:optional]" TaskStop,execution,low,executes,"Stop a running background task by ID.","[task_id:string:required]" TaskCreate,execution,low,none,"Create a new task in the structured task list.","[subject:string:required, description:string:required, activeForm:string:optional]" -TaskUpdate,execution,low,none,"Update task status/details/dependencies.","[taskId:string:required, status:enum(pending|in_progress|completed|deleted):optional, subject:string:optional, description:string:optional]" -TaskList,execution,low,reads,"List all tasks with status and dependencies.","" -TaskGet,execution,low,reads,"Get full details of a specific task by ID.","[taskId:string:required]" -TodoWrite,execution,low,none,"Create and manage structured task/todo items for tracking session progress.","[subject:string:required, description:string:required, activeForm:string:optional]" -MCPSearch,execution,low,reads,"Search for and load MCP tools. Requires MCP servers configured.","" -WebFetch,web,medium,network,"Fetch URL content and process with prompt. 15-min cache. Fails for auth URLs.","[url:string:required, prompt:string:required]" -WebSearch,web,medium,network,"Search the web. Must include Sources section with URLs.","[query:string:required, allowed_domains:array:optional, blocked_domains:array:optional]" -AskUserQuestion,interaction,low,none,"Ask user questions. 1-4 questions with 2-4 options each.","[questions:array:required]" -Skill,skills,medium,mixed,"Execute a skill (slash command) within the conversation.","[skill:string:required, args:string:optional]" -EnterPlanMode,planning,low,none,"Transition to plan mode for implementation approaches.","" -ExitPlanMode,planning,low,none,"Signal plan completion and request user approval.","[allowedPrompts:array:optional, pushToRemote:boolean:optional]" -LSP,code_intelligence,low,reads,"Code intelligence via Language Server Protocol. IDE-only.","" +TaskUpdate,execution,low,none,"Update task status, details, or dependencies.","[taskId:string:required, status:enum(pending|in_progress|completed|deleted):optional, subject:string:optional, description:string:optional]" +TaskList,execution,low,reads,"List all structured tasks.","" +TaskGet,execution,low,reads,"Get full details for a structured task.","[taskId:string:required]" +TodoWrite,execution,low,none,"Create and manage structured todo items for session progress.","[subject:string:required, description:string:required, activeForm:string:optional]" +MCPSearch,execution,low,reads,"Search for and load MCP tools.","" +WebFetch,web,medium,network,"Fetch URL content and process it with a prompt.","[url:string:required, prompt:string:required]" +WebSearch,web,medium,network,"Search the web.","[query:string:required, allowed_domains:array:optional, blocked_domains:array:optional]" +AskUserQuestion,interaction,low,none,"Ask the user structured questions.","[questions:array:required]" +Skill,skills,medium,mixed,"Execute a skill within the conversation.","[skill:string:required, args:string:optional]" +EnterPlanMode,planning,low,none,"Transition to plan mode.","" +ExitPlanMode,planning,low,none,"Signal plan completion and request approval.","[allowedPrompts:array:optional, pushToRemote:boolean:optional]" +LSP,code_intelligence,low,reads,"Code intelligence via Language Server Protocol.","" >> -RECOMMENDED_PLANNER_TOOLS: ["Read", "Glob", "Grep", "WebFetch", "WebSearch", "TaskCreate", "TaskUpdate", "TaskList", "TaskGet", "AskUserQuestion", "Task"] -RECOMMENDED_IMPLEMENTER_TOOLS: ["Read", "Write", "Edit", "Bash", "Glob", "Grep", "TaskCreate", "TaskUpdate", "TaskList", "TaskGet", "Task", "NotebookEdit"] +RECOMMENDED_PLANNER_TOOLS: ["Read", "Glob", "Grep", "WebFetch", "WebSearch", "TaskCreate", "TaskUpdate", "TaskList", "TaskGet", "AskUserQuestion", "Agent"] +RECOMMENDED_IMPLEMENTER_TOOLS: ["Read", "Write", "Edit", "Bash", "Glob", "Grep", "TaskCreate", "TaskUpdate", "TaskList", "TaskGet", "Agent", "NotebookEdit"] PERMISSION_MODES: ["default", "acceptEdits", "dontAsk", "bypassPermissions", "plan"] AGENT_MODELS: ["sonnet", "opus", "haiku", "inherit"] @@ -76,7 +117,7 @@ AGENT_VERSIONING: JSON<< "templates": [ { "path": "templates/.claude/agents/aps-v{major}.{minor}.{patch}.md", - "current_path": "templates/.claude/agents/aps-v1.1.16.md", + "current_path": "templates/.claude/agents/aps-v1.2.1.md", "frontmatter": { "name_pattern": "aps-v{major}-{minor}-{patch}", "description_pattern": "Generate APS v{major}.{minor}.{patch} agent files for any platform: load APS skill + target platform adapter, extract intent, then generate+write+lint." @@ -94,24 +135,30 @@ SKILL_AUTHORING_RESOURCES: JSON<< } >> -DOCS_MEMORY_URL: "https://docs.anthropic.com/en/docs/claude-code/memory" -DOCS_SETTINGS_URL: "https://docs.anthropic.com/en/docs/claude-code/settings" -DOCS_HOOKS_URL: "https://docs.anthropic.com/en/docs/claude-code/hooks" -DOCS_MCP_URL: "https://docs.anthropic.com/en/docs/claude-code/mcp" -DOCS_TOOLS_URL: "https://docs.anthropic.com/en/docs/claude-code/cli-reference" -DOCS_SUBAGENTS_URL: "https://docs.anthropic.com/en/docs/claude-code/sub-agents" +DOCS_MEMORY_URL: "https://code.claude.com/docs/en/memory" +DOCS_SETTINGS_URL: "https://code.claude.com/docs/en/settings" +DOCS_HOOKS_URL: "https://code.claude.com/docs/en/hooks" +DOCS_MCP_URL: "https://code.claude.com/docs/en/mcp" +DOCS_TOOLS_URL: "https://code.claude.com/docs/en/cli-reference" +DOCS_SUBAGENTS_URL: "https://code.claude.com/docs/en/sub-agents" - + --- name: description: "" -model: tools: disallowedTools: +model: permissionMode: -skills: +maxTurns: +skills: + - +mcpServers: + - +memory: +background: hooks: : - matcher: "" @@ -121,16 +168,20 @@ hooks: --- WHERE: -- is String; regex: ^[a-z][a-z0-9-]{1,63}$; unique across all loaded subagents. -- is String; describes what the subagent does and when to invoke it. -- is one of AGENT_MODELS; default inherit; omit to use default. -- is String; comma-separated names from TOOLS; omit if no allowlist needed. -- is String; comma-separated names from TOOLS; omit if no denylist needed. -- is one of PERMISSION_MODES; default default; omit to use default. -- is String; comma-separated skill names; omit if no skills needed. -- is one of: "PreToolUse", "PostToolUse", "Stop"; subset of HOOK_EVENTS. -- is String; tool name to match (e.g., "Bash", "Write"). +- is String; single-line double-quoted string that says what the agent does and when to invoke it. +- is String; regex: ^[a-z][a-z0-9-]{1,63}$; unique across all loaded agents. +- is Boolean; true to always run the worker as a background task. +- is String; comma-separated names from TOOLS; omit if no denylist is needed. - is String; shell command to execute; receives tool context via environment variables. +- is one of HOOK_EVENTS. +- is String; tool name or regex pattern to match. +- is Integer; maximum number of agentic turns before the agent stops. +- is String; preconfigured MCP server name; repeat or replace the list with inline server objects when needed. +- is one of SUBAGENT_MEMORY_SCOPES; omit if no persistent memory is needed. +- is one of AGENT_MODELS; omit to inherit the parent model. +- is one of PERMISSION_MODES; omit to inherit the current permission context. +- is String; skill id to preload into the agent context; omit the list if no skills are needed. +- is String; comma-separated PascalCase names from TOOLS. For main-thread coordinators use `Agent` or `Agent(worker, reviewer)`. For leaf workers omit `Agent`. @@ -140,7 +191,7 @@ paths: --- WHERE: -- is String; standard glob syntax (e.g., "src/**/*.ts", "**/*.test.ts", "docs/**/*.md"); ** for recursive matching, * for single directory. +- is String; standard glob syntax such as "src/**/*.ts", "**/*.test.ts", or "docs/**/*.md". @@ -157,7 +208,7 @@ WHERE: WHERE: - is one of HOOK_EVENTS. -- is String; tool name to match (e.g., "Bash"); omit matcher for unconditional hooks. +- is String; tool or agent matcher; omit matcher for unconditional hooks. - is String; shell command to execute at the lifecycle event. @@ -171,7 +222,7 @@ WHERE: } WHERE: -- is String; exact tool name from TOOLS (e.g., "Read", "Glob", "Grep"). -- is String; tool name with optional argument restriction (e.g., "Bash(rm -rf *)"). +- is String; exact PascalCase tool name from TOOLS, for example "Read", "Glob", "Grep", or "Agent(worker)". +- is String; tool name with optional argument restriction, for example "Bash(rm -rf *)" or "Agent(my-custom-agent)". diff --git a/.github/skills/agnostic-prompt-standard/platforms/claude-code/templates/.claude/agents/aps-v1.1.16.md b/.github/skills/agnostic-prompt-standard/platforms/claude-code/templates/.claude/agents/aps-v1.2.1.md similarity index 98% rename from .github/skills/agnostic-prompt-standard/platforms/claude-code/templates/.claude/agents/aps-v1.1.16.md rename to .github/skills/agnostic-prompt-standard/platforms/claude-code/templates/.claude/agents/aps-v1.2.1.md index 42d1932..ad5021f 100644 --- a/.github/skills/agnostic-prompt-standard/platforms/claude-code/templates/.claude/agents/aps-v1.1.16.md +++ b/.github/skills/agnostic-prompt-standard/platforms/claude-code/templates/.claude/agents/aps-v1.2.1.md @@ -1,6 +1,6 @@ --- -name: aps-v1-1-16 -description: "Generate APS v1.1.16 agent files for any platform: load APS skill + target platform adapter, extract intent, then generate+write+lint. Author: Christopher Buckley. Co-authors: Juan Burckhardt, Anastasiya Smirnova. URL: https://github.com/chris-buckley/agnostic-prompt-standard" +name: aps-v1-2-1 +description: "Generate APS v1.2.1 agent files for any platform: load APS skill + target platform adapter, extract intent, then generate+write+lint. Author: Christopher Buckley. Co-authors: Juan Burckhardt, Anastasiya Smirnova. URL: https://github.com/chris-buckley/agnostic-prompt-standard" model: inherit tools: Read, Write, Glob, Grep, Bash, TodoWrite disallowedTools: Edit, MultiEdit diff --git a/.github/skills/agnostic-prompt-standard/platforms/generic/adaptor.md b/.github/skills/agnostic-prompt-standard/platforms/generic/adaptor.md new file mode 100644 index 0000000..5a07e21 --- /dev/null +++ b/.github/skills/agnostic-prompt-standard/platforms/generic/adaptor.md @@ -0,0 +1,63 @@ + +Generate artifacts for tool-agnostic APS usage or for runtimes that use external tools only. +You MUST load `guides/subagent-architecture-v1.0.0.guide.md` before authoring coordinator or worker contracts. +You MUST keep the APS coordinator as the single dispatch owner unless the host documents nested delegation. +You MUST define worker `` as the interface into the worker and mirror it in the caller dispatch process. +You MUST define worker `` outputs and capture them in the caller before the next step. +You MUST isolate host-specific tool or routing names in config files instead of APS process text. +Use this adapter when a host has no stable native tool registry, when tools come only from MCP or an equivalent external declaration file, or when you want one neutral tool layer across hosts. +Do not assume host-specific file names, frontmatter, or native tool naming. +Declare external tools in `predefinedTools.json` with canonical APS tool ids. +If a host exposes decorated runtime names, map them with `config.json` ALIAS entries instead of duplicating tool objects. + + + +PLATFORM_ID: "generic" +DISPLAY_NAME: "Generic / External Tools" +ADAPTER_VERSION: "1.1.0" +LAST_UPDATED: "2026-03-12" + +SUBAGENT_AUTHORING_GUIDE: "guides/subagent-architecture-v1.0.0.guide.md" + +SUBAGENT_ARCHITECTURE: JSON<< +{ + "coordinator_role": "Host-defined or manual APS coordinator", + "worker_role": "Host-defined, external, or user-mediated worker", + "depth_policy": "unknown-use-depth-1-by-default", + "invocation_surface": "host-defined", + "request_contract_rule": "Define the worker as the public interface and mirror it in the caller dispatch process args.", + "response_contract_rule": "Define a typed worker result and capture it before the caller continues.", + "fallback_pattern": "If the host has no native subagent surface, model delegation as explicit APS processes or user-mediated steps." +} +>> + +INSTRUCTION_FILE_PATHS: [] +DETECTION_MARKERS: [] +MCP_CONFIG_PATHS: [] +TOOL_SOURCES: ["native", "mcp", "mixed", "none"] +HOST_CAPABILITY_STATES: ["unknown", "depth-1", "nested", "manual"] +EXTERNAL_TOOL_DECLARATION_FILES: ["predefinedTools.json", "config.json"] + +DOCS_MCP_URL: "https://modelcontextprotocol.io/specification/2025-06-18/schema" + + + + +# Generic Coordinator Worker Map + +| Worker | Input contract | Invocation surface | Output contract | Notes | +|--------|----------------|--------------------|-----------------|-------| +| | | | | | + +## Caller mapping + + +WHERE: +- is String; worker request contract id or label. +- is String; host-defined invocation mechanism or `manual APS process`. +- is String; routing, policy, or fallback notes. +- is String; worker response contract id or label. +- is Markdown; explicit mapping from caller args to worker input and from worker output to caller capture. +- is String; worker identifier. + + diff --git a/.github/skills/agnostic-prompt-standard/platforms/opencode/adaptor.md b/.github/skills/agnostic-prompt-standard/platforms/opencode/adaptor.md index 938c33a..79eb2e2 100644 --- a/.github/skills/agnostic-prompt-standard/platforms/opencode/adaptor.md +++ b/.github/skills/agnostic-prompt-standard/platforms/opencode/adaptor.md @@ -1,23 +1,159 @@ -Generate artifacts for the OpenCode agent runtime using the constants in this adapter. -OpenCode uses AGENTS.md and JSONC configuration files. -Configuration supports JSON with comments (JSONC). +Generate artifacts for the OpenCode agent runtime using the constants and format contracts in this adapter. +You MUST load `guides/subagent-architecture-v1.0.0.guide.md` before authoring primary agents or subagents. +You MUST treat `mode: primary` agents as coordinators and `mode: subagent` agents as workers. +You SHOULD treat OpenCode workers as leaf workers for portable APS authoring because nested delegation is not documented. +You MUST map worker APS `` fields to caller dispatch process args one-for-one. +You MUST keep host-specific `Task` and command `subtask` wiring in the caller dispatch layer. PLATFORM_ID: "opencode" DISPLAY_NAME: "OpenCode" -ADAPTER_VERSION: "2.0.0" -LAST_UPDATED: "2026-02-19" +ADAPTER_VERSION: "2.1.0" +LAST_UPDATED: "2026-03-12" + +ARTIFACT_TYPES: CSV<< +type,scope,file_pattern,config_format +agent,project,.opencode/agents/*.md,OPENCODE_AGENT_FRONTMATTER_V1 +agent,user,~/.config/opencode/agents/*.md,OPENCODE_AGENT_FRONTMATTER_V1 +config,project,.opencode/opencode.json,OPENCODE_AGENT_CONFIG_JSON_V1 +config,project,.opencode/opencode.jsonc,OPENCODE_AGENT_CONFIG_JSON_V1 +config,project,opencode.json,OPENCODE_AGENT_CONFIG_JSON_V1 +config,project,opencode.jsonc,OPENCODE_AGENT_CONFIG_JSON_V1 +>> + +SUBAGENT_AUTHORING_GUIDE: "guides/subagent-architecture-v1.0.0.guide.md" + +SUBAGENT_ARCHITECTURE: JSON<< +{ + "coordinator_role": "Primary agent", + "worker_role": "Subagent configured with mode: subagent", + "depth_policy": "portable-depth-1", + "documented_limit": "Primary and subagent roles are documented, but nested delegation is not documented.", + "invocation_tool": "Task", + "manual_invocation": "@mention", + "definition_paths": [".opencode/agents/*.md", "~/.config/opencode/agents/*.md"], + "allowlist_surface": "permission.task", + "visibility_surface": "hidden", + "mode_surface": "mode", + "defaults": { + "model": "subagent inherits the invoking primary model when omitted", + "todo_tools": "todoread and todowrite are disabled for subagents by default" + }, + "request_contract_rule": "Define the worker as the public request interface and mirror it in the caller dispatch process args.", + "response_contract_rule": "Return a typed or tightly bounded result and capture it in the primary process before the next step.", + "command_rule": "If a command targets a subagent it triggers a subagent invocation by default. Use subtask:true to force subagent invocation." +} +>> INSTRUCTION_FILE_PATHS: ["AGENTS.md", ".opencode/instructions.md"] -CONFIG_FILE_PATHS: [".opencode/opencode.jsonc", ".opencode/opencode.json", "opencode.json", "opencode.jsonc", ".opencode.json"] +AGENT_FILE_PATHS: [".opencode/agents/*.md", "~/.config/opencode/agents/*.md"] +CONFIG_FILE_PATHS: [".opencode/opencode.json", ".opencode/opencode.jsonc", "opencode.json", "opencode.jsonc", ".opencode.json"] +MCP_CONFIG_PATHS: [".opencode/opencode.json", ".opencode/opencode.jsonc", "opencode.json", "opencode.jsonc", ".opencode.json"] +DETECTION_MARKERS: [".opencode", ".opencode/agents", ".opencode/opencode.json", ".opencode/opencode.jsonc", "opencode.json", "opencode.jsonc", ".opencode.json"] -DETECTION_MARKERS: [".opencode", ".opencode/opencode.jsonc", ".opencode/opencode.json", "opencode.json", "opencode.jsonc", ".opencode.json"] +AGENT_MODES: ["primary", "subagent", "all"] +COMMAND_SUBTASK_RULE: "If a command sets agent to a subagent, it triggers subagent invocation by default. Use subtask:false to disable. Use subtask:true to force subagent invocation." +SUBAGENT_TODO_DEFAULT: "todoread and todowrite are disabled for subagents by default." DOCS_OFFICIAL_URL: "https://opencode.ai/docs" -DOCS_CONFIG_URL: "https://opencode.ai/docs/config" +DOCS_AGENTS_URL: "https://opencode.ai/docs/agents/" +DOCS_COMMANDS_URL: "https://opencode.ai/docs/commands/" +DOCS_PERMISSIONS_URL: "https://opencode.ai/docs/permissions/" +DOCS_TOOLS_URL: "https://opencode.ai/docs/tools/" +DOCS_MCP_URL: "https://opencode.ai/docs/mcp-servers/" + +--- +description: +mode: +model: +temperature: +steps: +tools: + : +permission: + : + task: + "": +hidden: +disable: +--- + +WHERE: +- is String; glob pattern matched against subagent names in permission.task. +- is String; required description of what the agent does and when to use it. +- is Boolean; true to disable the agent. +- is Boolean; only applicable to mode `subagent`; hides the worker from `@` autocomplete. +- is one of AGENT_MODES. +- is String; provider/model-id. Omit it on workers to inherit the invoking primary model. +- is String; permission key such as `edit`, `bash`, `webfetch`, `todoread`, or `todowrite`. +- is String; one of `allow`, `ask`, or `deny`. +- is Integer; maximum number of agentic steps; prefer `steps` over the deprecated `maxSteps`. +- is String; one of `allow`, `ask`, or `deny`. +- is Number; typical range 0.0 to 1.0. +- is Boolean; true or false. +- is String; tool id or wildcard such as `write`, `edit`, `bash`, or `mymcp_*`. +- The markdown filename becomes the agent name. + + + +{ + "agent": { + "": { + "description": "", + "mode": "", + "model": "", + "steps": , + "tools": { + "": + }, + "permission": { + "": "", + "task": { + "": "" + } + }, + "hidden": , + "disable": + } + } +} + +WHERE: +- is String; glob pattern matched against subagent names in permission.task. +- is String; agent id. +- is String; required description of what the agent does and when to use it. +- is Boolean; true to disable the agent. +- is Boolean; only applies to mode `subagent`. +- is one of AGENT_MODES. +- is String; provider/model-id. +- is String; permission key such as `edit`, `bash`, or `webfetch`. +- is String; one of `allow`, `ask`, or `deny`. +- is Integer; maximum number of agentic steps. +- is String; one of `allow`, `ask`, or `deny`. +- is Boolean; true or false. +- is String; tool id or wildcard pattern. + + + +{ + "command": { + "": { + "agent": "", + "subtask": , + "model": "" + } + } +} + +WHERE: +- is String; agent id that executes the command. +- is String; command id. +- is String; optional model override for the command execution. +- is Boolean; true to force subagent invocation and isolate context. + diff --git a/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/adaptor.md b/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/adaptor.md index c54a6ed..666e826 100644 --- a/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/adaptor.md +++ b/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/adaptor.md @@ -7,24 +7,66 @@ Agents are stored in .github/agents/*.agent.md with YAML frontmatter. Prompt files are stored in .github/prompts/*.prompt.md with YAML frontmatter. Instructions are in .github/copilot-instructions.md and .github/instructions/*.instructions.md. Skills are at .github/skills//SKILL.md. +Workspace MCP servers are configured in .vscode/mcp.json. Use toolSet name to include all tools in a set, or qualifiedName for individual tools. The functionName is resolved automatically at runtime. Generated frontmatter MUST NOT contain YAML comments. Description MUST be a single-line quoted string (avoid YAML block scalars). +You MUST load `guides/subagent-architecture-v1.0.0.guide.md` before authoring coordinator or worker agents. +You SHOULD treat custom-agent subagents as leaf workers for portable APS authoring because nested delegation is not documented. +You MUST map worker APS `` fields to caller dispatch process args one-for-one. PLATFORM_ID: "vscode-copilot" DISPLAY_NAME: "VS Code + GitHub Copilot" -ADAPTER_VERSION: "2.0.0" -LAST_UPDATED: "2026-02-19" +ADAPTER_VERSION: "2.1.0" +LAST_UPDATED: "2026-03-12" + +ARTIFACT_TYPES: CSV<< +type,scope,file_pattern,frontmatter_format +agent,project,.github/agents/*.agent.md,VSCODE_AGENT_FRONTMATTER_V1 +agent,project,.claude/agents/*.md,VSCODE_AGENT_FRONTMATTER_V1 +agent,user,~/.copilot/agents/*.agent.md,VSCODE_AGENT_FRONTMATTER_V1 +prompt,project,.github/prompts/*.prompt.md,VSCODE_PROMPT_FRONTMATTER_V1 +instructions,project,.github/copilot-instructions.md, +scoped-instructions,project,.github/instructions/*.instructions.md,VSCODE_INSTRUCTIONS_FRONTMATTER_V1 +skill,project,.github/skills//SKILL.md,VSCODE_SKILL_FRONTMATTER_V1 +skill,personal,~/.copilot/skills//SKILL.md,VSCODE_SKILL_FRONTMATTER_V1 +mcp-config,project,.vscode/mcp.json, +>> + +SUBAGENT_AUTHORING_GUIDE: "guides/subagent-architecture-v1.0.0.guide.md" + +SUBAGENT_ARCHITECTURE: JSON<< +{ + "coordinator_role": "Main chat agent or prompt that can call agent/runSubagent", + "worker_role": "Built-in subagent or custom .agent.md agent used as a subagent", + "depth_policy": "portable-depth-1", + "documented_limit": "Custom-agent subagents are experimental and nested delegation is not documented.", + "invocation_tools": ["agent", "runSubagent"], + "definition_paths": [".github/agents/*.agent.md", ".claude/agents/*.md", "~/.copilot/agents/*.agent.md"], + "default_inheritance": { + "agent": "inherits the main agent", + "model": "inherits the main session unless overridden", + "tools": "inherits the main session unless overridden" + }, + "controls": { + "subagent_allowlist": "agents", + "visible_in_picker": "user-invocable", + "subagent_disable": "disable-model-invocation", + "handoff_chain": "handoffs" + }, + "request_contract_rule": "Define the worker as the interface and mirror it in the caller dispatch process args.", + "response_contract_rule": "The worker returns a summary or typed result that the main agent incorporates before continuing.", + "portability_rule": "Keep coordinator-owned dispatch and leaf workers. Use handoffs for sequential flows." +} +>> -INSTRUCTION_FILE_PATHS: [".github/copilot-instructions.md", ".github/instructions/*.instructions.md"] -AGENT_FILE_PATHS: [".github/agents/*.agent.md"] -PROMPT_FILE_PATHS: [".github/prompts/*.prompt.md"] -SKILL_FILE_PATHS: [".github/skills//SKILL.md", "~/.copilot/skills//SKILL.md"] +AGENT_FILE_PATHS: [".github/agents/*.agent.md", ".claude/agents/*.md", "~/.copilot/agents/*.agent.md"] +DETECTION_MARKERS: [".github/copilot-instructions.md", ".github/agents", ".claude/agents", ".github/prompts", ".github/instructions", ".github/skills", ".vscode/mcp.json"] -DETECTION_MARKERS: [".github/copilot-instructions.md", ".github/agents", ".github/prompts", ".github/instructions", ".github/skills"] +MCP_CONFIG_PATHS: [".vscode/mcp.json"] TOOL_NAMING_STYLE: "three-tier: toolSet / qualifiedName / functionName" TOOL_NAMING_QUALIFICATION: "qualifiedName for individual tools, toolSet for all tools in a set" @@ -33,56 +75,56 @@ TOOL_FRONTMATTER_SYNTAX: "YAML array (no # prefix)" TOOLS: CSV<< name,toolset,qualified_name,function_name,mention,risk,side_effects,description -semantic_search,search,search/codebase,semantic_search,#codebase,low,reads,"Search workspace for relevant code or documentation." +semantic_search,search,search/codebase,semantic_search,#codebase,low,reads,"Search the workspace for relevant code or documentation." get_changed_files,search,search/changes,get_changed_files,#changes,low,reads,"Get git diffs of current file changes." -list_code_usages,search,search/usages,list_code_usages,#usages,low,reads,"List usages of a function/class/variable." +list_code_usages,search,search/usages,list_code_usages,#usages,low,reads,"List usages of a function, class, or variable." file_search,search,search/fileSearch,file_search,#fileSearch,low,reads,"Search for files by glob pattern." -grep_search,search,search/textSearch,grep_search,#textSearch,low,reads,"Fast text search with exact string or regex." +grep_search,search,search/textSearch,grep_search,#textSearch,low,reads,"Fast exact or regex text search." get_search_view_results,search,search/searchResults,get_search_view_results,#searchResults,low,reads,"Get results from the Search view." -read_file,read,read/readFile,read_file,#readFile,low,reads,"Read contents of a file (1-indexed line range)." +read_file,read,read/readFile,read_file,#readFile,low,reads,"Read contents of a file." get_errors,read,read/problems,get_errors,#problems,low,reads,"Get compile or lint errors." -terminal_last_command,read,read/terminalLastCommand,terminal_last_command,#terminalLastCommand,low,reads,"Get last command run in active terminal." -terminal_selection,read,read/terminalSelection,terminal_selection,#terminalSelection,low,reads,"Get current selection in active terminal." -copilot_getNotebookSummary,read,read/notebookSummary,copilot_getNotebookSummary,#notebookSummary,low,reads,"Get list of Notebook cells with metadata." -read_notebook_cell_output,read,read/notebookCellOutput,read_notebook_cell_output,#notebookCellOutput,low,reads,"Retrieve output for a notebook cell." -create_directory,edit,edit/createDirectory,create_directory,#createDirectory,medium,writes,"Create a new directory structure (like mkdir -p)." -create_file,edit,edit/createFile,create_file,#createFile,medium,writes,"Create a new file with specified content." -replace_string_in_file,edit,edit/editFiles,replace_string_in_file,#editFiles,high,writes,"Replace a unique string in an existing file." -multi_replace_string_in_file,edit,edit/multiEditFiles,multi_replace_string_in_file,#multiEditFiles,high,writes,"Apply multiple replacements in a single call." -edit_notebook_file,edit,edit/editNotebook,edit_notebook_file,#editNotebook,high,writes,"Edit an existing Notebook file." -create_new_jupyter_notebook,edit,edit/createNotebook,create_new_jupyter_notebook,#createNotebook,medium,writes,"Generate a new Jupyter Notebook." +terminal_last_command,read,read/terminalLastCommand,terminal_last_command,#terminalLastCommand,low,reads,"Get the last command run in the active terminal." +terminal_selection,read,read/terminalSelection,terminal_selection,#terminalSelection,low,reads,"Get the current terminal selection." +copilot_getNotebookSummary,read,read/notebookSummary,copilot_getNotebookSummary,#notebookSummary,low,reads,"Get notebook cells with metadata." +read_notebook_cell_output,read,read/notebookCellOutput,read_notebook_cell_output,#notebookCellOutput,low,reads,"Read notebook cell output." +create_directory,edit,edit/createDirectory,create_directory,#createDirectory,medium,writes,"Create a directory structure." +create_file,edit,edit/createFile,create_file,#createFile,medium,writes,"Create a new file with content." +replace_string_in_file,edit,edit/editFiles,replace_string_in_file,#editFiles,high,writes,"Replace a unique string in a file." +multi_replace_string_in_file,edit,edit/multiEditFiles,multi_replace_string_in_file,#multiEditFiles,high,writes,"Apply multiple replacements in one call." +edit_notebook_file,edit,edit/editNotebook,edit_notebook_file,#editNotebook,high,writes,"Edit an existing notebook file." +create_new_jupyter_notebook,edit,edit/createNotebook,create_new_jupyter_notebook,#createNotebook,medium,writes,"Create a new notebook." run_in_terminal,execute,execute/runInTerminal,run_in_terminal,#runInTerminal,high,executes,"Execute shell commands in a persistent terminal." -get_terminal_output,execute,execute/getTerminalOutput,get_terminal_output,#getTerminalOutput,low,reads,"Get output of a terminal command." +get_terminal_output,execute,execute/getTerminalOutput,get_terminal_output,#getTerminalOutput,low,reads,"Get terminal command output." run_task,execute,execute/runTask,run_task,#runTask,high,executes,"Run an existing VS Code task." -create_and_run_task,execute,execute/createAndRunTask,create_and_run_task,#createAndRunTask,high,executes,"Create and run a build/run/custom task." -get_task_output,execute,execute/getTaskOutput,get_task_output,#getTaskOutput,low,reads,"Get the output of a task." -run_notebook_cell,execute,execute/runNotebookCell,run_notebook_cell,#runNotebookCell,high,executes,"Run a code cell in a notebook." +create_and_run_task,execute,execute/createAndRunTask,create_and_run_task,#createAndRunTask,high,executes,"Create and run a task." +get_task_output,execute,execute/getTaskOutput,get_task_output,#getTaskOutput,low,reads,"Get task output." +run_notebook_cell,execute,execute/runNotebookCell,run_notebook_cell,#runNotebookCell,high,executes,"Run a notebook cell." test_failure,execute,execute/testFailure,test_failure,#testFailure,low,reads,"Include test failure information." fetch_webpage,web,web/fetch,fetch_webpage,#fetch,medium,network,"Fetch main content from web pages." github_repo,web,web/githubRepo,github_repo,#githubRepo,medium,network,"Search a GitHub repository for source code." run_vscode_command,vscode,vscode/runCommand,run_vscode_command,#runVscodeCommand,high,mixed,"Run a VS Code command." -vscode_searchExtensions_internal,vscode,vscode/extensions,vscode_searchExtensions_internal,#extensions,low,network,"Browse VS Code Extensions Marketplace." +vscode_searchExtensions_internal,vscode,vscode/extensions,vscode_searchExtensions_internal,#extensions,low,network,"Browse the VS Code Extensions Marketplace." install_extension,vscode,vscode/installExtension,install_extension,#installExtension,high,writes,"Install a VS Code extension." get_project_setup_info,vscode,vscode/getProjectSetupInfo,get_project_setup_info,#getProjectSetupInfo,low,none,"Get project setup info for scaffolding." open_simple_browser,vscode,vscode/openSimpleBrowser,open_simple_browser,#openSimpleBrowser,medium,none,"Preview a website in Simple Browser." -create_new_workspace,vscode,vscode/newWorkspace,create_new_workspace,#newWorkspace,high,writes,"Get setup steps to create project structures." +create_new_workspace,vscode,vscode/newWorkspace,create_new_workspace,#newWorkspace,high,writes,"Create a new workspace structure." get_vscode_api,vscode,vscode/vscodeAPI,get_vscode_api,#VSCodeAPI,low,none,"Get VS Code API documentation." -runSubagent,agent,agent/runSubagent,runSubagent,#runSubagent,high,mixed,"Launch a new agent for complex multi-step tasks." -get_selection,,selection,get_selection,#selection,low,reads,"Get current editor selection." +runSubagent,agent,agent/runSubagent,runSubagent,#runSubagent,high,mixed,"Launch a new agent for isolated subagent work." +get_selection,,selection,get_selection,#selection,low,reads,"Get the current editor selection." manage_todo_list,,todo,manage_todo_list,#todo,low,none,"Manage a structured todo list." >> RECOMMENDED_PLANNER_TOOLS: ["search/codebase", "search/fileSearch", "search/textSearch", "search/changes", "search/usages", "read/readFile", "read/problems", "todo", "web/fetch", "web/githubRepo"] -RECOMMENDED_IMPLEMENTER_TOOLS: ["search/codebase", "search/fileSearch", "search/textSearch", "read/readFile", "read/problems", "edit/createDirectory", "edit/createFile", "edit/editFiles", "execute/runInTerminal", "execute/getTerminalOutput", "todo", "web/fetch", "web/githubRepo", "agent/runSubagent"] +RECOMMENDED_IMPLEMENTER_TOOLS: ["search/codebase", "search/fileSearch", "search/textSearch", "read/readFile", "read/problems", "edit/createDirectory", "edit/createFile", "edit/editFiles", "execute/runInTerminal", "execute/getTerminalOutput", "todo", "web/fetch", "web/githubRepo", "agent", "agent/runSubagent"] -AGENT_MODELS: ["Claude Haiku 4.5 (copilot)", "Claude Opus 4.5 (copilot)", "Claude Sonnet 4 (copilot)", "Claude Sonnet 4.5 (copilot)", "Gemini 2.5 Pro (copilot)", "GPT-4.1 (copilot)"] +AGENT_MODELS: ["Claude Haiku 4.5 (copilot)", "Claude Opus 4.5 (copilot)", "Claude Sonnet 4 (copilot)", "Claude Sonnet 4.5 (copilot)", "Gemini 2.5 Pro (copilot)", "GPT-4.1 (copilot)", "GPT-5 (copilot)", "GPT-5.2 (copilot)"] AGENT_VERSIONING: JSON<< { "templates": [ { "path": "templates/.github/agents/aps-v{major}.{minor}.{patch}.agent.md", - "current_path": "templates/.github/agents/aps-v1.1.16.agent.md", + "current_path": "templates/.github/agents/aps-v1.2.1.agent.md", "frontmatter": { "name_pattern": "APS v{major}.{minor}.{patch} Agent", "description_pattern": "Generate APS v{major}.{minor}.{patch} .agent.md or .prompt.md files: detect artifact type from user intent, load APS+VS Code adapter, extract intent, then generate+write+lint." @@ -102,7 +144,9 @@ SKILL_AUTHORING_RESOURCES: JSON<< DOCS_AGENT_SKILLS_URL: "https://code.visualstudio.com/docs/copilot/customization/agent-skills" DOCS_PROMPT_FILES_URL: "https://code.visualstudio.com/docs/copilot/customization/prompt-files" +DOCS_MCP_URL: "https://code.visualstudio.com/docs/copilot/reference/mcp-configuration" DOCS_CUSTOM_AGENTS_URL: "https://code.visualstudio.com/docs/copilot/customization/custom-agents" +DOCS_SUBAGENTS_URL: "https://code.visualstudio.com/docs/copilot/agents/subagents" DOCS_TOOLS_IN_CHAT_URL: "https://code.visualstudio.com/docs/copilot/chat/chat-tools" DOCS_TOOLS_REFERENCE_URL: "https://code.visualstudio.com/docs/copilot/reference/copilot-vscode-features" DOCS_CUSTOM_INSTRUCTIONS_URL: "https://code.visualstudio.com/docs/copilot/customization/custom-instructions" @@ -113,19 +157,38 @@ DOCS_CUSTOM_INSTRUCTIONS_URL: "https://code.visualstudio.com/docs/copilot/custom --- name: description: "" +argument-hint: "" tools: +agents: +model: user-invocable: disable-model-invocation: target: +handoffs: + - label: "" + agent: + prompt: "" + send: + model: +mcp-servers: --- WHERE: -- is String; the agent identifier shown in UI. -- is String; single-line quoted string describing agent purpose. -- is YAML array of tool qualified names or toolset names from TOOLS constant. -- is Boolean; true if agent appears in the agents dropdown; default true. -- is Boolean; true to prevent invocation as subagent; default false. -- is one of: "vscode", "github-copilot"; default "vscode". +- is String; single-line double-quoted description shown in chat. +- is String; custom agent name. If omitted in a real file, the filename is used. +- is YAML array of agent names, `*`, or `[]`. If present, include `agent` or `agent/runSubagent` in . +- is String; optional hint shown in the chat input field. +- is Boolean; true to prevent this agent from being invoked as a subagent. +- is String; target agent identifier for the handoff. +- is String; button label shown after the response completes. +- is String; qualified model name such as `GPT-5.2 (copilot)`; omit to reuse the current model. +- is String; prompt text sent to the next agent. +- is Boolean; true to auto-submit the handoff prompt. +- is YAML array of MCP server config objects; only applicable for target `github-copilot`. +- is String or YAML array; use qualified model names in the format `Model Name (vendor)`. +- is one of: `vscode`, `github-copilot`; default `vscode`. +- is YAML array of qualified names or tool set values from TOOLS; no `#` prefix. +- is Boolean; true if the agent appears in the picker. @@ -136,9 +199,9 @@ tools: --- WHERE: -- is String; the prompt name shown in UI. -- is String; single-line quoted string describing what the prompt does. -- is YAML array of tool qualified names or toolset names from TOOLS constant. +- is String; single-line double-quoted description of what the prompt does. +- is String; prompt name shown in the UI. +- is YAML array of qualified names or tool set values from TOOLS. Include `agent` or `agent/runSubagent` when the prompt invokes a subagent. @@ -148,8 +211,8 @@ description: "" --- WHERE: -- is String; comma-separated glob patterns (e.g., "**/*.ts,**/*.tsx"). -- is String; describes the coding conventions in this file. +- is String; comma-separated glob patterns such as `**/*.ts,**/*.tsx`. +- is String; single-line double-quoted description of the coding conventions in this file. @@ -159,7 +222,7 @@ description: "" --- WHERE: -- is String; lowercase hyphenated skill identifier (e.g., "webapp-testing"). -- is String; specific description so Copilot can auto-load the skill when relevant. +- is String; single-line double-quoted string so Copilot can auto-load the skill when relevant. +- is String; lowercase hyphenated skill identifier such as `webapp-testing`. diff --git a/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/templates/.github/agents/aps-v1.1.16.agent.md b/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/templates/.github/agents/aps-v1.2.1.agent.md similarity index 98% rename from .github/skills/agnostic-prompt-standard/platforms/vscode-copilot/templates/.github/agents/aps-v1.1.16.agent.md rename to .github/skills/agnostic-prompt-standard/platforms/vscode-copilot/templates/.github/agents/aps-v1.2.1.agent.md index 5fe4f29..563daa1 100644 --- a/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/templates/.github/agents/aps-v1.1.16.agent.md +++ b/.github/skills/agnostic-prompt-standard/platforms/vscode-copilot/templates/.github/agents/aps-v1.2.1.agent.md @@ -1,6 +1,6 @@ --- -name: APS v1.1.16 Agent -description: "Generate APS v1.1.16 .agent.md or .prompt.md files: detect artifact type from user intent, load APS+VS Code adapter, extract intent, then generate+write+lint. Author: Christopher Buckley. Co-authors: Juan Burckhardt, Anastasiya Smirnova. URL: https://github.com/chris-buckley/agnostic-prompt-standard" +name: APS v1.2.1 Agent +description: "Generate APS v1.2.1 .agent.md or .prompt.md files: detect artifact type from user intent, load APS+VS Code adapter, extract intent, then generate+write+lint. Author: Christopher Buckley. Co-authors: Juan Burckhardt, Anastasiya Smirnova. URL: https://github.com/chris-buckley/agnostic-prompt-standard" tools: - execute/runInTerminal - read/readFile diff --git a/.github/skills/agnostic-prompt-standard/references/03-agentic-control.md b/.github/skills/agnostic-prompt-standard/references/03-agentic-control.md index 9339637..138b51e 100644 --- a/.github/skills/agnostic-prompt-standard/references/03-agentic-control.md +++ b/.github/skills/agnostic-prompt-standard/references/03-agentic-control.md @@ -180,6 +180,35 @@ MILESTONE "title" SNAP [SYM1, SYM2 ...] [delta=true|false] [redact=[SYM_A, SYM_B ...]] ``` +## External tools and MCP + +APS treats MCP tools and other external tools as normal tool names after the host engine registers +or aliases them. + +Rules: + +- A `USE` statement MUST reference the tool name that the engine exposes at runtime. +- The prompt MUST NOT declare transport, server URLs, headers, or MCP config inside `USE`. + Put those settings in external host files. +- Hosts MAY expose the raw MCP `Tool.name`, a host-decorated name, or a canonical APS alias. +- If a host uses decorated names (for example `mcp__docs__search_docs`), the engine SHOULD map + that runtime name to one stable APS tool id through external ALIAS config. +- A platform adapter MAY require a host-specific runtime name. In that case, the adapter decides the + final `tool_name` form. + +Examples: + +```text +USE `search_docs` where: query="adapter constants" +USE `mcp__docs__search_docs` where: query="adapter constants" +``` + +The two examples show different runtime naming styles. A host should expose one stable name to the +prompt at run time. + +For how to declare imported MCP signatures in `predefinedTools.json`, see **04 Schemas and +types**. + ## Arguments and values ```yaml diff --git a/.github/skills/agnostic-prompt-standard/references/04-schemas-and-types.md b/.github/skills/agnostic-prompt-standard/references/04-schemas-and-types.md index a1a98d1..64bdf12 100644 --- a/.github/skills/agnostic-prompt-standard/references/04-schemas-and-types.md +++ b/.github/skills/agnostic-prompt-standard/references/04-schemas-and-types.md @@ -117,6 +117,64 @@ Style guidelines: - Engines that emit `predefinedTools.json` SHOULD preserve or adopt the one-line-per-tool layout; engines MUST accept any valid JSON layout. +## MCP tool declaration pattern (external) + +Intent: let an engine import MCP tool signatures into `predefinedTools.json` without putting host +config inside the prompt. + +When an engine imports an MCP `Tool` from `tools/list`, it SHOULD: + +1. Create one canonical tool entry per MCP tool. +2. Use `Tool.name` as the canonical APS tool id unless a platform adapter requires a different + stable id. +3. Preserve `inputSchema` as the primary parameter contract. +4. Preserve `outputSchema` when it is present. +5. Derive the display label in this order: `title`, `annotations.title`, `name`. +6. Treat `readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint` as advisory + metadata only. +7. Record MCP origin metadata such as the server id and original tool name. + +If a host exposes decorated runtime names (for example `mcp__server__tool`), the engine SHOULD: + +- keep one canonical tool object in `predefinedTools.json` +- map the decorated runtime name to the canonical APS tool id with `config.json` ALIAS entries +- avoid duplicate tool objects that differ only by host wrapper syntax. + +A collision between a host tool name, an MCP-imported tool name, or an ALIAS target/source MUST +raise `AG-034`. + +### Recommended object shape for `predefinedTools.json` + +This shape is RECOMMENDED for imported MCP tools. Engines MAY add extra fields. + +```json +{ + "name": "search_docs", + "displayName": "Search Docs", + "description": "Search the documentation site.", + "inputSchema": { "type": "object", "properties": { "query": { "type": "string" } }, "required": ["query"] }, + "outputSchema": { "type": "object", "properties": { "matches": { "type": "array" } } }, + "hints": { + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "source": { + "kind": "mcp", + "server": "docs", + "toolName": "search_docs" + } +} +``` + +Notes: + +- `name` is the canonical APS tool id. +- `displayName` is for humans and UI only. +- `hints` do not change the true behavior of a tool. They are advisory. +- `source` gives provenance for lint, IDE help, and debug output. + ## Example format contracts - Minimal error contract: [../assets/formats/format-error-v1.0.0.example.md](../assets/formats/format-error-v1.0.0.example.md) @@ -128,6 +186,8 @@ Style guidelines: - Code changes full: [../assets/formats/format-code-changes-full-v1.0.0.example.md](../assets/formats/format-code-changes-full-v1.0.0.example.md) - SMEAC plan: [../assets/formats/format-smeac-plan-v1.0.0.example.md](../assets/formats/format-smeac-plan-v1.0.0.example.md) +- MCP tool bridge example: [../assets/composites/mcp-tool-bridge-v1.0.0.example.md](../assets/composites/mcp-tool-bridge-v1.0.0.example.md) + ## Example constants - JSON block constant example: [../assets/constants/constants-json-block-v1.0.0.example.md](../assets/constants/constants-json-block-v1.0.0.example.md) From f019a43cde8705d8e999b2cc51725e7e458e0cbb Mon Sep 17 00:00:00 2001 From: jsburckhardt Date: Mon, 6 Apr 2026 03:33:32 +0000 Subject: [PATCH 2/3] feat: add yazi terminal file manager dev container feature Adds yazi (https://github.com/sxyazi/yazi) as a new dev container feature. Installs both yazi and ya binaries from GitHub releases with multi-architecture support (x86_64, aarch64, i686). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 18 +++++ src/yazi/devcontainer-feature.json | 13 ++++ src/yazi/install.sh | 100 ++++++++++++++++++++++++++ test/_global/all-tools.sh | 1 + test/_global/scenarios.json | 11 ++- test/_global/yazi-specific-version.sh | 7 ++ test/yazi/test.sh | 7 ++ 7 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/yazi/devcontainer-feature.json create mode 100644 src/yazi/install.sh create mode 100644 test/_global/yazi-specific-version.sh create mode 100644 test/yazi/test.sh diff --git a/README.md b/README.md index 6e61db4..63d16ec 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ This repository contains a _collection_ of Features. | OpenCode | https://opencode.ai/ | AI coding agent, built for the terminal. An open-source alternative to Claude Code with support for multiple LLM providers. | | Codex-cli | https://github.com/openai/codex | Codex CLI is an experimental project under active development. | | ccc | https://github.com/jsburckhardt/co-config | A TUI tool to interactively configure and view GitHub Copilot CLI settings. | +| Yazi | https://github.com/sxyazi/yazi | Blazing fast terminal file manager written in Rust, based on async I/O. | @@ -355,3 +356,20 @@ Running `ccc` inside the built container will print the version of ccc (Copilot ```bash ccc --version ``` + +### `yazi` + +Running `yazi --version` inside the built container will print the version of yazi. + +```jsonc +{ + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "ghcr.io/jsburckhardt/devcontainer-features/yazi:1": {} + } +} +``` + +```bash +yazi --version +``` diff --git a/src/yazi/devcontainer-feature.json b/src/yazi/devcontainer-feature.json new file mode 100644 index 0000000..40adfd8 --- /dev/null +++ b/src/yazi/devcontainer-feature.json @@ -0,0 +1,13 @@ +{ + "name": "Yazi", + "id": "yazi", + "version": "1.0.0", + "description": "Blazing fast terminal file manager written in Rust, based on async I/O.", + "options": { + "version": { + "type": "string", + "default": "latest", + "description": "Version of yazi to install from GitHub releases e.g. v26.1.22" + } + } +} diff --git a/src/yazi/install.sh b/src/yazi/install.sh new file mode 100644 index 0000000..0ff729c --- /dev/null +++ b/src/yazi/install.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +# Variables +REPO_OWNER="sxyazi" +REPO_NAME="yazi" +BINARY_NAME="yazi" +YAZI_VERSION="${VERSION:-"latest"}" +GITHUB_API_REPO_URL="https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases" + +set -e + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi + apt-get -y install --no-install-recommends "$@" + fi +} + +# Make sure we have curl, jq, and unzip +check_packages curl jq ca-certificates unzip + +# Function to get the latest version from GitHub API +get_latest_version() { + curl -s "${GITHUB_API_REPO_URL}/latest" | jq -r ".tag_name" +} + +# Check if a version is passed as an argument +if [ -z "$YAZI_VERSION" ] || [ "$YAZI_VERSION" == "latest" ]; then + YAZI_VERSION=$(get_latest_version) + echo "No version provided or 'latest' specified, installing the latest version: $YAZI_VERSION" +else + echo "Installing version from environment variable: $YAZI_VERSION" +fi + +# Determine the OS and architecture +ARCH=$(uname -m) + +case "$ARCH" in + x86_64) + ARCH="x86_64" + ;; + aarch64) + ARCH="aarch64" + ;; + i686) + ARCH="i686" + ;; + *) + echo "Unsupported architecture: $ARCH" + exit 1 + ;; +esac + +# Construct the download URL +# Asset pattern: yazi-{ARCH}-unknown-linux-gnu.zip +ASSET_NAME="${BINARY_NAME}-${ARCH}-unknown-linux-gnu" +DOWNLOAD_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/${YAZI_VERSION}/${ASSET_NAME}.zip" + +# Create a temporary directory for the download +TMP_DIR=$(mktemp -d) +cd "$TMP_DIR" || exit + +echo "Downloading $BINARY_NAME from $DOWNLOAD_URL" +curl -sSL "$DOWNLOAD_URL" -o "${BINARY_NAME}.zip" + +# Extract the zip +echo "Extracting $BINARY_NAME..." +unzip -q "${BINARY_NAME}.zip" + +# Move the binaries to /usr/local/bin +echo "Installing $BINARY_NAME..." +mv "${ASSET_NAME}/${BINARY_NAME}" /usr/local/bin/ +mv "${ASSET_NAME}/ya" /usr/local/bin/ +chmod +x /usr/local/bin/$BINARY_NAME +chmod +x /usr/local/bin/ya + +# Cleanup +cd - || exit +rm -rf "$TMP_DIR" + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Verify installation +echo "Verifying installation..." +$BINARY_NAME --version + +echo "Done!" diff --git a/test/_global/all-tools.sh b/test/_global/all-tools.sh index aef7f35..5676b52 100755 --- a/test/_global/all-tools.sh +++ b/test/_global/all-tools.sh @@ -19,5 +19,6 @@ check "codex" codex --version check "just" just --version check "opencode" opencode --version check "ccc" ccc --version +check "yazi" yazi --version reportResults diff --git a/test/_global/scenarios.json b/test/_global/scenarios.json index 58a9945..33acde0 100644 --- a/test/_global/scenarios.json +++ b/test/_global/scenarios.json @@ -20,7 +20,8 @@ "codex": {}, "just": {}, "opencode": {}, - "ccc": {} + "ccc": {}, + "yazi": {} } }, "flux-specific-version": { @@ -156,5 +157,13 @@ "version": "v0.1.5" } } + }, + "yazi-specific-version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "yazi": { + "version": "v26.1.22" + } + } } } diff --git a/test/_global/yazi-specific-version.sh b/test/_global/yazi-specific-version.sh new file mode 100644 index 0000000..517159c --- /dev/null +++ b/test/_global/yazi-specific-version.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e +source dev-container-features-test-lib +check "yazi with specific version" /bin/bash -c "yazi --version | grep '26.1.22'" + +reportResults diff --git a/test/yazi/test.sh b/test/yazi/test.sh new file mode 100644 index 0000000..fcf1fd1 --- /dev/null +++ b/test/yazi/test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +source dev-container-features-test-lib +check "yazi" yazi --version +reportResults From 5f7edb2f80f7883da8a312598dac89dc44e34502 Mon Sep 17 00:00:00 2001 From: jsburckhardt Date: Mon, 6 Apr 2026 03:55:53 +0000 Subject: [PATCH 3/3] fix: update new-feature agent with git workflow and test gates Adds branching, user review checkpoint, feature test execution, and PR creation steps. Removes contradictory 'MUST NOT run tests' instruction. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/agents/new-feature.agent.md | 34 +++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/.github/agents/new-feature.agent.md b/.github/agents/new-feature.agent.md index 3702b79..31febcd 100644 --- a/.github/agents/new-feature.agent.md +++ b/.github/agents/new-feature.agent.md @@ -34,12 +34,16 @@ You MUST include the check_packages helper for apt dependencies in generated ins You MUST verify installation with the binary's version command in install.sh. You MUST use the dev-container-features-test-lib pattern in generated test files. You MUST use conventional commit format for any commits. +You MUST create a feature branch from main before making any changes. +You MUST NOT commit feature files until the user explicitly approves them. +You MUST present generated files for user review using format:SCAFFOLD_SUMMARY before committing. +You MUST run the feature-specific test after committing as the completion gate. +You MUST offer to create a PR after tests pass. You MUST NOT modify unrelated files or make drive-by refactors. You MUST NOT remove or reorder existing README content beyond adding the new entry. -You MUST NOT run devcontainer features test automatically. +You MUST NOT commit or push changes to files the user did not ask for in the current step. You SHOULD read an existing feature's install.sh as a reference before generating a new one. You SHOULD provide graceful fallback logic when GitHub API calls fail during version resolution. -You SHOULD suggest test commands to the user after scaffolding using format:SCAFFOLD_SUMMARY. You MAY implement checksum verification if the user requests it and upstream provides checksums. You MAY add extra options to devcontainer-feature.json if the user specifies them. @@ -170,6 +174,7 @@ BINARY_NAME: "" REQUESTED_VERSION: "latest" SUPPORT_CHECKSUM: false RELEASE_ASSET_PATTERN: "" +TEST_RESULT: "" @@ -179,10 +184,15 @@ RELEASE_ASSET_PATTERN: "" RUN `parse-input` +RUN `create-branch` RUN `inspect-upstream` RUN `scaffold` RUN `integrate` RETURN: format="SCAFFOLD_SUMMARY" +WAIT for user approval +RUN `commit-feature` +RUN `test-feature` +RUN `create-pr` @@ -196,6 +206,10 @@ IF INP contains "checksum=true": SET SUPPORT_CHECKSUM := true (from "Agent Inference") + +USE `execute/runInTerminal` where: command="git checkout -b feat/{FEATURE_ID}" + + USE `web/githubRepo` where: query="latest release assets", repo=SOURCE_REPO CAPTURE RELEASE_ASSET_PATTERN from result @@ -226,6 +240,22 @@ USE `edit/editFiles` where: filePath=".github/workflows/test.yaml" USE `read/readFile` where: filePath="README.md" USE `edit/editFiles` where: filePath="README.md" + + +USE `execute/runInTerminal` where: command="git add -A && git commit -m 'feat: add {FEATURE_ID} dev container feature'" + + + +USE `execute/runInTerminal` where: command="devcontainer features test -f {FEATURE_ID} -i ubuntu:latest ." +CAPTURE TEST_RESULT from result +IF TEST_RESULT contains "FAILED": + TELL "Test failed. Review output and fix install.sh." level=error + + + +USE `execute/runInTerminal` where: command="git push origin feat/{FEATURE_ID}" +USE `execute/runInTerminal` where: command="gh pr create --base main --head feat/{FEATURE_ID} --title 'feat: add {FEATURE_DISPLAY_NAME} dev container feature' --fill" +