mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-30 14:03:29 +08:00
Compare commits
50 Commits
dependabot
...
fix/insait
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f92dc544c4 | ||
|
|
1c2d5dd389 | ||
|
|
b40de37ccb | ||
|
|
63485a26bf | ||
|
|
fe40a3d27b | ||
|
|
2c56c9c69f | ||
|
|
d9d52d8b77 | ||
|
|
2eaafc38f6 | ||
|
|
c7c7d37f29 | ||
|
|
b6b5b6d08e | ||
|
|
f6acf6e19f | ||
|
|
46aa301f1d | ||
|
|
fd95cf6b29 | ||
|
|
83d6bb230d | ||
|
|
6c8a6bd7c0 | ||
|
|
d89f8d895d | ||
|
|
0a87323eda | ||
|
|
5595c074fe | ||
|
|
530088c77c | ||
|
|
177b8f31da | ||
|
|
4e66b2882d | ||
|
|
e63241c699 | ||
|
|
81bde5c3cd | ||
|
|
602894efdd | ||
|
|
df9a478ea1 | ||
|
|
92e0c7e9ff | ||
|
|
8c422a76f4 | ||
|
|
8ae1499122 | ||
|
|
c42818f103 | ||
|
|
601c626b03 | ||
|
|
14f8f66833 | ||
|
|
32e3a31c3e | ||
|
|
b27551897d | ||
|
|
20041294d9 | ||
|
|
163cdee60f | ||
|
|
b6bce947f1 | ||
|
|
1ebf45c533 | ||
|
|
c32f0fffb1 | ||
|
|
d87304573c | ||
|
|
86511491a6 | ||
|
|
7b53efc709 | ||
|
|
797692d70f | ||
|
|
8bdf88e5ad | ||
|
|
0c3fc7074e | ||
|
|
01d816781e | ||
|
|
93cd5f4cff | ||
|
|
a35b2d125d | ||
|
|
53a599fc03 | ||
|
|
c19fde229a | ||
|
|
7992f8fcb8 |
@@ -6,7 +6,7 @@
|
||||
"plugins": [
|
||||
{
|
||||
"name": "ecc",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.1",
|
||||
"source": {
|
||||
"source": "local",
|
||||
"path": "../.."
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: agent-introspection-debugging
|
||||
description: Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Agent Introspection Debugging
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
interface:
|
||||
display_name: "Agent Introspection Debugging"
|
||||
short_description: "Structured self-debugging for AI agent failures"
|
||||
brand_color: "#0EA5E9"
|
||||
default_prompt: "Use $agent-introspection-debugging to diagnose and recover from an AI agent failure."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: agent-sort
|
||||
description: Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Agent Sort
|
||||
|
||||
7
.agents/skills/agent-sort/agents/openai.yaml
Normal file
7
.agents/skills/agent-sort/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
interface:
|
||||
display_name: "Agent Sort"
|
||||
short_description: "Evidence-backed ECC install planning"
|
||||
brand_color: "#0EA5E9"
|
||||
default_prompt: "Use $agent-sort to build an evidence-backed ECC install plan."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: api-design
|
||||
description: REST API design patterns including resource naming, status codes, pagination, filtering, error responses, versioning, and rate limiting for production APIs.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# API Design Patterns
|
||||
|
||||
@@ -2,6 +2,6 @@ interface:
|
||||
display_name: "API Design"
|
||||
short_description: "REST API design patterns and best practices"
|
||||
brand_color: "#F97316"
|
||||
default_prompt: "Design REST API: resources, status codes, pagination"
|
||||
default_prompt: "Use $api-design to design production REST API resources and responses."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: article-writing
|
||||
description: Write articles, guides, blog posts, tutorials, newsletter issues, and other long-form content in a distinctive voice derived from supplied examples or brand guidance. Use when the user wants polished written content longer than a paragraph, especially when voice consistency, structure, and credibility matter.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Article Writing
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Article Writing"
|
||||
short_description: "Write long-form content in a supplied voice without sounding templated"
|
||||
short_description: "Long-form content in a supplied voice"
|
||||
brand_color: "#B45309"
|
||||
default_prompt: "Draft a sharp long-form article from these notes and examples"
|
||||
default_prompt: "Use $article-writing to draft polished long-form content in the supplied voice."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: backend-patterns
|
||||
description: Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Backend Development Patterns
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Backend Patterns"
|
||||
short_description: "API design, database, and server-side patterns"
|
||||
short_description: "API, database, and server-side patterns"
|
||||
brand_color: "#F59E0B"
|
||||
default_prompt: "Apply backend patterns: API design, repository, caching"
|
||||
default_prompt: "Use $backend-patterns to apply backend architecture and API patterns."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: brand-voice
|
||||
description: Build a source-derived writing style profile from real posts, essays, launch notes, docs, or site copy, then reuse that profile across content, outreach, and social workflows. Use when the user wants voice consistency without generic AI writing tropes.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Brand Voice
|
||||
|
||||
7
.agents/skills/brand-voice/agents/openai.yaml
Normal file
7
.agents/skills/brand-voice/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
interface:
|
||||
display_name: "Brand Voice"
|
||||
short_description: "Source-derived writing style profiles"
|
||||
brand_color: "#0EA5E9"
|
||||
default_prompt: "Use $brand-voice to derive and reuse a source-grounded writing style."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: bun-runtime
|
||||
description: Bun as runtime, package manager, bundler, and test runner. When to choose Bun vs Node, migration notes, and Vercel support.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Bun Runtime
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Bun Runtime"
|
||||
short_description: "Bun as runtime, package manager, bundler, and test runner"
|
||||
short_description: "Bun runtime, package manager, and test runner"
|
||||
brand_color: "#FBF0DF"
|
||||
default_prompt: "Use Bun for scripts, install, or run"
|
||||
default_prompt: "Use $bun-runtime to choose and apply Bun runtime workflows."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: claude-api
|
||||
description: Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Claude API
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Claude API"
|
||||
short_description: "Anthropic Claude API patterns and SDKs"
|
||||
short_description: "Claude API patterns for Python and TypeScript"
|
||||
brand_color: "#D97706"
|
||||
default_prompt: "Build applications with the Claude API using Messages, tool use, streaming, and Agent SDK"
|
||||
default_prompt: "Use $claude-api to build with Claude API and Anthropic SDK patterns."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: coding-standards
|
||||
description: Baseline cross-project coding conventions for naming, readability, immutability, and code-quality review. Use detailed frontend or backend skills for framework-specific patterns.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Coding Standards & Best Practices
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Coding Standards"
|
||||
short_description: "Universal coding standards and best practices"
|
||||
short_description: "Cross-project coding conventions and review"
|
||||
brand_color: "#3B82F6"
|
||||
default_prompt: "Apply standards: immutability, error handling, type safety"
|
||||
default_prompt: "Use $coding-standards to review code against cross-project standards."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: content-engine
|
||||
description: Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Content Engine
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Content Engine"
|
||||
short_description: "Turn one idea into platform-native social and content outputs"
|
||||
short_description: "Platform-native content systems and campaigns"
|
||||
brand_color: "#DC2626"
|
||||
default_prompt: "Turn this source asset into strong multi-platform content"
|
||||
default_prompt: "Use $content-engine to turn source material into platform-native content."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: crosspost
|
||||
description: Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Crosspost
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Crosspost"
|
||||
short_description: "Multi-platform content distribution with native adaptation"
|
||||
short_description: "Multi-platform social distribution"
|
||||
brand_color: "#EC4899"
|
||||
default_prompt: "Distribute content across X, LinkedIn, Threads, and Bluesky with platform-native adaptation"
|
||||
default_prompt: "Use $crosspost to adapt content for multiple social platforms."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: deep-research
|
||||
description: Multi-source deep research using firecrawl and exa MCPs. Searches the web, synthesizes findings, and delivers cited reports with source attribution. Use when the user wants thorough research on any topic with evidence and citations.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Deep Research
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Deep Research"
|
||||
short_description: "Multi-source deep research with firecrawl and exa MCPs"
|
||||
short_description: "Multi-source cited research reports"
|
||||
brand_color: "#6366F1"
|
||||
default_prompt: "Research the given topic using firecrawl and exa, produce a cited report"
|
||||
default_prompt: "Use $deep-research to produce a cited multi-source research report."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: dmux-workflows
|
||||
description: Multi-agent orchestration using dmux (tmux pane manager for AI agents). Patterns for parallel agent workflows across Claude Code, Codex, OpenCode, and other harnesses. Use when running multiple agent sessions in parallel or coordinating multi-agent development workflows.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# dmux Workflows
|
||||
|
||||
@@ -2,6 +2,6 @@ interface:
|
||||
display_name: "dmux Workflows"
|
||||
short_description: "Multi-agent orchestration with dmux"
|
||||
brand_color: "#14B8A6"
|
||||
default_prompt: "Orchestrate parallel agent sessions using dmux pane manager"
|
||||
default_prompt: "Use $dmux-workflows to orchestrate parallel agent sessions with dmux."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: documentation-lookup
|
||||
description: Use up-to-date library and framework docs via Context7 MCP instead of training data. Activates for setup questions, API references, code examples, or when the user names a framework (e.g. React, Next.js, Prisma).
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Documentation Lookup (Context7)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Documentation Lookup"
|
||||
short_description: "Fetch up-to-date library docs via Context7 MCP"
|
||||
short_description: "Current library docs via Context7"
|
||||
brand_color: "#6366F1"
|
||||
default_prompt: "Look up docs for a library or API"
|
||||
default_prompt: "Use $documentation-lookup to fetch current library documentation via Context7."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: e2e-testing
|
||||
description: Playwright E2E testing patterns, Page Object Model, configuration, CI/CD integration, artifact management, and flaky test strategies.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# E2E Testing Patterns
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "E2E Testing"
|
||||
short_description: "Playwright end-to-end testing"
|
||||
short_description: "Playwright E2E testing patterns"
|
||||
brand_color: "#06B6D4"
|
||||
default_prompt: "Generate Playwright E2E tests with Page Object Model"
|
||||
default_prompt: "Use $e2e-testing to design Playwright end-to-end test coverage."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
name: eval-harness
|
||||
description: Formal evaluation framework for Claude Code sessions implementing eval-driven development (EDD) principles
|
||||
origin: ECC
|
||||
tools: Read, Write, Edit, Bash, Grep, Glob
|
||||
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
||||
---
|
||||
|
||||
# Eval Harness Skill
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Eval Harness"
|
||||
short_description: "Eval-driven development with pass/fail criteria"
|
||||
short_description: "Eval-driven development harnesses"
|
||||
brand_color: "#EC4899"
|
||||
default_prompt: "Set up eval-driven development with pass/fail criteria"
|
||||
default_prompt: "Use $eval-harness to define eval-driven development checks."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: everything-claude-code-conventions
|
||||
name: everything-claude-code
|
||||
description: Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
interface:
|
||||
display_name: "Everything Claude Code"
|
||||
short_description: "Repo-specific patterns and workflows for everything-claude-code"
|
||||
default_prompt: "Use the everything-claude-code repo skill to follow existing architecture, testing, and workflow conventions."
|
||||
short_description: "Repo workflows for everything-claude-code"
|
||||
brand_color: "#0EA5E9"
|
||||
default_prompt: "Use $everything-claude-code to follow this repository's conventions and workflows."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: exa-search
|
||||
description: Neural search via Exa MCP for web, code, and company research. Use when the user needs web search, code examples, company intel, people lookup, or AI-powered deep research with Exa's neural search engine.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Exa Search
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Exa Search"
|
||||
short_description: "Neural search via Exa MCP for web, code, and companies"
|
||||
short_description: "Neural search via Exa MCP"
|
||||
brand_color: "#8B5CF6"
|
||||
default_prompt: "Search using Exa MCP tools for web content, code, or company research"
|
||||
default_prompt: "Use $exa-search to search web, code, or company data through Exa."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: fal-ai-media
|
||||
description: Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# fal.ai Media Generation
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "fal.ai Media"
|
||||
short_description: "AI image, video, and audio generation via fal.ai"
|
||||
short_description: "AI media generation via fal.ai"
|
||||
brand_color: "#F43F5E"
|
||||
default_prompt: "Generate images, videos, or audio using fal.ai models"
|
||||
default_prompt: "Use $fal-ai-media to generate image, video, or audio assets with fal.ai."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: frontend-design
|
||||
description: Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Frontend Design
|
||||
|
||||
7
.agents/skills/frontend-design/agents/openai.yaml
Normal file
7
.agents/skills/frontend-design/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
interface:
|
||||
display_name: "Frontend Design"
|
||||
short_description: "Production-grade frontend interface design"
|
||||
brand_color: "#0EA5E9"
|
||||
default_prompt: "Use $frontend-design to build a distinctive production-grade interface."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: frontend-patterns
|
||||
description: Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Frontend Development Patterns
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Frontend Patterns"
|
||||
short_description: "React and Next.js patterns and best practices"
|
||||
short_description: "React and Next.js frontend patterns"
|
||||
brand_color: "#8B5CF6"
|
||||
default_prompt: "Apply React/Next.js patterns and best practices"
|
||||
default_prompt: "Use $frontend-patterns to apply React and Next.js frontend patterns."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: frontend-slides
|
||||
description: Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Frontend Slides
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Frontend Slides"
|
||||
short_description: "Create distinctive HTML slide decks and convert PPTX to web"
|
||||
short_description: "Animation-rich HTML presentation decks"
|
||||
brand_color: "#FF6B3D"
|
||||
default_prompt: "Create a viewport-safe HTML presentation with strong visual direction"
|
||||
default_prompt: "Use $frontend-slides to create an animation-rich HTML presentation deck."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: investor-materials
|
||||
description: Create and update pitch decks, one-pagers, investor memos, accelerator applications, financial models, and fundraising materials. Use when the user needs investor-facing documents, projections, use-of-funds tables, milestone plans, or materials that must stay internally consistent across multiple fundraising assets.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Investor Materials
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Investor Materials"
|
||||
short_description: "Create decks, memos, and financial materials from one source of truth"
|
||||
short_description: "Investor decks, memos, and financial materials"
|
||||
brand_color: "#7C3AED"
|
||||
default_prompt: "Draft investor materials that stay numerically consistent across assets"
|
||||
default_prompt: "Use $investor-materials to draft consistent investor-facing fundraising assets."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: investor-outreach
|
||||
description: Draft cold emails, warm intro blurbs, follow-ups, update emails, and investor communications for fundraising. Use when the user wants outreach to angels, VCs, strategic investors, or accelerators and needs concise, personalized, investor-facing messaging.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Investor Outreach
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Investor Outreach"
|
||||
short_description: "Write concise, personalized outreach and follow-ups for fundraising"
|
||||
short_description: "Personalized investor outreach and follow-ups"
|
||||
brand_color: "#059669"
|
||||
default_prompt: "Draft a personalized investor outreach email with a clear low-friction ask"
|
||||
default_prompt: "Use $investor-outreach to write concise personalized investor outreach."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: market-research
|
||||
description: Conduct market research, competitive analysis, investor due diligence, and industry intelligence with source attribution and decision-oriented summaries. Use when the user wants market sizing, competitor comparisons, fund research, technology scans, or research that informs business decisions.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Market Research
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Market Research"
|
||||
short_description: "Source-attributed market, competitor, and investor research"
|
||||
short_description: "Source-attributed market research"
|
||||
brand_color: "#2563EB"
|
||||
default_prompt: "Research this market and summarize the decision-relevant findings"
|
||||
default_prompt: "Use $market-research to research markets with source-attributed findings."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: mcp-server-patterns
|
||||
description: Build MCP servers with Node/TypeScript SDK — tools, resources, prompts, Zod validation, stdio vs Streamable HTTP. Use Context7 or official MCP docs for latest API.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# MCP Server Patterns
|
||||
|
||||
7
.agents/skills/mcp-server-patterns/agents/openai.yaml
Normal file
7
.agents/skills/mcp-server-patterns/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
interface:
|
||||
display_name: "MCP Server Patterns"
|
||||
short_description: "MCP server tools, resources, and prompts"
|
||||
brand_color: "#0EA5E9"
|
||||
default_prompt: "Use $mcp-server-patterns to build MCP tools, resources, and prompts."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: nextjs-turbopack
|
||||
description: Next.js 16+ and Turbopack — incremental bundling, FS caching, dev speed, and when to use Turbopack vs webpack.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Next.js and Turbopack
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Next.js Turbopack"
|
||||
short_description: "Next.js 16+ and Turbopack dev bundler"
|
||||
short_description: "Next.js and Turbopack workflow guidance"
|
||||
brand_color: "#000000"
|
||||
default_prompt: "Next.js dev, Turbopack, or bundle optimization"
|
||||
default_prompt: "Use $nextjs-turbopack to work through Next.js and Turbopack decisions."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: product-capability
|
||||
description: Translate PRD intent, roadmap asks, or product discussions into an implementation-ready capability plan that exposes constraints, invariants, interfaces, and unresolved decisions before multi-service work starts. Use when the user needs an ECC-native PRD-to-SRS lane instead of vague planning prose.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Product Capability
|
||||
|
||||
7
.agents/skills/product-capability/agents/openai.yaml
Normal file
7
.agents/skills/product-capability/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
interface:
|
||||
display_name: "Product Capability"
|
||||
short_description: "Implementation-ready product capability plans"
|
||||
brand_color: "#0EA5E9"
|
||||
default_prompt: "Use $product-capability to turn product intent into an implementation plan."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: security-review
|
||||
description: Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Security Review Skill
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Security Review"
|
||||
short_description: "Comprehensive security checklist and vulnerability detection"
|
||||
short_description: "Security checklist and vulnerability review"
|
||||
brand_color: "#EF4444"
|
||||
default_prompt: "Run security checklist: secrets, input validation, injection prevention"
|
||||
default_prompt: "Use $security-review to review sensitive code with the security checklist."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: strategic-compact
|
||||
description: Suggests manual context compaction at logical intervals to preserve context through task phases rather than arbitrary auto-compaction.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Strategic Compact Skill
|
||||
|
||||
@@ -2,6 +2,6 @@ interface:
|
||||
display_name: "Strategic Compact"
|
||||
short_description: "Context management via strategic compaction"
|
||||
brand_color: "#14B8A6"
|
||||
default_prompt: "Suggest task boundary compaction for context management"
|
||||
default_prompt: "Use $strategic-compact to choose a useful context compaction boundary."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: tdd-workflow
|
||||
description: Use this skill when writing new features, fixing bugs, or refactoring code. Enforces test-driven development with 80%+ coverage including unit, integration, and E2E tests.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Test-Driven Development Workflow
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "TDD Workflow"
|
||||
short_description: "Test-driven development with 80%+ coverage"
|
||||
short_description: "Test-driven development with coverage gates"
|
||||
brand_color: "#22C55E"
|
||||
default_prompt: "Follow TDD: write tests first, implement, verify 80%+ coverage"
|
||||
default_prompt: "Use $tdd-workflow to drive the change with tests before implementation."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: verification-loop
|
||||
description: "A comprehensive verification system for Claude Code sessions."
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Verification Loop Skill
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Verification Loop"
|
||||
short_description: "Build, test, lint, typecheck verification"
|
||||
short_description: "Build, test, lint, and typecheck verification"
|
||||
brand_color: "#10B981"
|
||||
default_prompt: "Run verification: build, test, lint, typecheck, security"
|
||||
default_prompt: "Use $verification-loop to run build, test, lint, and typecheck verification."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: video-editing
|
||||
description: AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Video Editing
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "Video Editing"
|
||||
short_description: "AI-assisted video editing for real footage"
|
||||
short_description: "AI-assisted editing for real footage"
|
||||
brand_color: "#EF4444"
|
||||
default_prompt: "Edit video using AI-assisted pipeline: organize, cut, compose, generate assets, polish"
|
||||
default_prompt: "Use $video-editing to plan an AI-assisted edit for real footage."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: x-api
|
||||
description: X/Twitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# X API
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface:
|
||||
display_name: "X API"
|
||||
short_description: "X/Twitter API integration for posting, threads, and analytics"
|
||||
short_description: "X API posting, timelines, and analytics"
|
||||
brand_color: "#000000"
|
||||
default_prompt: "Use X API to post tweets, threads, or retrieve timeline and search data"
|
||||
default_prompt: "Use $x-api to build X API posting, timeline, or analytics workflows."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
||||
@@ -45,60 +45,37 @@ Example:
|
||||
|
||||
The following fields **must always be arrays**:
|
||||
|
||||
* `agents`
|
||||
* `commands`
|
||||
* `skills`
|
||||
* `hooks` (if present)
|
||||
|
||||
Even if there is only one entry, **strings are not accepted**.
|
||||
|
||||
### Invalid
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": "./agents"
|
||||
}
|
||||
```
|
||||
|
||||
### Valid
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": ["./agents/planner.md"]
|
||||
}
|
||||
```
|
||||
|
||||
This applies consistently across all component path fields.
|
||||
|
||||
---
|
||||
|
||||
## Path Resolution Rules (Critical)
|
||||
## The `agents` Field: DO NOT ADD
|
||||
|
||||
### Agents MUST use explicit file paths
|
||||
> WARNING: **CRITICAL:** Do NOT add an `"agents"` field to `plugin.json`. The Claude Code plugin validator rejects it entirely.
|
||||
|
||||
The validator **does not accept directory paths for `agents`**.
|
||||
### Why This Matters
|
||||
|
||||
Even the following will fail:
|
||||
The `agents` field is not part of the Claude Code plugin manifest schema. Any form of it -- string path, array of paths, or array of directories -- causes a validation error:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": ["./agents/"]
|
||||
}
|
||||
```
|
||||
agents: Invalid input
|
||||
```
|
||||
|
||||
Instead, you must enumerate agent files explicitly:
|
||||
Agent `.md` files under `agents/` are discovered automatically by convention (similar to hooks). They do not need to be declared in the manifest.
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": [
|
||||
"./agents/planner.md",
|
||||
"./agents/architect.md",
|
||||
"./agents/code-reviewer.md"
|
||||
]
|
||||
}
|
||||
```
|
||||
### History
|
||||
|
||||
This is the most common source of validation errors.
|
||||
Previously this repo listed agents explicitly in `plugin.json` as an array of file paths. This passed the repo's own schema but failed Claude Code's actual validator, which does not recognize the field. Removed in #1459.
|
||||
|
||||
---
|
||||
|
||||
## Path Resolution Rules
|
||||
|
||||
### Commands and Skills
|
||||
|
||||
@@ -160,7 +137,7 @@ The test `plugin.json does NOT have explicit hooks declaration` in `tests/hooks/
|
||||
These look correct but are rejected:
|
||||
|
||||
* String values instead of arrays
|
||||
* Arrays of directories for `agents`
|
||||
* **Adding `"agents"` in any form** - not a recognized manifest field, causes `Invalid input`
|
||||
* Missing `version`
|
||||
* Relying on inferred paths
|
||||
* Assuming marketplace behavior matches local validation
|
||||
@@ -175,10 +152,6 @@ Avoid cleverness. Be explicit.
|
||||
```json
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"agents": [
|
||||
"./agents/planner.md",
|
||||
"./agents/code-reviewer.md"
|
||||
],
|
||||
"commands": ["./commands/"],
|
||||
"skills": ["./skills/"]
|
||||
}
|
||||
@@ -186,7 +159,7 @@ Avoid cleverness. Be explicit.
|
||||
|
||||
This structure has been validated against the Claude plugin validator.
|
||||
|
||||
**Important:** Notice there is NO `"hooks"` field. The `hooks/hooks.json` file is loaded automatically by convention. Adding it explicitly causes a duplicate error.
|
||||
**Important:** Notice there is NO `"hooks"` field and NO `"agents"` field. Both are loaded automatically by convention. Adding either explicitly causes errors.
|
||||
|
||||
---
|
||||
|
||||
@@ -194,9 +167,9 @@ This structure has been validated against the Claude plugin validator.
|
||||
|
||||
Before submitting changes that touch `plugin.json`:
|
||||
|
||||
1. Use explicit file paths for agents
|
||||
2. Ensure all component fields are arrays
|
||||
3. Include a `version`
|
||||
1. Ensure all component fields are arrays
|
||||
2. Include a `version`
|
||||
3. Do NOT add `agents` or `hooks` fields (both are auto-loaded by convention)
|
||||
4. Run:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
### Plugin Manifest Gotchas
|
||||
|
||||
If you plan to edit `.claude-plugin/plugin.json`, be aware that the Claude plugin validator enforces several **undocumented but strict constraints** that can cause installs to fail with vague errors (for example, `agents: Invalid input`). In particular, component fields must be arrays, `agents` must use explicit file paths rather than directories, and a `version` field is required for reliable validation and installation.
|
||||
If you plan to edit `.claude-plugin/plugin.json`, be aware that the Claude plugin validator enforces several **undocumented but strict constraints** that can cause installs to fail with vague errors (for example, `agents: Invalid input`). In particular, component fields must be arrays, `agents` is not a supported manifest field and must not be included in plugin.json, and a `version` field is required for reliable validation and installation.
|
||||
|
||||
These constraints are not obvious from public examples and have caused repeated installation failures in the past. They are documented in detail in `.claude-plugin/PLUGIN_SCHEMA_NOTES.md`, which should be reviewed before making any changes to the plugin manifest.
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"name": "everything-claude-code",
|
||||
"source": "./",
|
||||
"description": "The most comprehensive Claude Code plugin — 38 agents, 156 skills, 72 legacy command shims, selective install profiles, and production-ready hooks for TDD, security scanning, code review, and continuous learning",
|
||||
"version": "1.10.0",
|
||||
"description": "The most comprehensive Claude Code plugin — 48 agents, 184 skills, 79 legacy command shims, selective install profiles, and production-ready hooks for TDD, security scanning, code review, and continuous learning",
|
||||
"version": "2.0.0-rc.1",
|
||||
"author": {
|
||||
"name": "Affaan Mustafa",
|
||||
"email": "me@affaanmustafa.com"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "everything-claude-code",
|
||||
"version": "1.10.0",
|
||||
"description": "Battle-tested Claude Code plugin for engineering teams — 38 agents, 156 skills, 72 legacy command shims, production-ready hooks, and selective install workflows evolved through continuous real-world use",
|
||||
"version": "2.0.0-rc.1",
|
||||
"description": "Battle-tested Claude Code plugin for engineering teams — 48 agents, 184 skills, 79 legacy command shims, production-ready hooks, and selective install workflows evolved through continuous real-world use",
|
||||
"author": {
|
||||
"name": "Affaan Mustafa",
|
||||
"url": "https://x.com/affaanmustafa"
|
||||
@@ -22,46 +22,6 @@
|
||||
"automation",
|
||||
"best-practices"
|
||||
],
|
||||
"agents": [
|
||||
"./agents/architect.md",
|
||||
"./agents/build-error-resolver.md",
|
||||
"./agents/chief-of-staff.md",
|
||||
"./agents/code-reviewer.md",
|
||||
"./agents/cpp-build-resolver.md",
|
||||
"./agents/cpp-reviewer.md",
|
||||
"./agents/csharp-reviewer.md",
|
||||
"./agents/dart-build-resolver.md",
|
||||
"./agents/database-reviewer.md",
|
||||
"./agents/doc-updater.md",
|
||||
"./agents/docs-lookup.md",
|
||||
"./agents/e2e-runner.md",
|
||||
"./agents/flutter-reviewer.md",
|
||||
"./agents/gan-evaluator.md",
|
||||
"./agents/gan-generator.md",
|
||||
"./agents/gan-planner.md",
|
||||
"./agents/go-build-resolver.md",
|
||||
"./agents/go-reviewer.md",
|
||||
"./agents/harness-optimizer.md",
|
||||
"./agents/healthcare-reviewer.md",
|
||||
"./agents/java-build-resolver.md",
|
||||
"./agents/java-reviewer.md",
|
||||
"./agents/kotlin-build-resolver.md",
|
||||
"./agents/kotlin-reviewer.md",
|
||||
"./agents/loop-operator.md",
|
||||
"./agents/opensource-forker.md",
|
||||
"./agents/opensource-packager.md",
|
||||
"./agents/opensource-sanitizer.md",
|
||||
"./agents/performance-optimizer.md",
|
||||
"./agents/planner.md",
|
||||
"./agents/python-reviewer.md",
|
||||
"./agents/pytorch-build-resolver.md",
|
||||
"./agents/refactor-cleaner.md",
|
||||
"./agents/rust-build-resolver.md",
|
||||
"./agents/rust-reviewer.md",
|
||||
"./agents/security-reviewer.md",
|
||||
"./agents/tdd-guide.md",
|
||||
"./agents/typescript-reviewer.md"
|
||||
],
|
||||
"skills": ["./skills/"],
|
||||
"commands": ["./commands/"]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ecc",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.1",
|
||||
"description": "Battle-tested Codex workflows — 156 shared ECC skills, production-ready MCP configs, and selective-install-aligned conventions for TDD, security scanning, code review, and autonomous development.",
|
||||
"author": {
|
||||
"name": "Affaan Mustafa",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"version": 1,
|
||||
"hooks": {
|
||||
"sessionStart": [
|
||||
{
|
||||
|
||||
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@@ -2,7 +2,8 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
branches: [main, 'release/**']
|
||||
tags: ['v*']
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
@@ -76,7 +77,7 @@ jobs:
|
||||
|
||||
- name: Cache npm
|
||||
if: matrix.pm == 'npm'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ matrix.node }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
@@ -93,7 +94,7 @@ jobs:
|
||||
|
||||
- name: Cache pnpm
|
||||
if: matrix.pm == 'pnpm'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ matrix.node }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
@@ -114,7 +115,7 @@ jobs:
|
||||
|
||||
- name: Cache yarn
|
||||
if: matrix.pm == 'yarn'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -123,7 +124,7 @@ jobs:
|
||||
|
||||
- name: Cache bun
|
||||
if: matrix.pm == 'bun'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||
|
||||
20
.github/workflows/release.yml
vendored
20
.github/workflows/release.yml
vendored
@@ -33,8 +33,8 @@ jobs:
|
||||
|
||||
- name: Validate version tag
|
||||
run: |
|
||||
if ! [[ "${REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Invalid version tag format. Expected vX.Y.Z"
|
||||
if ! [[ "${REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
|
||||
echo "Invalid version tag format. Expected vX.Y.Z or vX.Y.Z-prerelease"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -60,17 +60,13 @@ jobs:
|
||||
run: |
|
||||
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
||||
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
||||
NPM_DIST_TAG=$(node -p "require('./package.json').version.includes('-') ? 'next' : 'latest'")
|
||||
if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version >/dev/null 2>&1; then
|
||||
echo "already_published=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "already_published=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Publish npm package
|
||||
if: steps.npm_publish_state.outputs.already_published != 'true'
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npm publish --access public --provenance
|
||||
echo "dist_tag=${NPM_DIST_TAG}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate release highlights
|
||||
id: highlights
|
||||
@@ -102,3 +98,11 @@ jobs:
|
||||
with:
|
||||
body_path: release_body.md
|
||||
generate_release_notes: true
|
||||
prerelease: ${{ contains(github.ref_name, '-') }}
|
||||
make_latest: ${{ contains(github.ref_name, '-') && 'false' || 'true' }}
|
||||
|
||||
- name: Publish npm package
|
||||
if: steps.npm_publish_state.outputs.already_published != 'true'
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npm publish --access public --provenance --tag "${{ steps.npm_publish_state.outputs.dist_tag }}"
|
||||
|
||||
23
.github/workflows/reusable-release.yml
vendored
23
.github/workflows/reusable-release.yml
vendored
@@ -18,7 +18,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Version tag to release or republish (e.g., v1.10.0)'
|
||||
description: 'Version tag to release or republish (e.g., v2.0.0-rc.1)'
|
||||
required: true
|
||||
type: string
|
||||
generate-notes:
|
||||
@@ -41,6 +41,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ inputs.tag }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
@@ -58,8 +59,8 @@ jobs:
|
||||
env:
|
||||
INPUT_TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
if ! [[ "$INPUT_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Invalid version tag format. Expected vX.Y.Z"
|
||||
if ! [[ "$INPUT_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
|
||||
echo "Invalid version tag format. Expected vX.Y.Z or vX.Y.Z-prerelease"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -83,17 +84,13 @@ jobs:
|
||||
run: |
|
||||
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
||||
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
||||
NPM_DIST_TAG=$(node -p "require('./package.json').version.includes('-') ? 'next' : 'latest'")
|
||||
if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version >/dev/null 2>&1; then
|
||||
echo "already_published=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "already_published=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Publish npm package
|
||||
if: steps.npm_publish_state.outputs.already_published != 'true'
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npm publish --access public --provenance
|
||||
echo "dist_tag=${NPM_DIST_TAG}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate release highlights
|
||||
env:
|
||||
@@ -119,3 +116,11 @@ jobs:
|
||||
tag_name: ${{ inputs.tag }}
|
||||
body_path: release_body.md
|
||||
generate_release_notes: ${{ inputs.generate-notes }}
|
||||
prerelease: ${{ contains(inputs.tag, '-') }}
|
||||
make_latest: ${{ contains(inputs.tag, '-') && 'false' || 'true' }}
|
||||
|
||||
- name: Publish npm package
|
||||
if: steps.npm_publish_state.outputs.already_published != 'true'
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npm publish --access public --provenance --tag "${{ steps.npm_publish_state.outputs.dist_tag }}"
|
||||
|
||||
8
.github/workflows/reusable-test.yml
vendored
8
.github/workflows/reusable-test.yml
vendored
@@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
- name: Cache npm
|
||||
if: inputs.package-manager == 'npm'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ inputs.node-version }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
|
||||
- name: Cache pnpm
|
||||
if: inputs.package-manager == 'pnpm'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ inputs.node-version }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
|
||||
- name: Cache yarn
|
||||
if: inputs.package-manager == 'yarn'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ inputs.node-version }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -114,7 +114,7 @@ jobs:
|
||||
|
||||
- name: Cache bun
|
||||
if: inputs.package-manager == 'bun'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||
|
||||
2
.opencode/.npmignore
Normal file
2
.opencode/.npmignore
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
bun.lock
|
||||
4
.opencode/package-lock.json
generated
4
.opencode/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ecc-universal",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ecc-universal",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.1",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@opencode-ai/plugin": "^1.4.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ecc-universal",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.1",
|
||||
"description": "Everything Claude Code (ECC) plugin for OpenCode - agents, commands, hooks, and skills",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
@@ -456,7 +456,7 @@ export const ECCHooksPlugin: ECCHooksPluginFn = async ({
|
||||
const contextBlock = [
|
||||
"# ECC Context (preserve across compaction)",
|
||||
"",
|
||||
"## Active Plugin: Everything Claude Code v1.10.0",
|
||||
"## Active Plugin: Everything Claude Code v2.0.0-rc.1",
|
||||
"- Hooks: file.edited, tool.execute.before/after, session.created/idle/deleted, shell.env, compacting, permission.ask",
|
||||
"- Tools: run-tests, check-coverage, security-audit, format-code, lint-check, git-summary, changed-files",
|
||||
"- Agents: 13 specialized (planner, architect, tdd-guide, code-reviewer, security-reviewer, build-error-resolver, e2e-runner, refactor-cleaner, doc-updater, go-reviewer, go-build-resolver, database-reviewer, python-reviewer)",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Everything Claude Code (ECC) — Agent Instructions
|
||||
|
||||
This is a **production-ready AI coding plugin** providing 48 specialized agents, 183 skills, 79 commands, and automated hook workflows for software development.
|
||||
This is a **production-ready AI coding plugin** providing 48 specialized agents, 184 skills, 79 commands, and automated hook workflows for software development.
|
||||
|
||||
**Version:** 1.10.0
|
||||
**Version:** 2.0.0-rc.1
|
||||
|
||||
## Core Principles
|
||||
|
||||
@@ -146,7 +146,7 @@ Troubleshoot failures: check test isolation → verify mocks → fix implementat
|
||||
|
||||
```
|
||||
agents/ — 48 specialized subagents
|
||||
skills/ — 183 workflow skills and domain knowledge
|
||||
skills/ — 184 workflow skills and domain knowledge
|
||||
commands/ — 79 slash commands
|
||||
hooks/ — Trigger-based automations
|
||||
rules/ — Always-follow guidelines (common + per-language)
|
||||
|
||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,5 +1,25 @@
|
||||
# Changelog
|
||||
|
||||
## 2.0.0-rc.1 - 2026-04-28
|
||||
|
||||
### Highlights
|
||||
|
||||
- Adds the public ECC 2.0 release-candidate surface for the Hermes operator story.
|
||||
- Documents ECC as the reusable cross-harness substrate across Claude Code, Codex, Cursor, OpenCode, and Gemini.
|
||||
- Adds a sanitized Hermes import skill surface instead of publishing private operator state.
|
||||
|
||||
### Release Surface
|
||||
|
||||
- Updated package, plugin, marketplace, OpenCode, agent, and README metadata to `2.0.0-rc.1`.
|
||||
- Added `docs/releases/2.0.0-rc.1/` with release notes, social drafts, launch checklist, handoff notes, and demo prompts.
|
||||
- Added `docs/architecture/cross-harness.md` and regression coverage for the ECC/Hermes boundary.
|
||||
- Kept `ecc2/` versioning independent for now; it remains an alpha control-plane scaffold unless release engineering decides otherwise.
|
||||
|
||||
### Notes
|
||||
|
||||
- This is a release candidate, not a GA claim for the full ECC 2.0 control-plane roadmap.
|
||||
- Prerelease npm publishing should use the `next` dist-tag unless release engineering explicitly chooses otherwise.
|
||||
|
||||
## 1.10.0 - 2026-04-05
|
||||
|
||||
### Highlights
|
||||
|
||||
123
README.md
123
README.md
@@ -2,6 +2,8 @@
|
||||
|
||||
# Everything Claude Code
|
||||
|
||||

