Chatgpt Apps
Haohao-end/openagent
Build, scaffold, refactor, and troubleshoot ChatGPT Apps SDK applications that combine an MCP server and widget UI.
OpenSpec-mode authoring for Chorus PM workflows on OpenClaw — the default whenever OpenSpec is usable.
$ npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Chorus-AIDLC/Chorus openspec-aware --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/Chorus-AIDLC/Chorus.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/openclaw-plugin/skills/openspec-aware .claude/skills/openspec-aware && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "openspec-aware" agent skill from https://github.com/Chorus-AIDLC/Chorus/tree/main/packages/openclaw-plugin/skills/openspec-aware into .claude/skills/openspec-aware/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openspec-aware", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Chorus-AIDLC/Chorus/tree/main/packages/openclaw-plugin/skills/openspec-awareType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Chorus-AIDLC/Chorus openspec-aware --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Chorus-AIDLC/Chorus.git skills-src && mkdir -p .agents/skills && cp -r skills-src/packages/openclaw-plugin/skills/openspec-aware .agents/skills/openspec-aware && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "openspec-aware" agent skill from https://github.com/Chorus-AIDLC/Chorus/tree/main/packages/openclaw-plugin/skills/openspec-aware into .agents/skills/openspec-aware/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openspec-aware", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Chorus-AIDLC/Chorus openspec-aware --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Chorus-AIDLC/Chorus.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/packages/openclaw-plugin/skills/openspec-aware .cursor/skills/openspec-aware && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "openspec-aware" agent skill from https://github.com/Chorus-AIDLC/Chorus/tree/main/packages/openclaw-plugin/skills/openspec-aware into .cursor/skills/openspec-aware/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openspec-aware", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Chorus-AIDLC/Chorus.git --path packages/openclaw-plugin/skills/openspec-aware--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Chorus-AIDLC/Chorus openspec-aware --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Chorus-AIDLC/Chorus.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/packages/openclaw-plugin/skills/openspec-aware .gemini/skills/openspec-aware && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "openspec-aware" agent skill from https://github.com/Chorus-AIDLC/Chorus/tree/main/packages/openclaw-plugin/skills/openspec-aware into .gemini/skills/openspec-aware/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openspec-aware", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Chorus-AIDLC/Chorus openspec-awareInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Chorus-AIDLC/Chorus.git skills-src && mkdir -p .github/skills && cp -r skills-src/packages/openclaw-plugin/skills/openspec-aware .github/skills/openspec-aware && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "openspec-aware" agent skill from https://github.com/Chorus-AIDLC/Chorus/tree/main/packages/openclaw-plugin/skills/openspec-aware into .github/skills/openspec-aware/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openspec-aware", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Chorus-AIDLC/Chorus openspec-aware --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Chorus-AIDLC/Chorus.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/packages/openclaw-plugin/skills/openspec-aware .opencode/skills/openspec-aware && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "openspec-aware" agent skill from https://github.com/Chorus-AIDLC/Chorus/tree/main/packages/openclaw-plugin/skills/openspec-aware into .opencode/skills/openspec-aware/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openspec-aware", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
openspec-awareOpenSpec-mode authoring for Chorus PM workflows on OpenClaw — the default whenever OpenSpec is usable.
Openspec Aware is an agent skill from Chorus-AIDLC/Chorus. OpenSpec-mode authoring for Chorus PM workflows on OpenClaw — the default whenever OpenSpec is usable. Resolves the whole spec-mode contract (lite/openspec/off) by sourcing the plugin's shipped bin/resolve-spec-mode.sh (no SessionStart hook on OpenClaw), scaffolds openspec/changes/<slug/ on disk, and mirrors Markdown files into Chorus document drafts via chorus mcp call --arg-file (bash chorus-api.sh wrapper as fallback). When OpenSpec isn't usable the mode resolves to spec-lite (see the spec-lite skill)…
Its SKILL.md is about 7.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Computer vision and Project scaffolding. It works with Bash and Model Context Protocol. The repository describes itself as: The Agent Harness for AI-Human Collaboration, inspired by the AI-DLC (AI-Driven Development Lifecycle). The licence is AGPL-3.0.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 4754822. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
jqnpmFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
github.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
CHORUS_API_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Openspec Aware loads about 7.6k tokens when it runs. Until then it costs about 149 tokens; SKILL.md has 3,263 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from Chorus-AIDLC/Chorus at commit 4754822, republished under its AGPL-3.0 licence (© Chorus-AIDLC). 3,263 words, ~7,618 tokens.
.claude/skills/openspec-aware/SKILL.md (or your agent's skills folder).This skill is a shared sub-procedure invoked by the Chorus stage skills (proposal, develop, yolo) when the resolved spec mode is a usable OpenSpec — spec-driven authoring through the OpenSpec CLI:
CHORUS_SPEC_MODE=openspec or unset, and CHORUS_OPENSPEC_MODE not off, an openspec/ directory at the project root, and the openspec CLI on PATH.CHORUS_SPEC_MODE=off).See also —
spec-lite(the lightweight fallback): OpenSpec (this skill) stays the default whenever it is usable. When OpenSpec is absent or disabled — orCHORUS_SPEC_MODE=lite— the mode resolves to spec-lite: a durable local.chorus/specs/<slug>/spec.md(never synced) + per-change dated folders<slug>/<YYYY-MM-DD>-<change-slug>/of Chorus-typed docs mirrored 1:1 into Chorus via the same--arg-filetransport. See thespec-liteskill.
Tool namespace: Chorus MCP tools are exposed under a
chorus__prefix on OpenClaw (e.g.chorus__chorus_pm_create_proposal). Bare names are used in prose for readability — prependchorus__when invoking the MCP tools directly. Document-mirror calls do NOT go through the MCP harness at all — they go through thechorusCLI (chorus mcp call, preferred) or thechorus-api.shwrapper (fallback) (see §2 Rule 1), which talk to the Chorus MCP endpoint over HTTP using your API key, independent of thechorus__namespacing.
OpenClaw difference: the Claude Code / Codex / Pi ports precompute the spec mode once (in a SessionStart hook or an extension handler) and inject a
## Spec Modevalue into context. OpenClaw does none of that. You MUST resolve the mode yourself, at the moment you reach this skill from a stage skill. Do not look for an injectedCHORUS_OPENSPEC_ACTIVE/## Spec Modevalue — it will not exist on OpenClaw. Resolve the whole contract (lite / openspec / off), not just "is OpenSpec active".Never hand-roll the rule in this Markdown. The plugin ships the canonical resolver —
bin/resolve-spec-mode.sh, byte-identical to the Claude Code copy and enforced so bytest-resolver-drift.sh— precisely so this skill can source it instead of reproducing it. A prose copy of the rule drifts from the real one (it has); a sourced script cannot.
The rule: an explicit CHORUS_SPEC_MODE (lite/openspec/off) wins; when unset, OpenSpec is the default whenever it is usable — else spec-lite. OpenSpec is usable only when all three hold:
CHORUS_OPENSPEC_MODE not off; the enableOpenSpec plugin toggle not false).openspec/ directory (i.e. someone ran openspec init here).openspec CLI is on PATH.Both signals (2) and (3) are required because the OpenSpec authoring path needs the working directory and the CLI — having one without the other leaves the workflow unrunnable. When OpenSpec is requested but usable=false (signal 2 holds but 3 does not, say), surface a hint to the user — "OpenSpec repo detected — install with: npm i -g @fission-ai/openspec".
# PROJECT_ROOT is your project root — OpenClaw does not export
# CLAUDE_PROJECT_DIR, so default to $PWD. The resolver reads it.
PROJECT_ROOT="${PWD}"
# Locate the resolver the plugin ships. Covers the npm install, a global npm
# install, and a linked dev checkout; the first hit wins.
RESOLVER=""
for candidate in \
"$PWD/node_modules/@chorus-aidlc/chorus-openclaw-plugin/bin/resolve-spec-mode.sh" \
"$(npm root -g 2>/dev/null)/@chorus-aidlc/chorus-openclaw-plugin/bin/resolve-spec-mode.sh" \
"$PWD/packages/openclaw-plugin/bin/resolve-spec-mode.sh"
do
[ -f "$candidate" ] && { RESOLVER="$candidate"; break; }
done
# shellcheck source=/dev/null
. "$RESOLVER" # sets SPEC_MODE, SPEC_REASON, SPEC_FAIL, OPENSPEC_HINT, CHORUS_OPENSPEC_ACTIVE
echo "SPEC_MODE=$SPEC_MODE CHORUS_OPENSPEC_ACTIVE=$CHORUS_OPENSPEC_ACTIVE SPEC_FAIL=${SPEC_FAIL} REASON=${SPEC_REASON}"If RESOLVER came out empty (the loop found nothing), halt and ask the user to run /chorus spec — which resolves the same contract from the plugin's src/spec-mode.ts — and paste the result. Do not substitute your own detection.
Branch on the result:
SPEC_FAIL non-empty (explicit CHORUS_SPEC_MODE=openspec that can't be honored — either a config conflict or OpenSpec not installed; OPENSPEC_HINT carries the install command when it is merely missing) → the caller MUST halt and surface it verbatim. Do not silently fall back.CHORUS_OPENSPEC_ACTIVE=1 → follow §3 (OpenSpec authoring).SPEC_MODE=lite or off, no fail) → this skill is a no-op; return to the calling skill, which follows the resolved mode: spec-lite (the default when OpenSpec isn't usable — see the spec-lite skill) or free-form (off). Do not scaffold openspec/changes/. Do not add the slug line to the proposal description.Run this resolution whenever proposal / develop / yolo reference this skill. There is no host-injected value to read on OpenClaw — but "resolve it yourself" means run the shipped resolver, never re-derive the rule from this document's prose.
Both are enforced at review time. Both have caused incidents in past releases.
content from the file (CLI preferred, bash-wrapper fallback); never re-type document content from agent outputDocument/draft mirror calls (chorus_pm_add_document_draft, chorus_pm_update_document_draft, chorus_pm_update_document) MUST fill the content field from the local file's bytes, never from a hand-typed body. Calling these tools directly from the agent's MCP harness with a hand-typed content field is a protocol violation for OpenSpec mode and will fail review. Use whichever transport is available, preferred first:
chorus CLI: chorus mcp call <tool_name> '<json-without-content>' --arg-file content=<file>. --arg-file content=<path> reads the file's raw bytes and injects them as the JSON content string, byte-exact — the CLI's built-in replacement for json_encode_file, so no helper is needed. chorus mcp call reads the same CHORUS_URL / CHORUS_API_KEY from the environment (availability note below). See §3.6. Requires chorus >= 0.17.0 (the chorus mcp subcommand was added then; an older CLI errors with "unknown command"); on any version or unknown-command failure, upgrade with npm install -g @chorus-aidlc/chorus.chorus-api.sh wrapper, when chorus is not on PATH: build $PAYLOAD with the json_encode_file helper and call chorus-api.sh mcp-tool <tool_name> "$PAYLOAD". Defined in the §3.6 fallback block.New to the
chorusCLI? See thechorus-cliskill for install, configuring agents (chorus agents add|remove|list), the connection env vars, andchorus mcpbasics.
Acting identity — which agent the call acts as.
chorus mcp callresolves the agent from, in order:CHORUS_AGENT_PROFILE(a name or UUID) →CHORUS_URL+CHORUS_API_KEYin the environment → the single agent configured in~/.chorus/daemon.json. A daemon-woken session already hasCHORUS_AGENT_PROFILEset. If a mirror call fails withMultiple agents … specify --agent(several agents configured and no profile/creds in the env), pass your own identity explicitly:chorus mcp call <tool> … --agent <your-agentUuid>— your UUID is in yourchorus_checkinresult, andchorus agentslists every configured name/UUID.
Reasons (they apply to both paths):
--arg-file and the fallback's json_encode_file stream the file's bytes into the JSON string — content never enters LLM context. A typical 3-doc proposal mirror costs roughly zero content-tokens this way; via direct MCP with a re-typed body it routinely costs 20k+.--arg-file, or the fallback's jq -Rs '.') is a byte-faithful encoder: backslashes, quotes, newlines, code-fence content, zero-width chars all survive. LLM re-emission has a non-zero failure rate on long markdown — table alignment drifts, fence escapes get "fixed", long URLs wrap. The byte-equality guarantee (modulo trailing \n) holds only on a file-fill path, never on LLM re-emission.openspec/changes/<slug>/*.md is authoritative and Chorus is a mirror. With agent re-typing, authority splits between local file and whatever the LLM happened to output — a future diff cannot tell which one is correct.
chorus/chorus-api.shavailability on OpenClaw. The document-mirror transport is either thechorusCLI (preferred) or thechorus-api.shwrapper (fallback). The wrapper must be reachable aschorus-api.shonPATH(the Chorus standalone skill bundle ships it; if you installed via that bundle it is already onPATH). If neitherchorusnorchorus-api.shis onPATHin your OpenClaw environment, do one of:
- call the wrapper by its absolute path (e.g.
"$HOME/.chorus/bin/chorus-api.sh" mcp-tool ...), or- reproduce its single behavior inline — POST a JSON-RPC
tools/callfor<tool_name>with arguments$PAYLOADto"$CHORUS_URL/api/mcp"with headerAuthorization: Bearer $CHORUS_API_KEYusingcurl, capturing the raw body for the §6 halt-on-error check.Both
chorus mcp calland the wrapper readCHORUS_URLandCHORUS_API_KEYfrom the environment (same values as your plugin configchorusUrl/apiKey). Export them before the first call if they are not already set. What you must NOT do is re-type the document body through the model — the file-fill rule stands regardless of which transport you use.
chorus_check_responseEvery wrapper call must check three signals: wrapper exit code, "error": in body, empty body. Bare RC=$? is insufficient — the wrapper exits 0 on HTTP 401 (auth failure) with empty body, so a single-signal check silently misses the most common runtime failure. See §6 for the helper definition.
openspec/changes/<slug>/ is the local change folder. The slug must be:
add-export-csv, not addExportCsv or add_export_csv),openspec/changes/.Record it for later steps:
SLUG="add-export-csv"openspec new change "$SLUG" --description "<one-line idea summary>"This creates openspec/changes/$SLUG/ with README.md and .openspec.yaml. Then author by hand:
| Local file | Purpose | Mirror as Document.type |
|---|---|---|
proposal.md | Why + What Changes + Capabilities + Impact | prd |
design.md | Architecture, contracts, risks | tech_design |
specs/<capability>/spec.md | Delta spec (## ADDED Requirements + Scenarios) | spec (one draft per capability) |
tasks.md | OpenSpec tasks list | (not mirrored — Chorus task drafts are source of truth) |
Use openspec instructions <artifact> --change "$SLUG" (artifacts: proposal, specs, design, tasks) for templates.
openspec instructions specs)A delta spec lists one or more block headers — ## ADDED Requirements, ## MODIFIED Requirements, ## REMOVED Requirements, ## RENAMED Requirements — and within each, ### Requirement: entries. Mix freely in the same file; only include the blocks you actually need.
## ADDED RequirementsAppend a brand-new Requirement to the long-term spec.
## ADDED Requirements
### Requirement: <name>
<requirement text — use SHALL / MUST for normative behavior>
#### Scenario: <name>
- **WHEN** <condition>
- **THEN** <expected outcome>## MODIFIED RequirementsWhole-block replacement, not merge. Whatever you write here completely replaces the existing same-named Requirement in the long-term spec — title, description, and all scenarios. Half-writing it deletes the rest.
## MODIFIED Requirements
### Requirement: <existing name>
<full updated requirement text>
#### Scenario: <name>
- **WHEN** <condition>
- **THEN** <expected outcome>
#### Scenario: <other name>
- **WHEN** <condition>
- **THEN** <expected outcome>Always include every scenario you want the post-archive spec to have, even ones that were already present and unchanged.
## REMOVED RequirementsDelete a Requirement from the long-term spec. The block under the heading is just the requirement name(s) you're removing — no scenarios needed.
## REMOVED Requirements
### Requirement: <existing name>## RENAMED RequirementsRename a Requirement's title. Body and scenarios are preserved as-is in the long-term spec; use MODIFIED instead if you need to change anything besides the title.
## RENAMED Requirements
### Requirement: <old name> -> <new name>Critical formatting rules (verified):
#### Scenario:). 3 hashtags or a bullet list silently fail validation.### Requirement: under ADDED or MODIFIED MUST have at least one #### Scenario:.MODIFIED blocks MUST include the full updated content — they overwrite, not patch.SHALL / MUST for normative requirements; avoid should / may.openspec/specs/<capability>/spec.md happens at openspec archive time (§3.9), not at proposal time. While the proposal is in flight, Chorus only sees the delta file as one spec Document — there is no half-merged state for the skill to reason about.Optional:
openspec validate "$SLUG"content field byte-exactThe document content must be inserted byte-for-byte from the local file — never re-typed by the LLM. Two mechanisms, preferred first:
chorus mcp call … --arg-file content=<path> (§3.6). The CLI reads the file's raw bytes and injects them as the JSON content string. This is the byte-faithful replacement for json_encode_file, so on the CLI path no helper is needed — pass the base JSON without a content field and let --arg-file fill it.json_encode_file (defined in the §3.6 fallback block, used only when chorus is not on PATH). With jq available it streams the file through jq -Rs '.'; the pure-shell branch matches chorus-api.sh's own escaping when jq is missing.Round-trip: the Chorus backend appends a single \n to draft content on write, so server content is byte-equal modulo a trailing newline. Reviewers diffing local file vs server should ignore that one byte.
Use the regular chorus_pm_create_proposal MCP tool (no wrapper required for this single call — the description is short, the LLM-emitted version is fine). The description must carry exactly one line:
OpenSpec change slug: <slug>OpenSpec change slug: (capital O, capital S, single space after colon),openspec new change.This line is machine-grep-able by future runs of this skill and by the §3.9 archive trigger.
Rule 1 reminder:
contentcomes from the file's bytes, never a hand-typed body. The agent must not retype the document body.
Ensure CHORUS_URL and CHORUS_API_KEY are exported (Rule 1 note) — both the CLI and the wrapper read them. Define the halt-on-error helper from §6 once at the top. Primary path — the chorus CLI: pass the base JSON without a content field and let --arg-file content=<file> fill it byte-exact. One call per file:
# PRD draft — --arg-file fills content byte-exact from the file; no json_encode_file needed.
RESULT=$(chorus mcp call chorus_pm_add_document_draft \
"{\"proposalUuid\":\"$PROPOSAL_UUID\",\"type\":\"prd\",\"title\":\"PRD: $HUMAN_TITLE\"}" \
--arg-file content="openspec/changes/$SLUG/proposal.md")
RC=$?
chorus_check_response "chorus_pm_add_document_draft (prd)" "$RC" "$RESULT"
PRD_DRAFT_UUID=$(printf '%s' "$RESULT" | grep -o '"draftUuid"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')Repeat with type: "tech_design" for design.md, and one call per capability with type: "spec" for each specs/<capability>/spec.md. Do not mirror tasks.md — Chorus task drafts (created via the chorus_pm_add_task_draft MCP tool, no wrapper needed) are the source of truth for tasks.
Why parsing uses
printf '%s' "$RESULT" | grepnotecho "$RESULT" | jq:echointerprets backslash sequences inside the captured JSON, turning embedded\ninto a real newline.jqthen aborts withInvalid string: control characters from U+0000 through U+001F must be escaped.printf '%s'emits the captured bytes verbatim. Same pattern applies to all wrapper-result parsing in this skill.
chorus CLI is not on PATHIf command -v chorus fails, mirror through the chorus-api.sh wrapper (or the absolute-path / inline-curl variants from the Rule 1 availability note). Define json_encode_file here (it is used only on this fallback path), then build $PAYLOAD with an embedded content. The chorus_check_response halt-on-error check applies exactly as on the primary path.
# Define once, fallback-only: byte-faithful file → JSON string.
json_encode_file() {
local _path="$1"
if command -v jq >/dev/null 2>&1; then
jq -Rs '.' < "$_path"
else
local _content
_content=$(cat "$_path")
_content=${_content//\\/\\\\}
_content=${_content//\"/\\\"}
_content=${_content//$'\n'/\\n}
printf '"%s"' "$_content"
fi
}
# PRD draft
CONTENT=$(json_encode_file "openspec/changes/$SLUG/proposal.md")
PAYLOAD=$(cat <<JSON
{
"proposalUuid": "$PROPOSAL_UUID",
"type": "prd",
"title": "PRD: $HUMAN_TITLE",
"content": $CONTENT
}
JSON
)
RESULT=$(chorus-api.sh mcp-tool chorus_pm_add_document_draft "$PAYLOAD")
RC=$?
chorus_check_response "chorus_pm_add_document_draft (prd)" "$RC" "$RESULT"
PRD_DRAFT_UUID=$(printf '%s' "$RESULT" | grep -o '"draftUuid"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')Local file changes propagate via chorus_pm_update_document_draft — same primary/fallback split as §3.6, same halt check. Primary (CLI):
RESULT=$(chorus mcp call chorus_pm_update_document_draft \
"{\"proposalUuid\":\"$PROPOSAL_UUID\",\"draftUuid\":\"$PRD_DRAFT_UUID\"}" \
--arg-file content="openspec/changes/$SLUG/proposal.md")
RC=$?
chorus_check_response "chorus_pm_update_document_draft" "$RC" "$RESULT"Fallback (no chorus on PATH) — json_encode_file from the §3.6 fallback block:
CONTENT=$(json_encode_file "openspec/changes/$SLUG/proposal.md")
PAYLOAD=$(cat <<JSON
{
"proposalUuid": "$PROPOSAL_UUID",
"draftUuid": "$PRD_DRAFT_UUID",
"content": $CONTENT
}
JSON
)
RESULT=$(chorus-api.sh mcp-tool chorus_pm_update_document_draft "$PAYLOAD")
RC=$?
chorus_check_response "chorus_pm_update_document_draft" "$RC" "$RESULT"Once the proposal is approved, drafts materialize into Documents with their own UUIDs. To keep openspec/changes/$SLUG/ and the Chorus Document in sync, mirror file edits via chorus_pm_update_document. Primary (CLI):
RESULT=$(chorus mcp call chorus_pm_update_document \
"{\"documentUuid\":\"$SPEC_DOCUMENT_UUID\"}" \
--arg-file content="openspec/changes/$SLUG/specs/<capability>/spec.md")
RC=$?
chorus_check_response "chorus_pm_update_document" "$RC" "$RESULT"Fallback (no chorus on PATH) — json_encode_file from the §3.6 fallback block:
CONTENT=$(json_encode_file "openspec/changes/$SLUG/specs/<capability>/spec.md")
PAYLOAD=$(cat <<JSON
{
"documentUuid": "$SPEC_DOCUMENT_UUID",
"content": $CONTENT
}
JSON
)
RESULT=$(chorus-api.sh mcp-tool chorus_pm_update_document "$PAYLOAD")
RC=$?
chorus_check_response "chorus_pm_update_document" "$RC" "$RESULT"To re-derive $SPEC_DOCUMENT_UUID from a fresh shell, look it up via chorus_get_documents for the proposal's project and match by title + type. Re-derive $SLUG by grepping the proposal's description for ^OpenSpec change slug: .
OpenClaw difference: the Claude Code plugin has a PostToolUse hook (
bin/on-post-verify-task.sh) that fires afterchorus_admin_verify_taskand injects anopenspec archive <slug>reminder. OpenClaw has no such hook. You (the agent) must detect the trigger yourself: after eachchorus_admin_verify_task, check whether the just-verified task was the LAST task of its OpenSpec-mode idea (every Task across every approved Proposal of that idea is nowdone/closed, and the proposaldescriptioncarries anOpenSpec change slug: <slug>line). If so, run the archive flow below. If not, do nothing.
When the trigger holds, you perform the archive:
Run archive locally. Use --yes for non-interactive mode. Do NOT pass --skip-specs (defeats the mirror-back) or --no-validate (lets malformed deltas corrupt cumulative specs).
openspec archive "$SLUG" --yesThis moves openspec/changes/$SLUG/ under openspec/changes/archive/<date>-<slug>/ and emits/updates openspec/specs/<capability>/spec.md for each capability. (Run openspec archive --help against your installed version to confirm the current flag set — flags can drift between releases.)
Mirror each updated openspec/specs/<capability>/spec.md back to the matching post-approval Chorus Document (§3.8 contract). chorus_get_documents only supports projectUuid + type server-side filters; filter by title client-side. One chorus_pm_update_document call per capability.
Halt on any error from openspec archive or chorus_pm_update_document. Print stderr verbatim, post a comment on the proposal recording the failure (chorus_add_comment with targetType: "proposal", targetUuid: <proposalUuid>), then stop. No retry. Matches §6 "no silent errors." (Comment on the proposal, not the idea: the failure is in archiving proposal-derived specs, and proposals can be inputType: "document" with no idea attached.)
Confirm success. List openspec/specs/<capability>/spec.md files and verify they round-trip byte-equal (modulo trailing newline) with their Chorus Document counterparts.
Strict opt-in: if the verified task is not the last of its idea, OR the proposal description carries no OpenSpec change slug: <slug> line, OR the local shell has no openspec CLI, do nothing — no archive. Existing free-form behavior is preserved.
When the §1 resolution does not yield a usable OpenSpec (CHORUS_OPENSPEC_ACTIVE=0, no SPEC_FAIL), this skill is a no-op — return to the calling skill, which follows the resolved mode: spec-lite (the default when OpenSpec isn't usable — see the spec-lite skill) or free-form (CHORUS_SPEC_MODE=off). From this skill's side, regardless of which:
openspec/changes/ folder is created or referenced.OpenSpec change slug: … line is added to the proposal description.In spec-lite the caller mirrors the dated-folder docs under .chorus/specs/<slug>/ via the same --arg-file transport + Rule 1 / Rule 2 (that is the spec-lite skill's job). In free-form (off) there is no local file source of truth, so document drafts are authored via direct MCP chorus_pm_add_document_draft calls with inline content — same as before this skill existed, and Rule 1 (file-fill mirror) does not apply.
| Local file | Chorus Document.type | Mirrored? |
|---|---|---|
openspec/changes/<slug>/proposal.md | prd | yes |
openspec/changes/<slug>/design.md | tech_design | yes |
openspec/changes/<slug>/specs/<capability>/spec.md | spec | yes (one draft per capability) |
openspec/changes/<slug>/tasks.md | (not mapped) | no — Chorus task drafts are source of truth |
prd, tech_design, spec are pre-existing valid Document.type values — no schema change required.
chorus_check_response helperThis helper guards both the primary CLI path and the fallback wrapper path. On the fallback path there is a known wrapper edge case: when the server returns HTTP 4xx (e.g. 401 from a bad CHORUS_API_KEY), chorus-api.sh mcp-tool captures the JSON-RPC error body internally, pipes it through a .result.content[]? jq filter that produces no output when .result is absent, and exits 0 with empty stdout. A bare RC=$? check would not halt on this — the most common runtime failure mode would be invisible. (If you reproduced the wrapper inline via curl per the Rule 1 note, the same three-signal check still applies to the raw HTTP body. chorus mcp call exits non-zero on tool/transport errors, so RC is reliable on the primary path — but run the same three-signal check on both, as defense in depth.)
Define this helper once at the top of the authoring session and use it after every mirror call (CLI or wrapper):
chorus_check_response() {
local _tool="$1"
local _rc="$2"
local _body="$3"
local _has_error=0
local _is_empty=0
local _trimmed
_trimmed=$(printf '%s' "$_body" | tr -d ' \t\n\r')
[ -z "$_trimmed" ] && _is_empty=1
if [ "$_is_empty" -eq 0 ]; then
if command -v jq >/dev/null 2>&1; then
if printf '%s' "$_body" | jq -e 'try ([.. | objects | has("error")] | any) catch false' >/dev/null 2>&1; then
_has_error=1
fi
else
printf '%s' "$_body" | grep -qE '"error"[[:space:]]*:' && _has_error=1
fi
fi
if [ "$_rc" -ne 0 ] || [ "$_has_error" -eq 1 ] || [ "$_is_empty" -eq 1 ]; then
echo "ERROR: $_tool failed (exit=$_rc, error_in_body=$_has_error, empty_body=$_is_empty)" >&2
echo "Output: $_body" >&2
[ "$_rc" -ne 0 ] && exit "$_rc" || exit 1
fi
}Anti-patterns — do not:
|| true./dev/null.$?).$RESULT into a variable; the helper needs the body.if [ "$RC" -ne 0 ]; then ... — that misses the HTTP-error path.Minimal call site shape (both paths):
# Primary — chorus CLI:
RESULT=$(chorus mcp call <tool_name> '<json-without-content>' --arg-file content=<file>)
RC=$?
chorus_check_response "<tool_name>" "$RC" "$RESULT"
# Fallback — chorus-api.sh wrapper (chorus not on PATH):
RESULT=$(chorus-api.sh mcp-tool <tool_name> "$PAYLOAD")
RC=$?
chorus_check_response "<tool_name>" "$RC" "$RESULT"
# ...if we reach here, the call succeeded; parse RESULT and continue.This is project-wide policy: no silent errors.
When invoked from a stage skill (proposal / develop / yolo):
bin/resolve-spec-mode.sh. It resolves the whole contract (lite / openspec / off); do NOT hand-roll an OpenSpec-only check or re-derive the rule from prose.SPEC_FAIL is set (explicit CHORUS_SPEC_MODE=openspec unusable) → halt and surface it. If CHORUS_OPENSPEC_ACTIVE=0 (resolved mode = spec-lite or free-form) → no-op; return to the caller per the resolved mode (§4).CHORUS_OPENSPEC_ACTIVE=1):
a. Pick $SLUG (§3.1).
b. openspec new change "$SLUG" (§3.2).
c. Author proposal.md, design.md, specs/<capability>/spec.md (§3.2–§3.3). Mix ADDED / MODIFIED / REMOVED / RENAMED blocks as needed; remember MODIFIED overwrites the whole Requirement.
d. Optional: openspec validate "$SLUG".
e. chorus_pm_create_proposal (direct MCP) with the OpenSpec change slug: $SLUG line in description (§3.5).
f. Export CHORUS_URL / CHORUS_API_KEY (both the CLI and the wrapper read them); define the chorus_check_response helper. Prefer chorus mcp call … --arg-file content=<file> for mirrors (§3.6) — no json_encode_file needed on that path; define json_encode_file and confirm chorus-api.sh is reachable (Rule 1 note) only when falling back to the wrapper because chorus is not on PATH.
g. For each row in §5 with "yes" — mirror via chorus mcp call chorus_pm_add_document_draft … --arg-file content=<file> (§3.6; fallback = chorus-api.sh mcp-tool). Record each $DRAFT_UUID.
h. On any failed chorus_check_response — halt, surface the error, do NOT proceed.© Chorus-AIDLC, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in packages/openclaw-plugin/skills/openspec-aware of Chorus-AIDLC/Chorus.
Open the folder on GitHubat commit 4754822
Openspec Aware next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Openspec Aware this skillChorus-AIDLC/Chorus | 1.2k | — | ~7.6k | Automated safety check: Pass | AGPL-3.0 | |
| Chatgpt AppsHaohao-end/openagent | 808 | 1 repos | ~4.9k | Automated safety check: Pass | Apache-2.0 | |
| Tsed CLItsedio/tsed | 3.1k | — | ~2.7k | Automated safety check: Pass | MIT | |
| Ue Code AuthoringJasonMa0012/MooaToon | 750 | — | ~1.9k | Automated safety check: Notes | Custom licence | |
| Brain Bootstrapmindmuxai/brain.md | 566 | — | ~1.8k | Automated safety check: Pass | Apache-2.0 | |
| Diag Harnessruvnet/metaharness | 694 | — | ~835 | Automated safety check: Pass | MIT |
Haohao-end/openagent
Build, scaffold, refactor, and troubleshoot ChatGPT Apps SDK applications that combine an MCP server and widget UI.
tsedio/tsed
Scaffolds Ts.ED v8 projects and generates files with the Ts.ED CLI v7, through its MCP server (tools set-workspace, init-project, list-templates, get-template, generate-file) or the tsed binary…
JasonMa0012/MooaToon
A skill your agent uses when writing or modifying UE C++ (classes, actors, components, subsystems, interfaces, function libraries) with Rider MCP available.
mindmuxai/brain.md
Seed a freshly-scaffolded brain with real project knowledge — on an existing (brownfield) project read the code, docs, and git log to draft the six root pages and capture key historical decisions…
ruvnet/metaharness
Kernel-version skew check (ADR-027). An agent skill from ruvnet/metaharness.
ucsandman/DashClaw
Contribute to the DashClaw codebase — architecture, scaffolding, tests, CI
Chorus-AIDLC/Chorus
A skill your agent uses when manually verifying a Chorus frontend change in a real browser — finding local login credentials, driving the running dev server with the Playwright MCP, logging in…
Chorus-AIDLC/Chorus
Write release blog posts for Chorus — problem-first narrative, bilingual (zh/en), following the project's editorial style.
Chorus-AIDLC/Chorus
Optional divergent-then-convergent dialogue for fuzzy ideas on Hermes.
Chorus-AIDLC/Chorus
Optional divergent-then-convergent dialogue for fuzzy ideas.
Chorus-AIDLC/Chorus
Optional divergent-then-convergent dialogue for fuzzy ideas.
Chorus-AIDLC/Chorus
Optional divergent-then-convergent dialogue for fuzzy ideas.
Works with
OpenSpec-mode authoring for Chorus PM workflows on OpenClaw — the default whenever OpenSpec is usable. Openspec Aware is an agent skill from Chorus-AIDLC/Chorus. OpenSpec-mode authoring for Chorus PM workflows on OpenClaw — the default whenever OpenSpec is usable.
Openspec Aware fits situations like: tasks that involve Computer vision; tasks that involve Project scaffolding.
Run `npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a claude-code`. Or copy the skill folder (packages/openclaw-plugin/skills/openspec-aware in Chorus-AIDLC/Chorus) into .claude/skills/openspec-aware in your project. Claude Code loads it when a task matches its description.
Run `npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a codex`. Or copy the skill folder (packages/openclaw-plugin/skills/openspec-aware in Chorus-AIDLC/Chorus) into .agents/skills/openspec-aware in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Chorus-AIDLC/Chorus --skill openspec-aware -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/openspec-aware, .gemini/skills/openspec-aware, .github/skills/openspec-aware and .opencode/skills/openspec-aware in your project.
Going by SKILL.md and its folder, Openspec Aware needs the command-line tools its instructions call (jq and npm) and credentials named CHORUS_API_KEY. Our summary lists: Node.js; A credential in CHORUS_API_KEY.
SKILL.md names 1 domain. As links in the text: github.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Openspec Aware is published under the AGPL-3.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.6k tokens (SKILL.md is roughly 30k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Openspec Aware: Chatgpt Apps (Haohao-end/openagent, 808 stars), Tsed CLI (tsedio/tsed, 3.1k stars), Ue Code Authoring (JasonMa0012/MooaToon, 750 stars) and Brain Bootstrap (mindmuxai/brain.md, 566 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Chorus-AIDLC (a GitHub organization) maintains it in Chorus-AIDLC/Chorus, which has 1,191 GitHub stars. The repository holds 64 skills in this directory. The repository was last updated on October 9, 2026.
Source: Chorus-AIDLC/Chorus on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.