|
||||
|
||||
[](https://github.com/affaan-m/everything-claude-code/stargazers)
|
||||
[](https://github.com/affaan-m/everything-claude-code/network/members)
|
||||
[](https://github.com/affaan-m/everything-claude-code/graphs/contributors)
|
||||
@@ -38,6 +40,8 @@ Not just configs. A complete system: skills, instincts, memory optimization, con
|
||||
|
||||
Works across **Claude Code**, **Codex**, **Cursor**, **OpenCode**, **Gemini**, and other AI agent harnesses.
|
||||
|
||||
ECC v2.0.0-rc.1 adds the public Hermes operator story on top of that reusable layer: start with the [Hermes setup guide](docs/HERMES-SETUP.md), then review the [rc.1 release notes](docs/releases/2.0.0-rc.1/release-notes.md) and [cross-harness architecture](docs/architecture/cross-harness.md).
|
||||
|
||||
---
|
||||
|
||||
## The Guides
|
||||
@@ -82,7 +86,7 @@ This repo is the raw code only. The guides explain everything.
|
||||
|
||||
## What's New
|
||||
|
||||
### v1.10.0 — Surface Refresh, Operator Workflows, and ECC 2.0 Alpha (Apr 2026)
|
||||
### v2.0.0-rc.1 — Surface Refresh, Operator Workflows, and ECC 2.0 Alpha (Apr 2026)
|
||||
|
||||
- **Dashboard GUI** — New Tkinter-based desktop application (`ecc_dashboard.py` or `npm run dashboard`) with dark/light theme toggle, font customization, and project logo in header and taskbar.
|
||||
- **Public surface synced to the live repo** — metadata, catalog counts, plugin manifests, and install-facing docs now match the actual OSS surface: 38 agents, 156 skills, and 72 legacy command shims.
|
||||
@@ -165,7 +169,17 @@ See the full changelog in [Releases](https://github.com/affaan-m/everything-clau
|
||||
|
||||
Get up and running in under 2 minutes:
|
||||
|
||||
### Step 1: Install the Plugin
|
||||
### Pick one path only
|
||||
|
||||
Most Claude Code users should use exactly one install path:
|
||||
|
||||
- **Recommended default:** install the Claude Code plugin, then copy only the rule folders you actually want.
|
||||
- **Use the manual installer only if** you want finer-grained control, want to avoid the plugin path entirely, or your Claude Code build has trouble resolving the self-hosted marketplace entry.
|
||||
- **Do not stack install methods.** The most common broken setup is: `/plugin install` first, then `install.sh --profile full` or `npx ecc-install --profile full` afterward.
|
||||
|
||||
If you already layered multiple installs and things look duplicated, skip straight to [Reset / Uninstall ECC](#reset--uninstall-ecc).
|
||||
|
||||
### Step 1: Install the Plugin (Recommended)
|
||||
|
||||
> NOTE: The plugin is convenient, but the OSS installer below is still the most reliable path if your Claude Code build has trouble resolving self-hosted marketplace entries.
|
||||
|
||||
@@ -189,11 +203,15 @@ This is intentional. Anthropic marketplace/plugin installs are keyed by a canoni
|
||||
|
||||
### Step 2: Install Rules (Required)
|
||||
|
||||
> WARNING: **Important:** Claude Code plugins cannot distribute `rules` automatically. Install them manually:
|
||||
> WARNING: **Important:** Claude Code plugins cannot distribute `rules` automatically.
|
||||
>
|
||||
> If your local Claude setup was wiped or reset, that does not mean you need to repurchase ECC. Start with `ecc list-installed`, then run `ecc doctor` and `ecc repair` before reinstalling anything. That usually restores ECC-managed files without rebuilding your setup. If the problem is account or marketplace access for ECC Tools, handle billing/account recovery separately.
|
||||
|
||||
> If your local Claude setup was wiped or reset, that does not mean you need to repurchase ECC. Start with `ecc list-installed`, then run `ecc doctor` and `ecc repair` before reinstalling anything. That usually restores ECC-managed files without rebuilding your setup. If the problem is account or marketplace access for ECC Tools, handle billing/account recovery separately.
|
||||
> If you already installed ECC via `/plugin install`, **do not run `./install.sh --profile full`, `.\install.ps1 --profile full`, or `npx ecc-install --profile full` afterward**. The plugin already loads ECC skills, commands, and hooks. Running the full installer after a plugin install copies those same surfaces into your user directories and can create duplicate skills plus duplicate runtime behavior.
|
||||
>
|
||||
> For plugin installs, manually copy only the `rules/` directories you want. Start with `rules/common` plus one language or framework pack you actually use. Do not copy every rules directory unless you explicitly want all of that context in Claude.
|
||||
>
|
||||
> Use the full installer only when you are doing a fully manual ECC install instead of the plugin path.
|
||||
>
|
||||
> If your local Claude setup was wiped or reset, that does not mean you need to repurchase ECC. Start with `node scripts/ecc.js list-installed`, then run `node scripts/ecc.js doctor` and `node scripts/ecc.js repair` before reinstalling anything. That usually restores ECC-managed files without rebuilding your setup. If the problem is account or marketplace access for ECC Tools, handle billing/account recovery separately.
|
||||
|
||||
```bash
|
||||
# Clone the repo first
|
||||
@@ -203,38 +221,81 @@ cd everything-claude-code
|
||||
# Install dependencies (pick your package manager)
|
||||
npm install # or: pnpm install | yarn install | bun install
|
||||
|
||||
# macOS/Linux
|
||||
# Plugin install path: copy only rules
|
||||
mkdir -p ~/.claude/rules
|
||||
cp -R rules/common ~/.claude/rules/
|
||||
cp -R rules/typescript ~/.claude/rules/
|
||||
|
||||
# Recommended: install everything (full profile)
|
||||
./install.sh --profile full
|
||||
|
||||
# Or install for specific languages only
|
||||
./install.sh typescript # or python or golang or swift or php
|
||||
# ./install.sh typescript python golang swift php
|
||||
# ./install.sh --target cursor typescript
|
||||
# ./install.sh --target antigravity typescript
|
||||
# ./install.sh --target gemini --profile full
|
||||
# Fully manual ECC install path (use this instead of /plugin install)
|
||||
# ./install.sh --profile full
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Windows PowerShell
|
||||
|
||||
# Recommended: install everything (full profile)
|
||||
.\install.ps1 --profile full
|
||||
# Plugin install path: copy only rules
|
||||
New-Item -ItemType Directory -Force -Path "$HOME/.claude/rules" | Out-Null
|
||||
Copy-Item -Recurse rules/common "$HOME/.claude/rules/"
|
||||
Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/"
|
||||
|
||||
# Or install for specific languages only
|
||||
.\install.ps1 typescript # or python or golang or swift or php
|
||||
# .\install.ps1 typescript python golang swift php
|
||||
# .\install.ps1 --target cursor typescript
|
||||
# .\install.ps1 --target antigravity typescript
|
||||
# .\install.ps1 --target gemini --profile full
|
||||
|
||||
# npm-installed compatibility entrypoint also works cross-platform
|
||||
npx ecc-install typescript
|
||||
# Fully manual ECC install path (use this instead of /plugin install)
|
||||
# .\install.ps1 --profile full
|
||||
# npx ecc-install --profile full
|
||||
```
|
||||
|
||||
For manual install instructions see the README in the `rules/` folder. When copying rules manually, copy the whole language directory (for example `rules/common` or `rules/golang`), not the files inside it, so relative references keep working and filenames do not collide.
|
||||
|
||||
### Fully manual install (Fallback)
|
||||
|
||||
Use this only if you are intentionally skipping the plugin path:
|
||||
|
||||
```bash
|
||||
./install.sh --profile full
|
||||
```
|
||||
|
||||
```powershell
|
||||
.\install.ps1 --profile full
|
||||
# or
|
||||
npx ecc-install --profile full
|
||||
```
|
||||
|
||||
If you choose this path, stop there. Do not also run `/plugin install`.
|
||||
|
||||
### Reset / Uninstall ECC
|
||||
|
||||
If ECC feels duplicated, intrusive, or broken, do not keep reinstalling it on top of itself.
|
||||
|
||||
- **Plugin path:** remove the plugin from Claude Code, then delete the specific rule folders you manually copied under `~/.claude/rules/`.
|
||||
- **Manual installer / CLI path:** from the repo root, preview removal first:
|
||||
|
||||
```bash
|
||||
node scripts/uninstall.js --dry-run
|
||||
```
|
||||
|
||||
Then remove ECC-managed files:
|
||||
|
||||
```bash
|
||||
node scripts/uninstall.js
|
||||
```
|
||||
|
||||
You can also use the lifecycle wrapper:
|
||||
|
||||
```bash
|
||||
node scripts/ecc.js list-installed
|
||||
node scripts/ecc.js doctor
|
||||
node scripts/ecc.js repair
|
||||
node scripts/ecc.js uninstall --dry-run
|
||||
```
|
||||
|
||||
ECC only removes files recorded in its install-state. It will not delete unrelated files it did not install.
|
||||
|
||||
If you stacked methods, clean up in this order:
|
||||
|
||||
1. Remove the Claude Code plugin install.
|
||||
2. Run the ECC uninstall command from the repo root to remove install-state-managed files.
|
||||
3. Delete any extra rule folders you copied manually and no longer want.
|
||||
4. Reinstall once, using a single path.
|
||||
|
||||
### Step 3: Start Using
|
||||
|
||||
```bash
|
||||
@@ -251,7 +312,7 @@ For manual install instructions see the README in the `rules/` folder. When copy
|
||||
/plugin list everything-claude-code@everything-claude-code
|
||||
```
|
||||
|
||||
**That's it!** You now have access to 48 agents, 183 skills, and 79 legacy command shims.
|
||||
**That's it!** You now have access to 48 agents, 184 skills, and 79 legacy command shims.
|
||||
|
||||
### Dashboard GUI
|
||||
|
||||
@@ -1219,7 +1280,7 @@ The configuration is automatically detected from `.opencode/opencode.json`.
|
||||
|---------|-------------|----------|--------|
|
||||
| Agents | PASS: 48 agents | PASS: 12 agents | **Claude Code leads** |
|
||||
| Commands | PASS: 79 commands | PASS: 31 commands | **Claude Code leads** |
|
||||
| Skills | PASS: 183 skills | PASS: 37 skills | **Claude Code leads** |
|
||||
| Skills | PASS: 184 skills | PASS: 37 skills | **Claude Code leads** |
|
||||
| Hooks | PASS: 8 event types | PASS: 11 events | **OpenCode has more!** |
|
||||
| Rules | PASS: 29 rules | PASS: 13 instructions | **Claude Code leads** |
|
||||
| MCP Servers | PASS: 14 servers | PASS: Full | **Full parity** |
|
||||
@@ -1328,7 +1389,7 @@ ECC is the **first plugin to maximize every major AI coding tool**. Here's how e
|
||||
|---------|------------|------------|-----------|----------|
|
||||
| **Agents** | 48 | Shared (AGENTS.md) | Shared (AGENTS.md) | 12 |
|
||||
| **Commands** | 79 | Shared | Instruction-based | 31 |
|
||||
| **Skills** | 183 | Shared | 10 (native format) | 37 |
|
||||
| **Skills** | 184 | Shared | 10 (native format) | 37 |
|
||||
| **Hook Events** | 8 types | 15 types | None yet | 11 types |
|
||||
| **Hook Scripts** | 20+ scripts | 16 scripts (DRY adapter) | N/A | Plugin hooks |
|
||||
| **Rules** | 34 (common + lang) | 34 (YAML frontmatter) | Instruction-based | 13 instructions |
|
||||
@@ -1338,7 +1399,7 @@ ECC is the **first plugin to maximize every major AI coding tool**. Here's how e
|
||||
| **Context File** | CLAUDE.md + AGENTS.md | AGENTS.md | AGENTS.md | AGENTS.md |
|
||||
| **Secret Detection** | Hook-based | beforeSubmitPrompt hook | Sandbox-based | Hook-based |
|
||||
| **Auto-Format** | PostToolUse hook | afterFileEdit hook | N/A | file.edited hook |
|
||||
| **Version** | Plugin | Plugin | Reference config | 1.10.0 |
|
||||
| **Version** | Plugin | Plugin | Reference config | 2.0.0-rc.1 |
|
||||
|
||||
**Key architectural decisions:**
|
||||
- **AGENTS.md** at root is the universal cross-tool file (read by all 4 tools)
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
## 最新动态
|
||||
|
||||
### v1.10.0 — 表面同步、运营工作流与 ECC 2.0 Alpha(2026年4月)
|
||||
### v2.0.0-rc.1 — 表面同步、运营工作流与 ECC 2.0 Alpha(2026年4月)
|
||||
|
||||
- **公共表面已与真实仓库同步** —— 元数据、目录数量、插件清单以及安装文档现在都与实际开源表面保持一致。
|
||||
- **运营与外向型工作流扩展** —— `brand-voice`、`social-graph-ranker`、`customer-billing-ops`、`google-workspace-ops` 等运营型 skill 已纳入同一系统。
|
||||
@@ -109,7 +109,11 @@
|
||||
|
||||
### 第二步:安装规则(必需)
|
||||
|
||||
> WARNING: **重要提示:** Claude Code 插件无法自动分发 `rules`,需要手动安装:
|
||||
> WARNING: **重要提示:** Claude Code 插件无法自动分发 `rules`。
|
||||
>
|
||||
> 如果你已经通过 `/plugin install` 安装了 ECC,**不要再运行 `./install.sh --profile full`、`.\install.ps1 --profile full` 或 `npx ecc-install --profile full`**。插件已经会自动加载 ECC 的技能、命令和 hooks;此时再执行完整安装,会把同一批内容再次复制到用户目录,导致技能重复以及运行时行为重复。
|
||||
>
|
||||
> 对于插件安装路径,请只手动复制你需要的 `rules/` 目录。只有在你完全不走插件安装、而是选择“纯手动安装 ECC”时,才应该使用完整安装器。
|
||||
|
||||
```bash
|
||||
# 首先克隆仓库
|
||||
@@ -119,34 +123,26 @@ cd everything-claude-code
|
||||
# 安装依赖(选择你常用的包管理器)
|
||||
npm install # 或:pnpm install | yarn install | bun install
|
||||
|
||||
# macOS/Linux 系统
|
||||
# 插件安装路径:只复制规则
|
||||
mkdir -p ~/.claude/rules
|
||||
cp -R rules/common ~/.claude/rules/
|
||||
cp -R rules/typescript ~/.claude/rules/
|
||||
|
||||
# 推荐方式:完整安装(完整配置文件)
|
||||
./install.sh --profile full
|
||||
|
||||
# 或仅为指定编程语言安装
|
||||
./install.sh typescript # 也可安装 python、golang、swift、php
|
||||
# ./install.sh typescript python golang swift php
|
||||
# ./install.sh --target cursor typescript
|
||||
# ./install.sh --target antigravity typescript
|
||||
# ./install.sh --target gemini --profile full
|
||||
# 纯手动安装 ECC(不要和 /plugin install 叠加)
|
||||
# ./install.sh --profile full
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Windows 系统(PowerShell)
|
||||
|
||||
# 推荐方式:完整安装(完整配置文件)
|
||||
.\install.ps1 --profile full
|
||||
# 插件安装路径:只复制规则
|
||||
New-Item -ItemType Directory -Force -Path "$HOME/.claude/rules" | Out-Null
|
||||
Copy-Item -Recurse rules/common "$HOME/.claude/rules/"
|
||||
Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/"
|
||||
|
||||
# 或仅为指定编程语言安装
|
||||
.\install.ps1 typescript # 也可安装 python、golang、swift、php
|
||||
# .\install.ps1 typescript python golang swift php
|
||||
# .\install.ps1 --target cursor typescript
|
||||
# .\install.ps1 --target antigravity typescript
|
||||
# .\install.ps1 --target gemini --profile full
|
||||
|
||||
# 通过 npm 安装的兼容入口,支持全平台使用
|
||||
npx ecc-install typescript
|
||||
# 纯手动安装 ECC(不要和 /plugin install 叠加)
|
||||
# .\install.ps1 --profile full
|
||||
# npx ecc-install --profile full
|
||||
```
|
||||
|
||||
如需手动安装说明,请查看 `rules/` 文件夹中的 README 文档。手动复制规则文件时,请直接复制**整个语言目录**(例如 `rules/common` 或 `rules/golang`),而非目录内的单个文件,以保证相对路径引用正常、文件名不会冲突。
|
||||
@@ -164,7 +160,7 @@ npx ecc-install typescript
|
||||
/plugin list everything-claude-code@everything-claude-code
|
||||
```
|
||||
|
||||
**完成!** 你现在可以使用 48 个代理、183 个技能和 79 个命令。
|
||||
**完成!** 你现在可以使用 48 个代理、184 个技能和 79 个命令。
|
||||
|
||||
### multi-* 命令需要额外配置
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
spec_version: "0.1.0"
|
||||
name: everything-claude-code
|
||||
version: 1.10.0
|
||||
version: 2.0.0-rc.1
|
||||
description: "Initial gitagent export surface for ECC's shared skill catalog, governance, and identity. Native agents, commands, and hooks remain authoritative in the repository while manifest coverage expands."
|
||||
author: affaan-m
|
||||
license: MIT
|
||||
|
||||
BIN
assets/hero.png
Normal file
BIN
assets/hero.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
@@ -100,9 +100,9 @@ This stack is useful when you want:
|
||||
- automation that can nudge, audit, and escalate
|
||||
- a public repo that shows the system shape without exposing your private operator state
|
||||
|
||||
## Public Preview Scope
|
||||
## Public Release Candidate Scope
|
||||
|
||||
ECC 2.0 preview documents the Hermes surface and ships launch collateral now.
|
||||
ECC v2.0.0-rc.1 documents the Hermes surface and ships launch collateral now.
|
||||
|
||||
The remaining private pieces can be layered later:
|
||||
|
||||
|
||||
@@ -703,7 +703,7 @@ Suggested payload:
|
||||
"skippedModules": []
|
||||
},
|
||||
"source": {
|
||||
"repoVersion": "1.10.0",
|
||||
"repoVersion": "2.0.0-rc.1",
|
||||
"repoCommit": "git-sha",
|
||||
"manifestVersion": 1
|
||||
},
|
||||
|
||||
111
docs/architecture/cross-harness.md
Normal file
111
docs/architecture/cross-harness.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Cross-Harness Architecture
|
||||
|
||||
ECC is the reusable workflow layer. Harnesses are execution surfaces.
|
||||
|
||||
The goal is to keep the durable parts of agentic work in one repo:
|
||||
|
||||
- skills
|
||||
- rules and instructions
|
||||
- hooks where the harness supports them
|
||||
- MCP configuration
|
||||
- install manifests
|
||||
- session and orchestration patterns
|
||||
|
||||
Claude Code, Codex, OpenCode, Cursor, Gemini, and future harnesses should adapt those assets at the edge instead of requiring a new workflow model for every tool.
|
||||
|
||||
## Portability Model
|
||||
|
||||
| Surface | Shared Source | Harness Adapter | Current Status |
|
||||
|---------|---------------|-----------------|----------------|
|
||||
| Skills | `skills/*/SKILL.md` | Claude plugin, Codex plugin, `.agents/skills`, Cursor skill copies, OpenCode plugin/config | Supported with harness-specific packaging |
|
||||
| Rules and instructions | `rules/`, `AGENTS.md`, translated docs | Claude rules install, Codex `AGENTS.md`, Cursor rules, OpenCode instructions | Supported, but not identical across harnesses |
|
||||
| Hooks | `hooks/hooks.json`, `scripts/hooks/` | Claude native hooks, OpenCode plugin events, Cursor hook adapter | Hook-backed in Claude/OpenCode/Cursor; instruction-backed in Codex |
|
||||
| MCPs | `.mcp.json`, `mcp-configs/` | Native MCP config import per harness | Supported where the harness exposes MCP |
|
||||
| Commands | `commands/`, CLI scripts | Claude slash commands, compatibility shims, CLI entrypoints | Supported, but command semantics vary |
|
||||
| Sessions | `ecc2/`, session adapters, orchestration scripts | TUI/daemon, tmux/worktree orchestration, harness-specific runners | Alpha |
|
||||
|
||||
## What Travels Unchanged
|
||||
|
||||
`SKILL.md` is the most portable unit.
|
||||
|
||||
A good ECC skill should:
|
||||
|
||||
- use YAML frontmatter with `name`, `description`, and `origin`
|
||||
- describe when to use the skill
|
||||
- state required tools or connectors without embedding secrets
|
||||
- keep examples repo-relative or generic
|
||||
- avoid harness-only command assumptions unless the section is clearly labeled
|
||||
|
||||
The same source skill can be installed into multiple harnesses because it is mostly instructions, constraints, and workflow shape.
|
||||
|
||||
## What Gets Adapted
|
||||
|
||||
Each harness has different loading and enforcement behavior:
|
||||
|
||||
- Claude Code loads plugin assets and has native hook execution.
|
||||
- Codex reads `AGENTS.md`, plugin metadata, skills, and MCP config, but hook parity is instruction-driven.
|
||||
- OpenCode has a plugin/event system that can reuse ECC hook logic through an adapter layer.
|
||||
- Cursor uses its own rule and hook layout, so ECC maintains translated surfaces under `.cursor/`.
|
||||
- Gemini support is install/instruction oriented and should be treated as a compatibility surface, not as full hook parity.
|
||||
|
||||
Adapters should stay thin. The shared behavior belongs in `skills/`, `rules/`, `hooks/`, `scripts/`, and `mcp-configs/`.
|
||||
|
||||
## Hermes Boundary
|
||||
|
||||
Hermes is not the public ECC runtime.
|
||||
|
||||
Hermes is an operator shell that can consume ECC assets:
|
||||
|
||||
- import selected ECC skills into a Hermes skills directory
|
||||
- use ECC MCP conventions for tool access
|
||||
- route chat, CLI, cron, and handoff workflows through reusable ECC patterns
|
||||
- distill repeated local operator work back into sanitized ECC skills
|
||||
|
||||
The public repo should ship reusable patterns, not local Hermes state.
|
||||
|
||||
Do ship:
|
||||
|
||||
- sanitized setup docs
|
||||
- repo-relative demo prompts
|
||||
- general operator skills
|
||||
- examples that do not depend on private credentials
|
||||
|
||||
Do not ship:
|
||||
|
||||
- OAuth tokens or API keys
|
||||
- raw `~/.hermes` exports
|
||||
- personal workspace memory
|
||||
- private datasets
|
||||
- local-only automation packs that have not been reviewed
|
||||
|
||||
## Today vs Later
|
||||
|
||||
Supported today:
|
||||
|
||||
- shared skill source in `skills/`
|
||||
- Claude Code plugin packaging
|
||||
- Codex plugin metadata and MCP reference config
|
||||
- OpenCode package/plugin surface
|
||||
- Cursor-adapted rules, hooks, and skills
|
||||
- `ecc2/` as an alpha Rust control plane
|
||||
|
||||
Still maturing:
|
||||
|
||||
- exact hook parity across all harnesses
|
||||
- automated skill sync into Hermes
|
||||
- release packaging for `ecc2/`
|
||||
- cross-harness session resume semantics
|
||||
- deeper memory and operator planning layers
|
||||
|
||||
## Rule For New Work
|
||||
|
||||
When adding a workflow, put the durable behavior in ECC first.
|
||||
|
||||
Use harness-specific files only for:
|
||||
|
||||
- loading the shared asset
|
||||
- adapting event shapes
|
||||
- mapping command names
|
||||
- handling platform limits
|
||||
|
||||
If a workflow only works in one harness, document that boundary directly.
|
||||
109
docs/fixes/HOOK-FIX-20260421-ADDENDUM.md
Normal file
109
docs/fixes/HOOK-FIX-20260421-ADDENDUM.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# HOOK-FIX-20260421 Addendum — v2.1.116 argv 重複バグ
|
||||
|
||||
朝セッションで commit 527c18b として修正済み。夜セッションで追加検証と、
|
||||
朝fix でカバーしきれない Claude Code 固有のバグを特定したので補遺を記録する。
|
||||
|
||||
## 朝fixの形式
|
||||
|
||||
```json
|
||||
"command": "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh pre"
|
||||
```
|
||||
|
||||
`.sh` ファイルを直接 command にする形式。Git Bash が shebang 経由で実行する前提。
|
||||
|
||||
## 夜 追加検証で判明したこと
|
||||
|
||||
Node.js の `child_process.spawn` で `.sh` ファイルを直接実行すると Windows では
|
||||
**EFTYPE** で失敗する:
|
||||
|
||||
```js
|
||||
spawn('C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh',
|
||||
['post'], {stdio:['pipe','pipe','pipe']});
|
||||
// → Error: spawn EFTYPE (errno -4028)
|
||||
```
|
||||
|
||||
`shell:true` を付ければ cmd.exe 経由で実行できるが、Claude Code 側の実装
|
||||
依存のリスクが残る。
|
||||
|
||||
## 夜 適用した追加 fix
|
||||
|
||||
第1トークンを `bash`(PATH 解決)に変えた明示的な呼び出しに更新:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [{
|
||||
"matcher": "*",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "bash \"C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh\" pre"
|
||||
}]
|
||||
}],
|
||||
"PostToolUse": [{
|
||||
"matcher": "*",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "bash \"C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh\" post"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
この形式は `~/.claude/hooks/hooks.json` 内の ECC 正規 observer 登録と
|
||||
同じパターンで、現実にエラーなく動作している実績あり。
|
||||
|
||||
### Node spawn 検証
|
||||
|
||||
```js
|
||||
spawn('bash "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" post',
|
||||
[], {shell:true});
|
||||
// exit=0 → observations.jsonl に正常追記
|
||||
```
|
||||
|
||||
## Claude Code v2.1.116 の argv 重複バグ(詳細)
|
||||
|
||||
朝fix docの「Defect 2」として `bash.exe: bash.exe: cannot execute binary file` を
|
||||
記録しているが、その根本メカニズムが特定できたので記す。
|
||||
|
||||
### 再現
|
||||
|
||||
```bash
|
||||
"C:\Program Files\Git\bin\bash.exe" "C:\Program Files\Git\bin\bash.exe"
|
||||
# stderr: "C:\Program Files\Git\bin\bash.exe: C:\Program Files\Git\bin\bash.exe: cannot execute binary file"
|
||||
# exit: 126
|
||||
```
|
||||
|
||||
bash は argv[1] を script とみなし読み込もうとする。argv[1] が bash.exe 自身なら
|
||||
ELF/PE バイナリ検出で失敗 → exit 126。エラー文言は完全一致。
|
||||
|
||||
### Claude Code 側の挙動
|
||||
|
||||
hook command が `"C:\Program Files\Git\bin\bash.exe" "C:\Users\...\wrapper.sh"`
|
||||
のとき、v2.1.116 は**第1トークン(= bash.exe フルパス)を argv[0] と argv[1] の
|
||||
両方に渡す**と推定される。結果 bash は argv[1] = bash.exe を script として
|
||||
読み込もうとして 126 で落ちる。
|
||||
|
||||
### 回避策
|
||||
|
||||
第1トークンを bash.exe のフルパス+スペース付きパスにしないこと:
|
||||
1. `OK:` `bash` (PATH 解決の単一トークン)— 夜fix / hooks.json パターン
|
||||
2. `OK:` `.sh` 直接パス(Claude Code の .sh ハンドリングに依存)— 朝fix
|
||||
3. `BAD:` `"C:\Program Files\Git\bin\bash.exe" "<path>"` — 1トークン目が quoted で空白込み
|
||||
|
||||
## 結論
|
||||
|
||||
朝fix(直接 .sh 指定)と夜fix(明示的 bash prefix)のどちらも argv 重複バグを
|
||||
踏まないが、**夜fixの方が Claude Code の実装依存が少ない**ため推奨。
|
||||
|
||||
ただし朝fix commit 527c18b は既に docs/fixes/ に入っているため、この Addendum を
|
||||
追記することで両論併記とする。次回 CLI 再起動時に夜fix の方が実運用に残る。
|
||||
|
||||
## 関連
|
||||
|
||||
- 朝 fix commit: 527c18b
|
||||
- 朝 fix doc: docs/fixes/HOOK-FIX-20260421.md
|
||||
- 朝 apply script: docs/fixes/apply-hook-fix.sh
|
||||
- 夜 fix 記録(ローカル): C:\Users\sugig\Documents\Claude\Projects\ECC作成\hook-fix-report-20260421.md
|
||||
- 夜 fix 適用ファイル: C:\Users\sugig\.claude\settings.local.json
|
||||
- 夜 backup: C:\Users\sugig\.claude\settings.local.json.bak-hook-fix-20260421
|
||||
144
docs/fixes/HOOK-FIX-20260421.md
Normal file
144
docs/fixes/HOOK-FIX-20260421.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# ECC Hook Fix — 2026-04-21
|
||||
|
||||
## Summary
|
||||
|
||||
Claude Code CLI v2.1.116 on Windows was failing all Bash tool hook invocations with:
|
||||
|
||||
```
|
||||
PreToolUse:Bash hook error
|
||||
Failed with non-blocking status code:
|
||||
C:\Program Files\Git\bin\bash.exe: C:\Program Files\Git\bin\bash.exe:
|
||||
cannot execute binary file
|
||||
|
||||
PostToolUse:Bash hook error (同上)
|
||||
```
|
||||
|
||||
Result: `observations.jsonl` stopped updating after `2026-04-20T23:03:38Z`
|
||||
(last entry was a `parse_error` from an earlier BOM-on-stdin issue).
|
||||
|
||||
## Root Cause
|
||||
|
||||
`C:\Users\sugig\.claude\settings.local.json` had two defects:
|
||||
|
||||
### Defect 1 — UTF-8 BOM + CRLF line endings
|
||||
|
||||
The file started with `EF BB BF` (UTF-8 BOM) and used `CRLF` line terminators.
|
||||
This is the PowerShell `ConvertTo-Json | Out-File` default behavior, and it is
|
||||
what `patch_settings_cl_v2_simple.ps1` leaves behind when it rewrites the file.
|
||||
|
||||
```
|
||||
00000000: efbb bf7b 0d0a 2020 2020 2268 6f6f 6b73 ...{.. "hooks
|
||||
```
|
||||
|
||||
### Defect 2 — Double-wrapped bash.exe invocation
|
||||
|
||||
The command string explicitly re-invoked bash.exe:
|
||||
|
||||
```json
|
||||
"command": "\"C:\\Program Files\\Git\\bin\\bash.exe\" \"C:\\Users\\sugig\\.claude\\skills\\continuous-learning\\hooks\\observe-wrapper.sh\""
|
||||
```
|
||||
|
||||
When Claude Code spawns this on Windows, argument splitting does not preserve
|
||||
the quoted `"C:\Program Files\..."` token correctly. The embedded space in
|
||||
`Program Files` splits `argv[0]`, and `bash.exe` ends up being passed to
|
||||
itself as a script file, producing:
|
||||
|
||||
```
|
||||
bash.exe: bash.exe: cannot execute binary file
|
||||
```
|
||||
|
||||
### Prior working shape (for reference)
|
||||
|
||||
Before `patch_settings_cl_v2_simple.ps1` ran, the command was simply:
|
||||
|
||||
```json
|
||||
"command": "C:\\Users\\sugig\\.claude\\skills\\continuous-learning\\hooks\\observe.sh"
|
||||
```
|
||||
|
||||
Claude Code on Windows detects `.sh` and invokes it via Git Bash itself — no
|
||||
manual `bash.exe` wrapping needed.
|
||||
|
||||
## Fix
|
||||
|
||||
`C:\Users\sugig\.claude\settings.local.json` rewritten as UTF-8 (no BOM), LF
|
||||
line endings, with the command pointing directly at the wrapper `.sh` and
|
||||
passing the hook phase as a plain argument:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh pre"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh post"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Side benefit: the `pre` / `post` argument is now routed to `observe.sh`'s
|
||||
`HOOK_PHASE` variable so events are correctly logged as `tool_start` vs
|
||||
`tool_complete` (previously everything was recorded as `tool_complete`).
|
||||
|
||||
## Verification
|
||||
|
||||
Direct invocation of the new command format, emulating both hook phases:
|
||||
|
||||
```bash
|
||||
# PostToolUse path
|
||||
echo '{"tool_name":"Bash","tool_input":{"command":"pwd"},"session_id":"post-fix-verify-001","cwd":"...","hook_event_name":"PostToolUse"}' \
|
||||
| "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" post
|
||||
# exit=0
|
||||
|
||||
# PreToolUse path
|
||||
echo '{"tool_name":"Bash","tool_input":{"command":"ls"},"session_id":"post-fix-verify-pre-001","cwd":"...","hook_event_name":"PreToolUse"}' \
|
||||
| "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" pre
|
||||
# exit=0
|
||||
```
|
||||
|
||||
`observations.jsonl` gained:
|
||||
|
||||
```
|
||||
{"timestamp":"2026-04-21T05:57:54Z","event":"tool_complete","tool":"Bash","session":"post-fix-verify-001",...}
|
||||
{"timestamp":"2026-04-21T05:57:55Z","event":"tool_start","tool":"Bash","session":"post-fix-verify-pre-001","input":"{\"command\":\"ls\"}",...}
|
||||
```
|
||||
|
||||
Both phases now produce correctly typed events.
|
||||
|
||||
**Note on live CLI verification:** settings changes take effect on the next
|
||||
`claude` CLI session launch. Restart the CLI and run a Bash tool call to
|
||||
confirm new rows appear in `observations.jsonl` from the actual CLI session.
|
||||
|
||||
## Files Touched
|
||||
|
||||
- `C:\Users\sugig\.claude\settings.local.json` — rewritten
|
||||
- `C:\Users\sugig\.claude\settings.local.json.bak-hookfix-20260421-145718` — pre-fix backup
|
||||
|
||||
## Known Upstream Bugs (not fixed here)
|
||||
|
||||
- `install_hook_wrapper.ps1` — halts at step [3/4], never reaches [4/4].
|
||||
- `patch_settings_cl_v2_simple.ps1` — overwrites `settings.local.json` with
|
||||
UTF-8-BOM + CRLF and re-introduces the double-wrapped `bash.exe` command.
|
||||
Should be replaced with a patcher that emits UTF-8 (no BOM), LF, and a
|
||||
direct `.sh` path.
|
||||
|
||||
## Branch
|
||||
|
||||
`claude/hook-fix-20260421`
|
||||
66
docs/fixes/INSTALL-HOOK-WRAPPER-FIX-20260422.md
Normal file
66
docs/fixes/INSTALL-HOOK-WRAPPER-FIX-20260422.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# install_hook_wrapper.ps1 argv-dup bug workaround (2026-04-22)
|
||||
|
||||
## Summary
|
||||
|
||||
`docs/fixes/install_hook_wrapper.ps1` is the PowerShell helper that copies
|
||||
`observe-wrapper.sh` into `~/.claude/skills/continuous-learning/hooks/` and
|
||||
rewrites `~/.claude/settings.local.json` so the observer hook points at it.
|
||||
|
||||
The previous version produced a hook command of the form:
|
||||
|
||||
```
|
||||
"C:\Program Files\Git\bin\bash.exe" "C:\Users\...\observe-wrapper.sh"
|
||||
```
|
||||
|
||||
Under Claude Code v2.1.116 the first argv token is duplicated. When that token
|
||||
is a quoted Windows executable path, `bash.exe` is re-invoked with itself as
|
||||
its `$0`, which fails with `cannot execute binary file` (exit 126). PR #1524
|
||||
documents the root cause; this script is a companion that keeps the installer
|
||||
in sync with the fixed `settings.local.json` layout.
|
||||
|
||||
## What the fix does
|
||||
|
||||
- First token is now the PATH-resolved `bash` (no quoted `.exe` path), so the
|
||||
argv-dup bug no longer passes a binary as a script.
|
||||
- The wrapper path is normalized to forward slashes before it is embedded in
|
||||
the hook command, avoiding MSYS backslash handling surprises.
|
||||
- `PreToolUse` and `PostToolUse` receive distinct commands with explicit
|
||||
`pre` / `post` positional arguments, matching the shape the wrapper expects.
|
||||
- The settings file is written with LF line endings so downstream JSON parsers
|
||||
never see mixed CRLF/LF output from `ConvertTo-Json`.
|
||||
|
||||
## Resulting command shape
|
||||
|
||||
```
|
||||
bash "C:/Users/<you>/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" pre
|
||||
bash "C:/Users/<you>/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" post
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```powershell
|
||||
# Place observe-wrapper.sh next to this script, then:
|
||||
pwsh -File docs/fixes/install_hook_wrapper.ps1
|
||||
```
|
||||
|
||||
The script backs up `settings.local.json` to
|
||||
`settings.local.json.bak-<timestamp>` before writing.
|
||||
|
||||
## PowerShell 5.1 compatibility
|
||||
|
||||
`ConvertFrom-Json -AsHashtable` is PowerShell 7+ only. The script tries
|
||||
`-AsHashtable` first and falls back to a manual `PSCustomObject` →
|
||||
`Hashtable` conversion on Windows PowerShell 5.1. Both hook buckets
|
||||
(`PreToolUse`, `PostToolUse`) and their inner `hooks` arrays are
|
||||
materialized as `System.Collections.ArrayList` before serialization, so
|
||||
PS 5.1's `ConvertTo-Json` cannot collapse single-element arrays into
|
||||
bare objects. Verified by running `powershell -NoProfile -File
|
||||
docs/fixes/install_hook_wrapper.ps1` on a Windows 11 machine with only
|
||||
Windows PowerShell 5.1 installed (no `pwsh`).
|
||||
|
||||
## Related
|
||||
|
||||
- PR #1524 — settings.local.json shape fix (same argv-dup root cause)
|
||||
- PR #1511 — skip `AppInstallerPythonRedirector.exe` in observer python resolution
|
||||
- PR #1539 — locale-independent `detect-project.sh`
|
||||
- PR #1542 — `patch_settings_cl_v2_simple.ps1` companion fix
|
||||
78
docs/fixes/PATCH-SETTINGS-SIMPLE-FIX-20260422.md
Normal file
78
docs/fixes/PATCH-SETTINGS-SIMPLE-FIX-20260422.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# patch_settings_cl_v2_simple.ps1 argv-dup bug workaround (2026-04-22)
|
||||
|
||||
## Summary
|
||||
|
||||
`docs/fixes/patch_settings_cl_v2_simple.ps1` is the minimal PowerShell
|
||||
helper that patches `~/.claude/settings.local.json` so the observer hook
|
||||
points at `observe-wrapper.sh`. It is the "simple" counterpart of
|
||||
`docs/fixes/install_hook_wrapper.ps1` (PR #1540): it never copies the
|
||||
wrapper script, it only rewrites the settings file.
|
||||
|
||||
The previous version of this helper registered the raw `observe.sh` path
|
||||
as the hook command, shared a single command string across `PreToolUse`
|
||||
and `PostToolUse`, and relied on `ConvertTo-Json` defaults that can emit
|
||||
CRLF line endings. Under Claude Code v2.1.116 the first argv token is
|
||||
duplicated, so the wrapper needs to be invoked with a specific shape and
|
||||
the two hook phases need distinct entries.
|
||||
|
||||
## What the fix does
|
||||
|
||||
- First token is the PATH-resolved `bash` (no quoted `.exe` path), so the
|
||||
argv-dup bug no longer passes a binary as a script. Matches PR #1524 and
|
||||
PR #1540.
|
||||
- The wrapper path is normalized to forward slashes before it is embedded
|
||||
in the hook command, avoiding MSYS backslash handling surprises.
|
||||
- `PreToolUse` and `PostToolUse` receive distinct commands with explicit
|
||||
`pre` / `post` positional arguments.
|
||||
- The settings file is written UTF-8 (no BOM) with CRLF normalized to LF
|
||||
so downstream JSON parsers never see mixed line endings.
|
||||
- Existing hooks (including legacy `observe.sh` entries and unrelated
|
||||
third-party hooks) are preserved — the script only appends the new
|
||||
wrapper entries when they are not already registered.
|
||||
- Idempotent on re-runs: a second invocation recognizes the canonical
|
||||
command strings and logs `[SKIP]` instead of duplicating entries.
|
||||
|
||||
## Resulting command shape
|
||||
|
||||
```
|
||||
bash "C:/Users/<you>/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" pre
|
||||
bash "C:/Users/<you>/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" post
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```powershell
|
||||
pwsh -File docs/fixes/patch_settings_cl_v2_simple.ps1
|
||||
# Windows PowerShell 5.1 is also supported:
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File docs/fixes/patch_settings_cl_v2_simple.ps1
|
||||
```
|
||||
|
||||
The script backs up the existing settings file to
|
||||
`settings.local.json.bak-<timestamp>` before writing.
|
||||
|
||||
## PowerShell 5.1 compatibility
|
||||
|
||||
`ConvertFrom-Json -AsHashtable` is PowerShell 7+ only. The script tries
|
||||
`-AsHashtable` first and falls back to a manual `PSCustomObject` →
|
||||
`Hashtable` conversion on Windows PowerShell 5.1. Both hook buckets
|
||||
(`PreToolUse`, `PostToolUse`) and their inner `hooks` arrays are
|
||||
materialized as `System.Collections.ArrayList` before serialization, so
|
||||
PS 5.1's `ConvertTo-Json` cannot collapse single-element arrays into bare
|
||||
objects.
|
||||
|
||||
## Verified cases (dry-run)
|
||||
|
||||
1. Fresh install — no existing settings → creates canonical file.
|
||||
2. Idempotent re-run — existing canonical file → `[SKIP]` both phases,
|
||||
file contents unchanged apart from the pre-write backup.
|
||||
3. Legacy `observe.sh` present → preserves the legacy entries and
|
||||
appends the new `observe-wrapper.sh` entries alongside them.
|
||||
|
||||
All three cases produce LF-only output and match the shape registered by
|
||||
PR #1524's manual fix to `settings.local.json`.
|
||||
|
||||
## Related
|
||||
|
||||
- PR #1524 — settings.local.json shape fix (same argv-dup root cause)
|
||||
- PR #1539 — locale-independent `detect-project.sh`
|
||||
- PR #1540 — `install_hook_wrapper.ps1` argv-dup fix (companion script)
|
||||
60
docs/fixes/apply-hook-fix.sh
Normal file
60
docs/fixes/apply-hook-fix.sh
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
# Apply ECC hook fix to ~/.claude/settings.local.json.
|
||||
#
|
||||
# - Creates a timestamped backup next to the original.
|
||||
# - Rewrites the file as UTF-8 (no BOM), LF line endings.
|
||||
# - Routes hook commands directly at observe-wrapper.sh with a "pre"/"post" arg.
|
||||
#
|
||||
# Related fix doc: docs/fixes/HOOK-FIX-20260421.md
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TARGET="${1:-$HOME/.claude/settings.local.json}"
|
||||
WRAPPER="${ECC_OBSERVE_WRAPPER:-$HOME/.claude/skills/continuous-learning/hooks/observe-wrapper.sh}"
|
||||
|
||||
if [ ! -f "$WRAPPER" ]; then
|
||||
echo "[hook-fix] wrapper not found: $WRAPPER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$TARGET")"
|
||||
|
||||
if [ -f "$TARGET" ]; then
|
||||
ts="$(date +%Y%m%d-%H%M%S)"
|
||||
cp "$TARGET" "$TARGET.bak-hookfix-$ts"
|
||||
echo "[hook-fix] backup: $TARGET.bak-hookfix-$ts"
|
||||
fi
|
||||
|
||||
# Convert wrapper path to forward-slash form for JSON.
|
||||
wrapper_fwd="$(printf '%s' "$WRAPPER" | tr '\\\\' '/')"
|
||||
|
||||
# Write the new config as UTF-8 (no BOM), LF line endings.
|
||||
printf '%s\n' '{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "'"$wrapper_fwd"' pre"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "'"$wrapper_fwd"' post"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}' > "$TARGET"
|
||||
|
||||
echo "[hook-fix] wrote: $TARGET"
|
||||
echo "[hook-fix] restart the claude CLI for changes to take effect"
|
||||
167
docs/fixes/install_hook_wrapper.ps1
Normal file
167
docs/fixes/install_hook_wrapper.ps1
Normal file
@@ -0,0 +1,167 @@
|
||||
# Install observe-wrapper.sh + rewrite settings.local.json to use it
|
||||
# No Japanese literals - uses $PSScriptRoot instead
|
||||
# argv-dup bug workaround: use `bash` (PATH-resolved) as first token and
|
||||
# normalize wrapper path to forward slashes. See PR #1524.
|
||||
#
|
||||
# PowerShell 5.1 compatibility:
|
||||
# - `ConvertFrom-Json -AsHashtable` is PS 7+ only; fall back to a manual
|
||||
# PSCustomObject -> Hashtable conversion on Windows PowerShell 5.1.
|
||||
# - PS 5.1 `ConvertTo-Json` collapses single-element arrays inside
|
||||
# Hashtables into bare objects. Normalize the hook buckets
|
||||
# (PreToolUse / PostToolUse) and their inner `hooks` arrays as
|
||||
# `System.Collections.ArrayList` before serialization to preserve
|
||||
# array shape.
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$SkillHooks = "$env:USERPROFILE\.claude\skills\continuous-learning\hooks"
|
||||
$WrapperSrc = Join-Path $PSScriptRoot "observe-wrapper.sh"
|
||||
$WrapperDst = "$SkillHooks\observe-wrapper.sh"
|
||||
$SettingsPath = "$env:USERPROFILE\.claude\settings.local.json"
|
||||
# Use PATH-resolved `bash` to avoid Claude Code v2.1.116 argv-dup bug that
|
||||
# double-passes the first token when the quoted path is a Windows .exe.
|
||||
$BashExe = "bash"
|
||||
|
||||
Write-Host "=== Install Hook Wrapper ===" -ForegroundColor Cyan
|
||||
Write-Host "ScriptRoot: $PSScriptRoot"
|
||||
Write-Host "WrapperSrc: $WrapperSrc"
|
||||
|
||||
if (-not (Test-Path $WrapperSrc)) {
|
||||
Write-Host "[ERROR] Source not found: $WrapperSrc" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Ensure the hook destination directory exists (fresh installs have no
|
||||
# skills/continuous-learning/hooks tree yet).
|
||||
$dstDir = Split-Path $WrapperDst
|
||||
if (-not (Test-Path $dstDir)) {
|
||||
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# --- Helpers ------------------------------------------------------------
|
||||
|
||||
# Convert a PSCustomObject tree (as returned by ConvertFrom-Json on PS 5.1)
|
||||
# into nested Hashtables/ArrayLists so the merge logic below works uniformly
|
||||
# and so ConvertTo-Json preserves single-element arrays on PS 5.1.
|
||||
function ConvertTo-HashtableRecursive {
|
||||
param($InputObject)
|
||||
if ($null -eq $InputObject) { return $null }
|
||||
if ($InputObject -is [System.Collections.IDictionary]) {
|
||||
$result = @{}
|
||||
foreach ($key in $InputObject.Keys) {
|
||||
$result[$key] = ConvertTo-HashtableRecursive -InputObject $InputObject[$key]
|
||||
}
|
||||
return $result
|
||||
}
|
||||
if ($InputObject -is [System.Management.Automation.PSCustomObject]) {
|
||||
$result = @{}
|
||||
foreach ($prop in $InputObject.PSObject.Properties) {
|
||||
$result[$prop.Name] = ConvertTo-HashtableRecursive -InputObject $prop.Value
|
||||
}
|
||||
return $result
|
||||
}
|
||||
if ($InputObject -is [System.Collections.IList] -or $InputObject -is [System.Array]) {
|
||||
$list = [System.Collections.ArrayList]::new()
|
||||
foreach ($item in $InputObject) {
|
||||
$null = $list.Add((ConvertTo-HashtableRecursive -InputObject $item))
|
||||
}
|
||||
return ,$list
|
||||
}
|
||||
return $InputObject
|
||||
}
|
||||
|
||||
function Read-SettingsAsHashtable {
|
||||
param([string]$Path)
|
||||
$raw = Get-Content -Raw -Path $Path -Encoding UTF8
|
||||
if ([string]::IsNullOrWhiteSpace($raw)) { return @{} }
|
||||
try {
|
||||
return ($raw | ConvertFrom-Json -AsHashtable)
|
||||
} catch {
|
||||
$obj = $raw | ConvertFrom-Json
|
||||
return (ConvertTo-HashtableRecursive -InputObject $obj)
|
||||
}
|
||||
}
|
||||
|
||||
function ConvertTo-ArrayList {
|
||||
param($Value)
|
||||
$list = [System.Collections.ArrayList]::new()
|
||||
foreach ($item in @($Value)) { $null = $list.Add($item) }
|
||||
return ,$list
|
||||
}
|
||||
|
||||
# --- 1) Copy wrapper + LF normalization ---------------------------------
|
||||
Write-Host "[1/4] Copy wrapper to $WrapperDst" -ForegroundColor Yellow
|
||||
$content = Get-Content -Raw -Path $WrapperSrc
|
||||
$contentLf = $content -replace "`r`n","`n"
|
||||
$utf8 = [System.Text.UTF8Encoding]::new($false)
|
||||
[System.IO.File]::WriteAllText($WrapperDst, $contentLf, $utf8)
|
||||
Write-Host " [OK] wrapper installed with LF endings" -ForegroundColor Green
|
||||
|
||||
# --- 2) Backup settings -------------------------------------------------
|
||||
Write-Host "[2/4] Backup settings.local.json" -ForegroundColor Yellow
|
||||
if (-not (Test-Path $SettingsPath)) {
|
||||
Write-Host "[ERROR] Settings file not found: $SettingsPath" -ForegroundColor Red
|
||||
Write-Host " Run patch_settings_cl_v2_simple.ps1 first to bootstrap the file." -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
$backup = "$SettingsPath.bak-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
Copy-Item $SettingsPath $backup -Force
|
||||
Write-Host " [OK] $backup" -ForegroundColor Green
|
||||
|
||||
# --- 3) Rewrite command path in settings.local.json ---------------------
|
||||
Write-Host "[3/4] Rewrite hook command to wrapper" -ForegroundColor Yellow
|
||||
$settings = Read-SettingsAsHashtable -Path $SettingsPath
|
||||
|
||||
# Normalize wrapper path to forward slashes so bash (MSYS/Git Bash) does not
|
||||
# mangle backslashes; quoting keeps spaces safe.
|
||||
$wrapperPath = $WrapperDst -replace '\\','/'
|
||||
$preCmd = $BashExe + ' "' + $wrapperPath + '" pre'
|
||||
$postCmd = $BashExe + ' "' + $wrapperPath + '" post'
|
||||
|
||||
if (-not $settings.ContainsKey("hooks") -or $null -eq $settings["hooks"]) {
|
||||
$settings["hooks"] = @{}
|
||||
}
|
||||
foreach ($key in @("PreToolUse", "PostToolUse")) {
|
||||
if (-not $settings.hooks.ContainsKey($key) -or $null -eq $settings.hooks[$key]) {
|
||||
$settings.hooks[$key] = [System.Collections.ArrayList]::new()
|
||||
} elseif (-not ($settings.hooks[$key] -is [System.Collections.ArrayList])) {
|
||||
$settings.hooks[$key] = (ConvertTo-ArrayList -Value $settings.hooks[$key])
|
||||
}
|
||||
# Inner `hooks` arrays need the same ArrayList normalization to
|
||||
# survive PS 5.1 ConvertTo-Json serialization.
|
||||
foreach ($entry in $settings.hooks[$key]) {
|
||||
if ($entry -is [System.Collections.IDictionary] -and $entry.ContainsKey("hooks") -and
|
||||
-not ($entry["hooks"] -is [System.Collections.ArrayList])) {
|
||||
$entry["hooks"] = (ConvertTo-ArrayList -Value $entry["hooks"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Point every existing hook command at the wrapper with the appropriate
|
||||
# positional argument. The entry shape is preserved exactly; only the
|
||||
# `command` field is rewritten.
|
||||
foreach ($entry in $settings.hooks.PreToolUse) {
|
||||
foreach ($h in @($entry.hooks)) {
|
||||
if ($h -is [System.Collections.IDictionary]) { $h["command"] = $preCmd }
|
||||
}
|
||||
}
|
||||
foreach ($entry in $settings.hooks.PostToolUse) {
|
||||
foreach ($h in @($entry.hooks)) {
|
||||
if ($h -is [System.Collections.IDictionary]) { $h["command"] = $postCmd }
|
||||
}
|
||||
}
|
||||
|
||||
$json = $settings | ConvertTo-Json -Depth 20
|
||||
# Normalize CRLF -> LF so hook parsers never see mixed line endings.
|
||||
$jsonLf = $json -replace "`r`n","`n"
|
||||
[System.IO.File]::WriteAllText($SettingsPath, $jsonLf, $utf8)
|
||||
Write-Host " [OK] command updated" -ForegroundColor Green
|
||||
Write-Host " PreToolUse command: $preCmd"
|
||||
Write-Host " PostToolUse command: $postCmd"
|
||||
|
||||
# --- 4) Verify ----------------------------------------------------------
|
||||
Write-Host "[4/4] Verify" -ForegroundColor Yellow
|
||||
Get-Content $SettingsPath | Select-String "command"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== DONE ===" -ForegroundColor Green
|
||||
Write-Host "Next: Launch Claude CLI and run any command to trigger observations.jsonl"
|
||||
187
docs/fixes/patch_settings_cl_v2_simple.ps1
Normal file
187
docs/fixes/patch_settings_cl_v2_simple.ps1
Normal file
@@ -0,0 +1,187 @@
|
||||
# Simple patcher for settings.local.json - CL v2 hooks (argv-dup safe)
|
||||
#
|
||||
# No Japanese literals - keeps the file ASCII-only so PowerShell parses it
|
||||
# regardless of the active code page.
|
||||
#
|
||||
# argv-dup bug workaround (Claude Code v2.1.116):
|
||||
# - Use PATH-resolved `bash` (no quoted .exe) as the first argv token.
|
||||
# - Point the hook at observe-wrapper.sh (not observe.sh).
|
||||
# - Pass `pre` / `post` as explicit positional arguments so PreToolUse and
|
||||
# PostToolUse are registered as distinct commands.
|
||||
# - Normalize the wrapper path to forward slashes to keep MSYS/Git Bash
|
||||
# happy and write the JSON with LF endings only.
|
||||
#
|
||||
# References:
|
||||
# - PR #1524 (settings.local.json argv-dup fix)
|
||||
# - PR #1540 (install_hook_wrapper.ps1 argv-dup fix)
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$SettingsPath = "$env:USERPROFILE\.claude\settings.local.json"
|
||||
$WrapperDst = "$env:USERPROFILE\.claude\skills\continuous-learning\hooks\observe-wrapper.sh"
|
||||
$BashExe = "bash"
|
||||
|
||||
# Normalize wrapper path to forward slashes and build distinct pre/post
|
||||
# commands. Quoting keeps spaces in the path safe.
|
||||
$wrapperPath = $WrapperDst -replace '\\','/'
|
||||
$preCmd = $BashExe + ' "' + $wrapperPath + '" pre'
|
||||
$postCmd = $BashExe + ' "' + $wrapperPath + '" post'
|
||||
|
||||
Write-Host "=== CL v2 Simple Patcher (argv-dup safe) ===" -ForegroundColor Cyan
|
||||
Write-Host "Target : $SettingsPath"
|
||||
Write-Host "Wrapper : $wrapperPath"
|
||||
Write-Host "Pre command : $preCmd"
|
||||
Write-Host "Post command: $postCmd"
|
||||
|
||||
# Ensure parent dir exists
|
||||
$parent = Split-Path $SettingsPath
|
||||
if (-not (Test-Path $parent)) {
|
||||
New-Item -ItemType Directory -Path $parent -Force | Out-Null
|
||||
}
|
||||
|
||||
function New-HookEntry {
|
||||
param([string]$Command)
|
||||
# Inner `hooks` uses ArrayList so a single-element list does not get
|
||||
# collapsed into an object when PS 5.1 ConvertTo-Json serializes the
|
||||
# enclosing Hashtable.
|
||||
$inner = [System.Collections.ArrayList]::new()
|
||||
$null = $inner.Add(@{ type = "command"; command = $Command })
|
||||
return @{
|
||||
matcher = "*"
|
||||
hooks = $inner
|
||||
}
|
||||
}
|
||||
|
||||
# Convert a PSCustomObject tree (as returned by ConvertFrom-Json on PS 5.1)
|
||||
# into nested Hashtables/Arrays so the merge logic below works uniformly.
|
||||
# PS 7+ gets the same shape via `ConvertFrom-Json -AsHashtable` directly.
|
||||
function ConvertTo-HashtableRecursive {
|
||||
param($InputObject)
|
||||
if ($null -eq $InputObject) { return $null }
|
||||
if ($InputObject -is [System.Collections.IDictionary]) {
|
||||
$result = @{}
|
||||
foreach ($key in $InputObject.Keys) {
|
||||
$result[$key] = ConvertTo-HashtableRecursive -InputObject $InputObject[$key]
|
||||
}
|
||||
return $result
|
||||
}
|
||||
if ($InputObject -is [System.Management.Automation.PSCustomObject]) {
|
||||
$result = @{}
|
||||
foreach ($prop in $InputObject.PSObject.Properties) {
|
||||
$result[$prop.Name] = ConvertTo-HashtableRecursive -InputObject $prop.Value
|
||||
}
|
||||
return $result
|
||||
}
|
||||
if ($InputObject -is [System.Collections.IList] -or $InputObject -is [System.Array]) {
|
||||
# Use ArrayList so PS 5.1 ConvertTo-Json preserves single-element
|
||||
# arrays instead of collapsing them into objects. Plain Object[]
|
||||
# suffers from that collapse when embedded in a Hashtable value.
|
||||
$result = [System.Collections.ArrayList]::new()
|
||||
foreach ($item in $InputObject) {
|
||||
$null = $result.Add((ConvertTo-HashtableRecursive -InputObject $item))
|
||||
}
|
||||
return ,$result
|
||||
}
|
||||
return $InputObject
|
||||
}
|
||||
|
||||
function Read-SettingsAsHashtable {
|
||||
param([string]$Path)
|
||||
$raw = Get-Content -Raw -Path $Path -Encoding UTF8
|
||||
if ([string]::IsNullOrWhiteSpace($raw)) { return @{} }
|
||||
# Prefer `-AsHashtable` (PS 7+); fall back to manual conversion on PS 5.1
|
||||
# where that parameter does not exist.
|
||||
try {
|
||||
return ($raw | ConvertFrom-Json -AsHashtable)
|
||||
} catch {
|
||||
$obj = $raw | ConvertFrom-Json
|
||||
return (ConvertTo-HashtableRecursive -InputObject $obj)
|
||||
}
|
||||
}
|
||||
|
||||
$preEntry = New-HookEntry -Command $preCmd
|
||||
$postEntry = New-HookEntry -Command $postCmd
|
||||
|
||||
if (Test-Path $SettingsPath) {
|
||||
$backup = "$SettingsPath.bak-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
Copy-Item $SettingsPath $backup -Force
|
||||
Write-Host "[BACKUP] $backup" -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
$existing = Read-SettingsAsHashtable -Path $SettingsPath
|
||||
} catch {
|
||||
Write-Host "[WARN] Failed to parse existing JSON, will overwrite (backup preserved)" -ForegroundColor Yellow
|
||||
$existing = @{}
|
||||
}
|
||||
if ($null -eq $existing) { $existing = @{} }
|
||||
|
||||
if (-not $existing.ContainsKey("hooks")) {
|
||||
$existing["hooks"] = @{}
|
||||
}
|
||||
# Normalize the two hook buckets into ArrayList so both existing and newly
|
||||
# added entries survive PS 5.1 ConvertTo-Json array collapsing.
|
||||
foreach ($key in @("PreToolUse", "PostToolUse")) {
|
||||
if (-not $existing.hooks.ContainsKey($key)) {
|
||||
$existing.hooks[$key] = [System.Collections.ArrayList]::new()
|
||||
} elseif (-not ($existing.hooks[$key] -is [System.Collections.ArrayList])) {
|
||||
$list = [System.Collections.ArrayList]::new()
|
||||
foreach ($item in @($existing.hooks[$key])) { $null = $list.Add($item) }
|
||||
$existing.hooks[$key] = $list
|
||||
}
|
||||
# Each entry's inner `hooks` array needs the same treatment so legacy
|
||||
# single-element arrays do not serialize as bare objects.
|
||||
foreach ($entry in $existing.hooks[$key]) {
|
||||
if ($entry -is [System.Collections.IDictionary] -and $entry.ContainsKey("hooks") -and
|
||||
-not ($entry["hooks"] -is [System.Collections.ArrayList])) {
|
||||
$innerList = [System.Collections.ArrayList]::new()
|
||||
foreach ($item in @($entry["hooks"])) { $null = $innerList.Add($item) }
|
||||
$entry["hooks"] = $innerList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Duplicate check uses the exact command string so legacy observe.sh
|
||||
# entries are left in place unless re-run manually removes them.
|
||||
$hasPre = $false
|
||||
foreach ($e in $existing.hooks.PreToolUse) {
|
||||
foreach ($h in @($e.hooks)) { if ($h.command -eq $preCmd) { $hasPre = $true } }
|
||||
}
|
||||
$hasPost = $false
|
||||
foreach ($e in $existing.hooks.PostToolUse) {
|
||||
foreach ($h in @($e.hooks)) { if ($h.command -eq $postCmd) { $hasPost = $true } }
|
||||
}
|
||||
|
||||
if (-not $hasPre) {
|
||||
$null = $existing.hooks.PreToolUse.Add($preEntry)
|
||||
Write-Host "[ADD] PreToolUse" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[SKIP] PreToolUse already registered" -ForegroundColor Gray
|
||||
}
|
||||
if (-not $hasPost) {
|
||||
$null = $existing.hooks.PostToolUse.Add($postEntry)
|
||||
Write-Host "[ADD] PostToolUse" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[SKIP] PostToolUse already registered" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
$json = $existing | ConvertTo-Json -Depth 20
|
||||
} else {
|
||||
Write-Host "[CREATE] new settings.local.json" -ForegroundColor Green
|
||||
$newSettings = @{
|
||||
hooks = @{
|
||||
PreToolUse = @($preEntry)
|
||||
PostToolUse = @($postEntry)
|
||||
}
|
||||
}
|
||||
$json = $newSettings | ConvertTo-Json -Depth 20
|
||||
}
|
||||
|
||||
# Write UTF-8 no BOM and normalize CRLF -> LF so hook parsers never see
|
||||
# mixed line endings.
|
||||
$jsonLf = $json -replace "`r`n","`n"
|
||||
$utf8 = [System.Text.UTF8Encoding]::new($false)
|
||||
[System.IO.File]::WriteAllText($SettingsPath, $jsonLf, $utf8)
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Patch SUCCESS ===" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Get-Content -Path $SettingsPath -Encoding UTF8
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user