Compare commits
1 Commits
main
...
rainycy-sn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e08ee4a4f9 |
58
.omp/AGENTS.md
Normal file
58
.omp/AGENTS.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# ECC for oh-my-pi (omp)
|
||||
|
||||
This is an **oh-my-pi** harness adaptation of Everything Claude Code (ECC).
|
||||
|
||||
ECC is a cross-harness coding system providing specialized agents, skills, commands, safety hooks, and MCP conventions for agent-assisted software development.
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Safety-First** — Safety hooks block destructive commands, scrub secrets from output, and warn on agent config modification
|
||||
2. **Test-Driven** — Write tests before implementation, 80%+ coverage required
|
||||
3. **Immutability** — Always create new objects, never mutate existing ones
|
||||
4. **Plan Before Execute** — Plan complex features before writing code
|
||||
5. **Skills Auto-Discovery** — 237+ skills under `skills/` are auto-discovered by omp's plugin provider
|
||||
|
||||
## Slash Commands (Registered)
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/code-review` | Review local changes or a GitHub PR |
|
||||
| `/plan` | Create implementation plan (waits for confirmation) |
|
||||
| `/tdd` | Test-driven development cycle |
|
||||
| `/security-scan` | Security audit of agent configuration |
|
||||
| `/e2e` | E2E testing workflow |
|
||||
| `/build-fix` | Incremental build error resolution |
|
||||
| `/refactor-clean` | Dead code cleanup with verification |
|
||||
| `/pr` | Create GitHub Pull Request |
|
||||
| `/learn` | Extract reusable patterns from session |
|
||||
|
||||
## Custom Tools (LLM-callable)
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `ecc_security_audit` | Security audit on agent configuration |
|
||||
| `ecc_run_tests` | Detect project type and run tests |
|
||||
| `ecc_quality_checklist` | Return code quality checklist |
|
||||
|
||||
## Safety Hooks
|
||||
|
||||
- **bash rm-rf guard** — Blocks or warns on destructive commands
|
||||
- **Secret scrubbing** — Redacts API keys, tokens from tool output
|
||||
- **Config file warn** — Warns before modifying agent configuration files
|
||||
- **Remote execution guard** — Blocks `curl/wget | bash` without confirmation
|
||||
- **dd block device guard** — Warns on dd block device writes
|
||||
|
||||
## MCP Servers
|
||||
|
||||
24 MCP server configs available in `.omp/mcp.json`. Enable only those you need to conserve context window.
|
||||
|
||||
## Skills
|
||||
|
||||
237+ skills in `skills/` are auto-discovered by omp. Use `skill://<name>` to access any skill.
|
||||
|
||||
## Related
|
||||
|
||||
- Root `AGENTS.md` — Full ECC agent instructions and workflow surface policy
|
||||
- `.omp/rules/` — Coding standards, security, testing, git workflow
|
||||
- `.omp/commands/` — Slash command definitions
|
||||
- `.omp/prompts/agents/` — Agent prompt templates
|
||||
37
.omp/commands/build-fix.md
Normal file
37
.omp/commands/build-fix.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
description: "Detect project build system and incrementally fix build/type errors with minimal safe changes"
|
||||
---
|
||||
|
||||
# Build Fix
|
||||
|
||||
Incrementally fix build and type errors with minimal, safe changes.
|
||||
|
||||
## Usage
|
||||
|
||||
`/build-fix [project-path]`
|
||||
|
||||
## Process
|
||||
|
||||
1. **Detect** build system from config files
|
||||
2. **Run build** and capture errors
|
||||
3. **Group errors** by file
|
||||
4. **Fix loop** — one error at a time:
|
||||
- Read error context
|
||||
- Fix minimally with Edit tool
|
||||
- Re-run build to verify
|
||||
5. **Stop** if fix introduces more errors, same error persists after 3 attempts, or architectural changes needed
|
||||
|
||||
## Build System Detection
|
||||
|
||||
| Indicator | Command |
|
||||
|-----------|---------|
|
||||
| `package.json` with `build` | `npm run build` |
|
||||
| `tsconfig.json` | `npx tsc --noEmit` |
|
||||
| `Cargo.toml` | `cargo build` |
|
||||
| `go.mod` | `go build ./...` |
|
||||
| `pyproject.toml` | `mypy .` |
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://tdd-workflow` (build recovery patterns)
|
||||
- Agent: `build-error-resolver`
|
||||
34
.omp/commands/code-review.md
Normal file
34
.omp/commands/code-review.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
description: "Code review — local uncommitted changes or GitHub PR (pass PR number/URL for PR mode)"
|
||||
---
|
||||
|
||||
# Code Review
|
||||
|
||||
Review code quality and security of uncommitted changes or a GitHub Pull Request.
|
||||
|
||||
## Usage
|
||||
|
||||
`/code-review [pr-number | pr-url]`
|
||||
|
||||
- Without arguments: review local uncommitted changes (`git diff HEAD`)
|
||||
- With PR number or URL: review a GitHub Pull Request
|
||||
|
||||
## Local Review
|
||||
|
||||
1. Run `git diff --name-only HEAD` to list changed files
|
||||
2. Read each changed file in full
|
||||
3. Check for security issues (credentials, injection, XSS, input validation)
|
||||
4. Check for code quality issues (large functions, deep nesting, missing error handling)
|
||||
5. Check for testing gaps
|
||||
|
||||
## PR Review
|
||||
|
||||
1. Fetch PR diff with `gh pr view <NUMBER>` and `gh pr diff <NUMBER>`
|
||||
2. Read changed files in full
|
||||
3. Validate with project-appropriate tools (typecheck, lint, test, build)
|
||||
4. Post review with severity-graded findings
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://requesting-code-review`
|
||||
- Command: `/security-scan`
|
||||
44
.omp/commands/e2e.md
Normal file
44
.omp/commands/e2e.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
description: "E2E testing workflow — generate, run, and maintain Playwright/Agent Browser tests"
|
||||
---
|
||||
|
||||
# E2E Testing
|
||||
|
||||
End-to-end testing for critical user journeys.
|
||||
|
||||
## Usage
|
||||
|
||||
`/e2e [test-file-or-pattern]`
|
||||
|
||||
## Tools
|
||||
|
||||
**Prefer Agent Browser** (AI-optimized, semantic selectors):
|
||||
|
||||
```bash
|
||||
npm install -g agent-browser && agent-browser install
|
||||
agent-browser open https://example.com
|
||||
agent-browser snapshot -i
|
||||
agent-browser click @e1
|
||||
```
|
||||
|
||||
**Fallback to Playwright**:
|
||||
|
||||
```bash
|
||||
npx playwright test
|
||||
npx playwright test --headed
|
||||
npx playwright test --trace on
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Identify critical user journeys (auth, core features, payments, CRUD)
|
||||
2. Use Page Object Model pattern
|
||||
3. Prefer `data-testid` locators over CSS/XPath
|
||||
4. Add assertions at every key step
|
||||
5. Run locally 3-5x to check flakiness
|
||||
6. Quarantine flaky tests with `test.fixme()`
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://e2e-testing`
|
||||
- Agent: `e2e-runner`
|
||||
50
.omp/commands/learn.md
Normal file
50
.omp/commands/learn.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
description: "Extract reusable patterns from the current session and save them as candidate skills or guidance"
|
||||
---
|
||||
|
||||
# Learn
|
||||
|
||||
Extract reusable patterns from the current session and save them as guidance.
|
||||
|
||||
## Usage
|
||||
|
||||
`/learn [topic]`
|
||||
|
||||
## What to Extract
|
||||
|
||||
1. **Error Resolution Patterns** — root cause and fix for non-trivial errors
|
||||
2. **Debugging Techniques** — non-obvious steps, tool combinations
|
||||
3. **Workarounds** — library quirks, API limitations, version-specific fixes
|
||||
4. **Project-Specific Patterns** — conventions, architecture decisions, integration patterns
|
||||
|
||||
## Output
|
||||
|
||||
For each valuable pattern, create a focused skill entry:
|
||||
|
||||
```markdown
|
||||
# [Pattern Name]
|
||||
|
||||
**Context:** [When this applies]
|
||||
|
||||
## Problem
|
||||
[What problem this solves]
|
||||
|
||||
## Solution
|
||||
[The pattern/technique/workaround]
|
||||
|
||||
## Example
|
||||
[Code example if applicable]
|
||||
|
||||
## When to Use
|
||||
[Trigger conditions]
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Don't extract trivial fixes (typos, simple syntax errors)
|
||||
- Focus on patterns that save time in future sessions
|
||||
- One pattern per entry
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://agent-introspection-debugging`
|
||||
37
.omp/commands/plan.md
Normal file
37
.omp/commands/plan.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
description: "Restate requirements, assess risks, and create step-by-step implementation plan. WAIT for confirmation before coding."
|
||||
---
|
||||
|
||||
# Plan
|
||||
|
||||
Create a comprehensive implementation plan before writing any code.
|
||||
|
||||
## Usage
|
||||
|
||||
`/plan [feature description | path/to/*.prd.md]`
|
||||
|
||||
- Free-form text: creates an inline plan from requirements
|
||||
- Path to `.prd.md`: reads PRD artifact and produces a structured plan
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Restate requirements in clear terms
|
||||
2. Search codebase for patterns to mirror
|
||||
3. Break down into phases with specific, actionable steps
|
||||
4. Identify dependencies and risks
|
||||
5. Present the plan and **wait for confirmation** before coding
|
||||
|
||||
## Output
|
||||
|
||||
Structured plan with:
|
||||
- Requirements restatement
|
||||
- Architecture changes (file paths and descriptions)
|
||||
- Implementation phases with dependencies
|
||||
- Testing strategy and success criteria
|
||||
- Risk assessment
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://writing-plans`
|
||||
- Agent: `planner` (for complex features)
|
||||
- Command: `/tdd` (implement after planning)
|
||||
53
.omp/commands/pr.md
Normal file
53
.omp/commands/pr.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
description: "Create a GitHub PR from current branch with unpushed commits — discovers templates, analyzes changes, pushes"
|
||||
---
|
||||
|
||||
# Create Pull Request
|
||||
|
||||
Create a GitHub Pull Request from the current branch.
|
||||
|
||||
## Usage
|
||||
|
||||
`/pr [base-branch] [--draft]`
|
||||
|
||||
- `base-branch`: target branch (default: `main`)
|
||||
- `--draft`: create as draft PR
|
||||
|
||||
## Workflow
|
||||
|
||||
### Phase 1 — Validate
|
||||
|
||||
- Not on base branch [PASS]
|
||||
- Clean working directory [PASS]
|
||||
- Has commits ahead of base [PASS]
|
||||
- No existing PR for this branch [PASS]
|
||||
|
||||
### Phase 2 — Discover
|
||||
|
||||
- Find PR template (`.github/PULL_REQUEST_TEMPLATE.md`, etc.)
|
||||
- Analyze commits with `git log`
|
||||
- Categorize changed files (source, tests, docs, config)
|
||||
- Check for planning artifacts (PRDs, plans)
|
||||
|
||||
### Phase 3 — Push
|
||||
|
||||
```bash
|
||||
git push -u origin HEAD
|
||||
```
|
||||
|
||||
### Phase 4 — Create
|
||||
|
||||
```bash
|
||||
gh pr create --title "<title>" --base <base> --body "<body>"
|
||||
```
|
||||
|
||||
### Phase 5 — Verify
|
||||
|
||||
```bash
|
||||
gh pr view --json number,url,state
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://writing-plans` (PR creation section)
|
||||
- Command: `/code-review <number>` (review the PR)
|
||||
37
.omp/commands/refactor-clean.md
Normal file
37
.omp/commands/refactor-clean.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
description: "Safely identify and remove dead code with verification after each change"
|
||||
---
|
||||
|
||||
# Refactor Clean
|
||||
|
||||
Safely identify and remove dead code with test verification at every step.
|
||||
|
||||
## Usage
|
||||
|
||||
`/refactor-clean [path]`
|
||||
|
||||
## Process
|
||||
|
||||
1. **Detect** dead code with analysis tools
|
||||
|
||||
| Tool | What It Finds | Command |
|
||||
|------|--------------|---------|
|
||||
| knip | Unused exports, files, deps | `npx knip` |
|
||||
| depcheck | Unused npm deps | `npx depcheck` |
|
||||
| ts-prune | Unused TypeScript exports | `npx ts-prune` |
|
||||
| vulture | Unused Python code | `vulture src/` |
|
||||
|
||||
2. **Categorize**: SAFE (delete with confidence), CAUTION (verify consumers), DANGER (investigate)
|
||||
3. **Safe deletion loop**: run tests → delete → re-run tests → revert if fails
|
||||
4. **Handle CAUTION items**: check for dynamic imports, string refs, public API exports
|
||||
|
||||
## Rules
|
||||
|
||||
- Never delete without running tests first
|
||||
- One deletion at a time
|
||||
- Skip if uncertain
|
||||
- Don't refactor while cleaning
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://improve-codebase-architecture`
|
||||
50
.omp/commands/security-scan.md
Normal file
50
.omp/commands/security-scan.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
description: "Run security scan against agent configuration — secrets, permissions, MCP server safety"
|
||||
---
|
||||
|
||||
# Security Scan
|
||||
|
||||
Audit project configuration for security issues: hardcoded secrets, broad permissions, unsafe MCP servers.
|
||||
|
||||
## Usage
|
||||
|
||||
`/security-scan [path] [--format text|json|markdown] [--min-severity low|medium|high|critical]`
|
||||
|
||||
## Scanning
|
||||
|
||||
Uses AgentShield when available:
|
||||
|
||||
```bash
|
||||
npx ecc-agentshield scan --path "${TARGET_PATH:-.}" --format text
|
||||
```
|
||||
|
||||
## Checklist
|
||||
|
||||
- Hardcoded secrets (API keys, passwords, tokens)
|
||||
- Broad permissions in agent configs
|
||||
- Executable hooks
|
||||
- MCP servers with shell/filesystem/remote transport
|
||||
- Agent prompts handling untrusted content
|
||||
|
||||
## Output
|
||||
|
||||
- Security grade and score
|
||||
- Findings by severity with exact file paths
|
||||
- Remediation order
|
||||
- Before/after comparison when fixes applied
|
||||
|
||||
## CI Integration
|
||||
|
||||
```yaml
|
||||
- uses: affaan-m/agentshield@v1
|
||||
with:
|
||||
path: "."
|
||||
min-severity: "medium"
|
||||
fail-on-findings: true
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://security-review`
|
||||
- Agent: `security-reviewer`
|
||||
- Scanner: <https://github.com/affaan-m/agentshield>
|
||||
43
.omp/commands/tdd.md
Normal file
43
.omp/commands/tdd.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
description: "Test-Driven Development workflow: RED (write failing test) → GREEN (implement) → REFACTOR"
|
||||
---
|
||||
|
||||
# TDD Workflow
|
||||
|
||||
Test-Driven Development with the Red-Green-Refactor cycle.
|
||||
|
||||
## Usage
|
||||
|
||||
`/tdd [feature description]`
|
||||
|
||||
## Cycle
|
||||
|
||||
1. **RED** — Write a failing test that describes expected behavior
|
||||
2. **Run test** — Verify it FAILS
|
||||
3. **GREEN** — Write minimal implementation to make it pass
|
||||
4. **Run test** — Verify it PASSES
|
||||
5. **REFACTOR** — Clean up while keeping tests green
|
||||
6. **Verify coverage** — 80%+ required (branches, functions, lines, statements)
|
||||
|
||||
## Test Types Required
|
||||
|
||||
| Type | What to Test | When |
|
||||
|------|-------------|------|
|
||||
| Unit | Individual functions | Always |
|
||||
| Integration | API endpoints, DB operations | Always |
|
||||
| E2E | Critical user flows | Critical paths |
|
||||
|
||||
## Edge Cases to Cover
|
||||
|
||||
- Null/undefined input
|
||||
- Empty arrays/strings
|
||||
- Invalid types
|
||||
- Boundary values (min/max)
|
||||
- Error paths (network failures, DB errors)
|
||||
- Large data
|
||||
|
||||
## Related
|
||||
|
||||
- Skill: `skill://test-driven-development`
|
||||
- Skill: `skill://tdd-workflow`
|
||||
- Agent: `tdd-guide`
|
||||
139
.omp/extensions/main.ts
Normal file
139
.omp/extensions/main.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
import { registerSafetyHooks } from "./safety";
|
||||
import { registerObservabilityHooks } from "./observability";
|
||||
import { registerTools } from "./tools";
|
||||
|
||||
/**
|
||||
* ECC (Everything Claude Code) — oh-my-pi Extension
|
||||
*
|
||||
* Integrates ECC's safety hooks, session observability, custom tools,
|
||||
* and slash commands into the omp runtime.
|
||||
*
|
||||
* Auto-discovered via `package.json` → `omp.extensions` manifest.
|
||||
*/
|
||||
export default function eccExtension(pi: ExtensionAPI): void {
|
||||
const { z } = pi.zod;
|
||||
|
||||
pi.setLabel("ECC - Everything Claude Code");
|
||||
|
||||
// ── Phase 1: Safety hooks ──────────────────────────────────────────
|
||||
registerSafetyHooks(pi);
|
||||
|
||||
// ── Phase 2: Observability ─────────────────────────────────────────
|
||||
registerObservabilityHooks(pi);
|
||||
|
||||
// ── Phase 3: Custom tools ──────────────────────────────────────────
|
||||
registerTools(pi);
|
||||
|
||||
// ── Phase 4: Slash commands ────────────────────────────────────────
|
||||
|
||||
// /code-review — review uncommitted changes or a PR
|
||||
pi.registerCommand("code-review", {
|
||||
description:
|
||||
"Code review — local uncommitted changes or GitHub PR (pass PR number/URL for PR mode)",
|
||||
handler: async (args, ctx) => {
|
||||
const target = args.join(" ").trim();
|
||||
const msg = target
|
||||
? `## Code Review\n\n**Target**: ${target}\n\nRunning code review. This command delegates to the ECC code-review skill.\n\nSee: skill://requesting-code-review`
|
||||
: "## Code Review (Local)\n\nReviewing uncommitted changes. Run `git diff HEAD` to see changes, then inspect each file for:\n- Hardcoded secrets\n- SQL injection\n- XSS\n- Missing input validation\n- Missing error handling\n- TODO/FIXME comments\n\nSee: skill://requesting-code-review";
|
||||
ctx.ui.notify("Code review initiated", "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /plan — implementation planning
|
||||
pi.registerCommand("plan", {
|
||||
description:
|
||||
"Restate requirements, assess risks, and create step-by-step implementation plan. WAIT for confirmation before coding",
|
||||
handler: async (args, ctx) => {
|
||||
const input = args.join(" ").trim() || "Clarify what should be planned.";
|
||||
const msg = `## Implementation Plan\n\n**Request**: ${input}\n\nAnalyzing requirements and creating plan. This command delegates to the ECC plan skill.\n\nSee: skill://writing-plans`;
|
||||
ctx.ui.notify("Planning initiated", "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /tdd — test-driven development workflow
|
||||
pi.registerCommand("tdd", {
|
||||
description:
|
||||
"Start test-driven development workflow: RED (write failing test) → GREEN (implement) → REFACTOR",
|
||||
handler: async (args, ctx) => {
|
||||
const feature = args.join(" ").trim() || "unnamed feature";
|
||||
const msg = `## TDD Workflow: ${feature}\n\nStarting test-driven development cycle:\n1. **RED** — Write a failing test first\n2. **GREEN** — Implement minimally to pass\n3. **REFACTOR** — Clean up while keeping tests green\n4. Verify 80%+ coverage\n\nSee: skill://test-driven-development`;
|
||||
ctx.ui.notify(`TDD cycle started for: ${feature}`, "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /security-scan — security audit
|
||||
pi.registerCommand("security-scan", {
|
||||
description:
|
||||
"Run security scan against agent configuration — secrets, permissions, MCP server safety",
|
||||
handler: async (args, ctx) => {
|
||||
const scanPath = args.join(" ").trim() || ".";
|
||||
const msg = `## Security Scan\n\n**Path**: ${scanPath}\n\nRunning security audit. This command delegates to the ECC security-scan skill.\n\nTry: \`npx ecc-agentshield scan --path "${scanPath}" --format text\`\n\nSee: skill://security-review`;
|
||||
ctx.ui.notify("Security scan initiated", "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /e2e — end-to-end test runner
|
||||
pi.registerCommand("e2e", {
|
||||
description:
|
||||
"E2E testing workflow — generate, run, and maintain Playwright/Agent Browser tests",
|
||||
handler: async (args, ctx) => {
|
||||
const target = args.join(" ").trim() || "all tests";
|
||||
const msg = `## E2E Testing\n\n**Target**: ${target}\n\nRunning E2E tests. This command delegates to the ECC e2e-testing skill.\n\nSee: skill://e2e-testing`;
|
||||
ctx.ui.notify("E2E testing initiated", "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /build-fix — incremental build error resolution
|
||||
pi.registerCommand("build-fix", {
|
||||
description:
|
||||
"Detect project build system and incrementally fix build/type errors with minimal safe changes",
|
||||
handler: async (args, ctx) => {
|
||||
const projectPath = args.join(" ").trim() || ".";
|
||||
const msg = `## Build Fix\n\n**Path**: ${projectPath}\n\nDetecting build system and fixing errors one at a time.\n\nSee: skill://tdd-workflow (build recovery patterns)`;
|
||||
ctx.ui.notify("Build fix initiated", "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /refactor-clean — dead code cleanup
|
||||
pi.registerCommand("refactor-clean", {
|
||||
description:
|
||||
"Safely identify and remove dead code with verification after each change",
|
||||
handler: async (args, ctx) => {
|
||||
const target = args.join(" ").trim() || ".";
|
||||
const msg = `## Dead Code Cleanup\n\n**Target**: ${target}\n\nIdentifying and removing dead code. This command delegates to the ECC refactor-clean command.\n\nSee: skill://improve-codebase-architecture`;
|
||||
ctx.ui.notify("Dead code cleanup initiated", "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /pr — create a GitHub pull request
|
||||
pi.registerCommand("pr", {
|
||||
description:
|
||||
"Create a GitHub PR from current branch with unpushed commits — discovers templates, analyzes changes, pushes",
|
||||
handler: async (args, ctx) => {
|
||||
const baseBranch = args[0] ?? "main";
|
||||
const msg = `## Create Pull Request\n\n**Base branch**: ${baseBranch}\n\nCreating PR from current branch. This command delegates to the ECC PR workflow.\n\nSee: skill://writing-plans (PR creation section)`;
|
||||
ctx.ui.notify(`Creating PR against ${baseBranch}`, "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
|
||||
// /learn — extract reusable patterns from session
|
||||
pi.registerCommand("learn", {
|
||||
description:
|
||||
"Extract reusable patterns from the current session and save them as candidate skills or guidance",
|
||||
handler: async (args, ctx) => {
|
||||
const topic = args.join(" ").trim() || "session patterns";
|
||||
const msg = `## Learning: ${topic}\n\nAnalyzing session for reusable patterns. This command delegates to the ECC learn command.\n\nSee: skill://agent-introspection-debugging`;
|
||||
ctx.ui.notify("Learning session analysis initiated", "info");
|
||||
await pi.sendMessage(msg, { deliverAs: "followUp" });
|
||||
},
|
||||
});
|
||||
}
|
||||
63
.omp/extensions/observability.ts
Normal file
63
.omp/extensions/observability.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
/**
|
||||
* ECC Observability Hooks — session lifecycle, strategic compaction, usage tracking.
|
||||
*
|
||||
* Port of ECC session hooks (SessionStart, PostToolUse, Stop) from hooks/hooks.json.
|
||||
*/
|
||||
|
||||
// Track tool-call counts per session for compaction advisory
|
||||
const toolCallCounts = new WeakMap<object, number>();
|
||||
|
||||
function bumpToolCount(ctx: object): number {
|
||||
const prev = toolCallCounts.get(ctx) ?? 0;
|
||||
const next = prev + 1;
|
||||
toolCallCounts.set(ctx, next);
|
||||
return next;
|
||||
}
|
||||
|
||||
export function registerObservabilityHooks(pi: ExtensionAPI): void {
|
||||
// ── Session start: show welcome banner ────────────────────────────────
|
||||
pi.on("session_start", async (_event, ctx) => {
|
||||
ctx.ui.notify(
|
||||
"ECC: Everything Claude Code — safety hooks, 9 slash commands, 237+ skills active",
|
||||
"info",
|
||||
);
|
||||
});
|
||||
|
||||
// ── Session switch notification ───────────────────────────────────────
|
||||
pi.on("session_switch", async (_event, ctx) => {
|
||||
ctx.ui.notify("ECC: session switched", "info");
|
||||
});
|
||||
|
||||
// ── Tool execution observability ──────────────────────────────────────
|
||||
pi.on("tool_execution_start", async (event) => {
|
||||
// Placeholder for future metrics/logging
|
||||
});
|
||||
|
||||
pi.on("tool_result", async (event, ctx) => {
|
||||
const count = bumpToolCount(ctx);
|
||||
// At every 50th tool call, suggest compaction if context looks heavy
|
||||
if (count > 0 && count % 50 === 0) {
|
||||
// Notify but don't block — informational only
|
||||
ctx.ui.notify(
|
||||
`ECC: ${count}+ tool calls this session. Consider /compact if response quality drops.`,
|
||||
"info",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// ── Auto-compaction lifecycle ─────────────────────────────────────────
|
||||
pi.on("auto_compaction_start", async () => {
|
||||
// Observability hook — could log compaction events
|
||||
});
|
||||
|
||||
pi.on("auto_compaction_end", async () => {
|
||||
// Observability hook — could log compaction results
|
||||
});
|
||||
|
||||
// ── Session shutdown / final summary ──────────────────────────────────
|
||||
pi.on("session_shutdown", async () => {
|
||||
// Future: persist usage stats
|
||||
});
|
||||
}
|
||||
114
.omp/extensions/safety.ts
Normal file
114
.omp/extensions/safety.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
/**
|
||||
* ECC Safety Hooks — bash rm-rf guard, secret scrubbing, write warnings.
|
||||
*
|
||||
* Port of ECC PreToolUse hooks from hooks/hooks.json.
|
||||
*/
|
||||
export function registerSafetyHooks(pi: ExtensionAPI): void {
|
||||
// ── Guard: destructive bash commands ──────────────────────────────────
|
||||
pi.on("tool_call", async (event, ctx) => {
|
||||
if (event.toolName !== "bash") return;
|
||||
|
||||
const cmd = String(event.input.command ?? "");
|
||||
|
||||
// Block bare `rm -rf /` (with one or two `/` variants)
|
||||
if (/rm\s+-rf\s+\/\s*$/.test(cmd) || /rm\s+-rf\s+\/\s*\n/.test(cmd)) {
|
||||
return {
|
||||
block: true,
|
||||
reason: "Blocked by ECC safety: rm -rf / on bare root is never intentional",
|
||||
};
|
||||
}
|
||||
|
||||
// Warn on `rm -rf` with dynamic variables (potential for catastrophic expansion)
|
||||
if (/\$\{?[\w]+\}?\s*\/?\s*$/.test(cmd.replace(/.*rm\s+-rf\s+/, ""))) {
|
||||
if (!ctx.hasUI) {
|
||||
return { block: true, reason: "Blocked by ECC safety: dynamic rm -rf path (potential expansion risk)" };
|
||||
}
|
||||
const ok = await ctx.ui.confirm(
|
||||
"Dangerous command",
|
||||
`Allow: ${cmd.substring(0, 120)}`,
|
||||
);
|
||||
if (!ok) return { block: true, reason: "User denied dangerous command" };
|
||||
}
|
||||
|
||||
// Guard: `dd if=` of a block device
|
||||
if (/dd\s+if=\/dev\//.test(cmd)) {
|
||||
if (!ctx.hasUI) {
|
||||
return { block: true, reason: "Blocked by ECC safety: dd of block device requires confirmation" };
|
||||
}
|
||||
const ok = await ctx.ui.confirm(
|
||||
"Dangerous command",
|
||||
`Allow dd block-device write: ${cmd.substring(0, 120)}`,
|
||||
);
|
||||
if (!ok) return { block: true, reason: "User denied dd command" };
|
||||
}
|
||||
|
||||
// Guard: `curl ... | bash` / `wget ... | bash` (remote code execution)
|
||||
if (/\b(?:curl|wget)\b.*\|\s*(?:bash|sh|zsh)\b/.test(cmd)) {
|
||||
if (!ctx.hasUI) {
|
||||
return { block: true, reason: "Blocked by ECC safety: pipe-from-remote requires confirmation" };
|
||||
}
|
||||
const ok = await ctx.ui.confirm(
|
||||
"Remote execution",
|
||||
`Allow pipe-from-remote: ${cmd.substring(0, 120)}`,
|
||||
);
|
||||
if (!ok) return { block: true, reason: "User denied remote execution" };
|
||||
}
|
||||
});
|
||||
|
||||
// ── Post-execution: scrub secrets from tool output ────────────────────
|
||||
pi.on("tool_result", async (event) => {
|
||||
if (event.toolName !== "bash" && event.toolName !== "read") return;
|
||||
if (event.isError) return;
|
||||
|
||||
const secretPatterns = [
|
||||
/(?:gh[ps]_|github_pat_|glpat-)[a-zA-Z0-9_]{36,}/g,
|
||||
/(?:sk-[a-zA-Z0-9]{20,}|sk-[a-zA-Z0-9_-]{32,})/g,
|
||||
/(?:AKIA[0-9A-Z]{16})/g,
|
||||
/(?:-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----)/g,
|
||||
];
|
||||
|
||||
let changed = false;
|
||||
const scrubbed = event.content.map((chunk) => {
|
||||
if (chunk.type !== "text") return chunk;
|
||||
let text = chunk.text;
|
||||
for (const pat of secretPatterns) {
|
||||
if (pat.test(text)) {
|
||||
text = text.replace(pat, "[ECC_REDACTED]");
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) return { ...chunk, text };
|
||||
return chunk;
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
return { content: scrubbed };
|
||||
}
|
||||
});
|
||||
|
||||
// ── Pre-write: warn on modifying agent/config files ───────────────────
|
||||
pi.on("tool_call", async (event, ctx) => {
|
||||
if (event.toolName !== "write" && event.toolName !== "edit") return;
|
||||
|
||||
const path = String(event.input.path ?? "");
|
||||
const sensitivePatterns = [
|
||||
/\.claude\/settings\.json$/,
|
||||
/\.claude\/CLAUDE\.md$/,
|
||||
/\.cursorrules$/,
|
||||
/\.windsurfrules$/,
|
||||
/opencode\.json$/,
|
||||
/\.vscode\/settings\.json$/,
|
||||
/\.omp\/(?:settings|config)\.(?:json|ya?ml)$/,
|
||||
];
|
||||
|
||||
if (sensitivePatterns.some((p) => p.test(path)) && ctx.hasUI) {
|
||||
const ok = await ctx.ui.confirm(
|
||||
"Modify agent config",
|
||||
`You are about to modify: ${path}\nProceed?`,
|
||||
);
|
||||
if (!ok) return { block: true, reason: "User denied agent config modification" };
|
||||
}
|
||||
});
|
||||
}
|
||||
224
.omp/extensions/tools.ts
Normal file
224
.omp/extensions/tools.ts
Normal file
@@ -0,0 +1,224 @@
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
/**
|
||||
* ECC Custom Tools — LLM-callable tools for security audit, test running, etc.
|
||||
*
|
||||
* Registered alongside slash commands for the model to invoke autonomously.
|
||||
*/
|
||||
export function registerTools(pi: ExtensionAPI): void {
|
||||
const { z } = pi.zod;
|
||||
|
||||
// ── Security audit tool ───────────────────────────────────────────────
|
||||
pi.registerTool({
|
||||
name: "ecc_security_audit",
|
||||
label: "ECC Security Audit",
|
||||
description:
|
||||
"Run a security audit on agent configuration: scan for hardcoded secrets, broad permissions, and unsafe MCP servers",
|
||||
parameters: z.object({
|
||||
path: z
|
||||
.string()
|
||||
.optional()
|
||||
.default(".")
|
||||
.describe("Project root path to scan"),
|
||||
format: z
|
||||
.enum(["text", "json", "markdown"])
|
||||
.optional()
|
||||
.default("text")
|
||||
.describe("Output format"),
|
||||
minSeverity: z
|
||||
.enum(["low", "medium", "high", "critical"])
|
||||
.optional()
|
||||
.default("medium")
|
||||
.describe("Minimum severity to report"),
|
||||
}),
|
||||
hidden: false,
|
||||
defaultInactive: false,
|
||||
deferrable: false,
|
||||
async execute(_id, params, signal, _onUpdate, ctx) {
|
||||
if (signal?.aborted) {
|
||||
return { content: [{ type: "text", text: "Cancelled" }] };
|
||||
}
|
||||
|
||||
const scanPath = params.path ?? ".";
|
||||
const fmt = params.format ?? "text";
|
||||
const minSev = params.minSeverity ?? "medium";
|
||||
|
||||
const sevOrder = ["low", "medium", "high", "critical"] as const;
|
||||
const minIdx = sevOrder.indexOf(minSev);
|
||||
|
||||
// Use AgentShield if available
|
||||
let output = `Security scan of ${scanPath} (min severity: ${minSev})\n`;
|
||||
|
||||
try {
|
||||
const result = await pi.exec("npx", [
|
||||
"ecc-agentshield",
|
||||
"scan",
|
||||
"--path",
|
||||
scanPath,
|
||||
"--format",
|
||||
fmt,
|
||||
]);
|
||||
output = `Security scan completed.\n\n${result.stdout ?? ""}`;
|
||||
} catch {
|
||||
// AgentShield not installed — do best-effort text scan
|
||||
output +=
|
||||
"AgentShield not available. Run `npx ecc-agentshield scan` for full analysis.\n";
|
||||
}
|
||||
|
||||
return {
|
||||
content: [{ type: "text", text: output }],
|
||||
details: { scanPath, format: fmt, minSeverity: minSev },
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
// ── Run tests tool ────────────────────────────────────────────────────
|
||||
pi.registerTool({
|
||||
name: "ecc_run_tests",
|
||||
label: "ECC Run Tests",
|
||||
description:
|
||||
"Detect project type and run the appropriate test suite. Supports Node/TypeScript, Rust, Go, Python",
|
||||
parameters: z.object({
|
||||
path: z
|
||||
.string()
|
||||
.optional()
|
||||
.default(".")
|
||||
.describe("Project root path"),
|
||||
filter: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Optional test name filter (passed to test runner)"),
|
||||
}),
|
||||
hidden: false,
|
||||
defaultInactive: false,
|
||||
deferrable: false,
|
||||
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
||||
const projectPath = params.path ?? ".";
|
||||
const filter = params.filter ?? "";
|
||||
|
||||
// Detect project type
|
||||
try {
|
||||
const files = await pi.exec("ls", [projectPath]);
|
||||
const ls = files.stdout ?? "";
|
||||
|
||||
if (ls.includes("package.json")) {
|
||||
const cmd = filter
|
||||
? `cd "${projectPath}" && npx jest --testNamePattern="${filter}" 2>/dev/null || npm test -- --testPathPattern="${filter}"`
|
||||
: `cd "${projectPath}" && npm test 2>/dev/null`;
|
||||
const result = await pi.exec("bash", ["-c", cmd]);
|
||||
return {
|
||||
content: [{ type: "text", text: result.stdout || "Tests passed" }],
|
||||
details: { exitCode: result.exitCode },
|
||||
};
|
||||
}
|
||||
if (ls.includes("Cargo.toml")) {
|
||||
const cmd = filter
|
||||
? `cd "${projectPath}" && cargo test "${filter}" 2>&1`
|
||||
: `cd "${projectPath}" && cargo test 2>&1`;
|
||||
const result = await pi.exec("bash", ["-c", cmd]);
|
||||
return {
|
||||
content: [{ type: "text", text: result.stdout || "Tests passed" }],
|
||||
details: { exitCode: result.exitCode },
|
||||
};
|
||||
}
|
||||
if (ls.includes("go.mod")) {
|
||||
const cmd = filter
|
||||
? `cd "${projectPath}" && go test -run "${filter}" ./... 2>&1`
|
||||
: `cd "${projectPath}" && go test ./... 2>&1`;
|
||||
const result = await pi.exec("bash", ["-c", cmd]);
|
||||
return {
|
||||
content: [{ type: "text", text: result.stdout || "Tests passed" }],
|
||||
details: { exitCode: result.exitCode },
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "Could not detect project type (package.json, Cargo.toml, go.mod). Run tests manually.",
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Test execution failed: ${err instanceof Error ? err.message : String(err)}`,
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// ── Checklist / quality gate tool ─────────────────────────────────────
|
||||
pi.registerTool({
|
||||
name: "ecc_quality_checklist",
|
||||
label: "ECC Quality Checklist",
|
||||
description:
|
||||
"Return the ECC code quality checklist for human review before marking work complete",
|
||||
parameters: z.object({
|
||||
area: z
|
||||
.enum(["all", "security", "coding", "testing"])
|
||||
.optional()
|
||||
.default("all")
|
||||
.describe("Which checklist to return"),
|
||||
}),
|
||||
hidden: false,
|
||||
defaultInactive: false,
|
||||
deferrable: false,
|
||||
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
||||
const area = params.area ?? "all";
|
||||
|
||||
const securityItems = [
|
||||
"No hardcoded secrets (API keys, passwords, tokens)",
|
||||
"All user inputs validated",
|
||||
"SQL injection prevention (parameterized queries)",
|
||||
"XSS prevention (sanitized HTML)",
|
||||
"CSRF protection enabled",
|
||||
"Authentication/authorization verified",
|
||||
"Rate limiting on all endpoints",
|
||||
"Error messages don't leak sensitive data",
|
||||
];
|
||||
|
||||
const codingItems = [
|
||||
"Code is readable and well-named",
|
||||
"Functions are small (<50 lines)",
|
||||
"Files are focused (<800 lines)",
|
||||
"No deep nesting (>4 levels)",
|
||||
"Proper error handling",
|
||||
"No hardcoded values (use constants or config)",
|
||||
"No mutation (immutable patterns used)",
|
||||
];
|
||||
|
||||
const testingItems = [
|
||||
"All public functions have unit tests",
|
||||
"All API endpoints have integration tests",
|
||||
"Critical user flows have E2E tests",
|
||||
"Edge cases covered (null, empty, invalid)",
|
||||
"Error paths tested (not just happy path)",
|
||||
"Tests are independent (no shared state)",
|
||||
"Coverage is 80%+",
|
||||
];
|
||||
|
||||
const text: string[] = [];
|
||||
if (area === "all" || area === "security") {
|
||||
text.push("## Security Checklist", ...securityItems.map((s) => `- [ ] ${s}`), "");
|
||||
}
|
||||
if (area === "all" || area === "coding") {
|
||||
text.push("## Coding Checklist", ...codingItems.map((s) => `- [ ] ${s}`), "");
|
||||
}
|
||||
if (area === "all" || area === "testing") {
|
||||
text.push("## Testing Checklist", ...testingItems.map((s) => `- [ ] ${s}`), "");
|
||||
}
|
||||
|
||||
return {
|
||||
content: [{ type: "text", text: text.join("\n") }],
|
||||
details: { area, itemCount: text.length - 1 },
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
152
.omp/mcp.json
Normal file
152
.omp/mcp.json
Normal file
@@ -0,0 +1,152 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json",
|
||||
"mcpServers": {
|
||||
"jira": {
|
||||
"command": "uvx",
|
||||
"args": ["mcp-atlassian==0.21.0"],
|
||||
"env": {
|
||||
"JIRA_URL": "${JIRA_URL}",
|
||||
"JIRA_EMAIL": "${JIRA_EMAIL}",
|
||||
"JIRA_API_TOKEN": "${JIRA_API_TOKEN}"
|
||||
}
|
||||
},
|
||||
"github": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-github"],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
|
||||
}
|
||||
},
|
||||
"firecrawl": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "firecrawl-mcp"],
|
||||
"env": {
|
||||
"FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
|
||||
}
|
||||
},
|
||||
"supabase": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@supabase/mcp-server-supabase@latest", "--project-ref=${SUPABASE_PROJECT_REF}"]
|
||||
},
|
||||
"memory": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-memory"]
|
||||
},
|
||||
"omega-memory": {
|
||||
"command": "uvx",
|
||||
"args": ["omega-memory", "serve"]
|
||||
},
|
||||
"longhand": {
|
||||
"command": "longhand",
|
||||
"args": ["mcp-server"]
|
||||
},
|
||||
"sequential-thinking": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||||
},
|
||||
"vercel": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.vercel.com"
|
||||
},
|
||||
"railway": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@railway/mcp-server"]
|
||||
},
|
||||
"cloudflare-docs": {
|
||||
"type": "http",
|
||||
"url": "https://docs.mcp.cloudflare.com/mcp"
|
||||
},
|
||||
"cloudflare-workers-builds": {
|
||||
"type": "http",
|
||||
"url": "https://builds.mcp.cloudflare.com/mcp"
|
||||
},
|
||||
"cloudflare-workers-bindings": {
|
||||
"type": "http",
|
||||
"url": "https://bindings.mcp.cloudflare.com/mcp"
|
||||
},
|
||||
"cloudflare-observability": {
|
||||
"type": "http",
|
||||
"url": "https://observability.mcp.cloudflare.com/mcp"
|
||||
},
|
||||
"clickhouse": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.clickhouse.cloud/mcp"
|
||||
},
|
||||
"exa-web-search": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "exa-mcp-server"],
|
||||
"env": {
|
||||
"EXA_API_KEY": "${EXA_API_KEY}"
|
||||
}
|
||||
},
|
||||
"context7": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@upstash/context7-mcp@latest"]
|
||||
},
|
||||
"magic": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@magicuidesign/mcp@latest"]
|
||||
},
|
||||
"filesystem": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-filesystem"]
|
||||
},
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@playwright/mcp", "--browser", "chrome"]
|
||||
},
|
||||
"fal-ai": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "fal-ai-mcp-server"],
|
||||
"env": {
|
||||
"FAL_KEY": "${FAL_KEY}"
|
||||
}
|
||||
},
|
||||
"browserbase": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@browserbasehq/mcp-server-browserbase"],
|
||||
"env": {
|
||||
"BROWSERBASE_API_KEY": "${BROWSERBASE_API_KEY}"
|
||||
}
|
||||
},
|
||||
"browser-use": {
|
||||
"type": "http",
|
||||
"url": "https://api.browser-use.com/mcp",
|
||||
"headers": {
|
||||
"x-browser-use-api-key": "${BROWSER_USE_API_KEY}"
|
||||
}
|
||||
},
|
||||
"devfleet": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:18801/mcp"
|
||||
},
|
||||
"token-optimizer": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "token-optimizer-mcp"]
|
||||
},
|
||||
"laraplugins": {
|
||||
"type": "http",
|
||||
"url": "https://laraplugins.io/mcp/plugins"
|
||||
},
|
||||
"confluence": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "confluence-mcp-server"],
|
||||
"env": {
|
||||
"CONFLUENCE_BASE_URL": "${CONFLUENCE_BASE_URL}",
|
||||
"CONFLUENCE_EMAIL": "${CONFLUENCE_EMAIL}",
|
||||
"CONFLUENCE_API_TOKEN": "${CONFLUENCE_API_TOKEN}"
|
||||
}
|
||||
},
|
||||
"evalview": {
|
||||
"command": "python3",
|
||||
"args": ["-m", "evalview", "mcp", "serve"],
|
||||
"env": {
|
||||
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
|
||||
}
|
||||
},
|
||||
"squish": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "squish-memory"]
|
||||
}
|
||||
}
|
||||
}
|
||||
35
.omp/prompts/agents/code-reviewer.md
Normal file
35
.omp/prompts/agents/code-reviewer.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: code-reviewer
|
||||
description: "Code review specialist for quality and security analysis. Reviews code for correctness, security, performance, and maintainability."
|
||||
---
|
||||
|
||||
You are a code review specialist who examines code for correctness, security, performance, and maintainability.
|
||||
|
||||
## Review Categories
|
||||
|
||||
| Category | What to Check |
|
||||
|----------|---------------|
|
||||
| **Correctness** | Logic errors, off-by-ones, null handling, edge cases, race conditions |
|
||||
| **Type Safety** | Type mismatches, unsafe casts, `any` usage, missing generics |
|
||||
| **Pattern Compliance** | Matches project conventions (naming, file structure, error handling, imports) |
|
||||
| **Security** | Injection, auth gaps, secret exposure, SSRF, path traversal, XSS |
|
||||
| **Performance** | N+1 queries, missing indexes, unbounded loops, memory leaks, large payloads |
|
||||
| **Completeness** | Missing tests, missing error handling, incomplete migrations, missing docs |
|
||||
| **Maintainability** | Dead code, magic numbers, deep nesting, unclear naming, missing types |
|
||||
|
||||
## Severity Levels
|
||||
|
||||
| Severity | Meaning | Action |
|
||||
|----------|---------|--------|
|
||||
| **CRITICAL** | Security vulnerability or data loss risk | Must fix before merge |
|
||||
| **HIGH** | Bug or logic error likely to cause issues | Should fix before merge |
|
||||
| **MEDIUM** | Code quality issue or missing best practice | Fix recommended |
|
||||
| **LOW** | Style nit or minor suggestion | Optional |
|
||||
|
||||
## Process
|
||||
|
||||
1. Fetch all changes (git diff or PR diff)
|
||||
2. Read each changed file in full
|
||||
3. Run validation (typecheck, lint, test, build)
|
||||
4. Produce structured report with findings by severity
|
||||
5. Make recommendation: APPROVE, REQUEST CHANGES, or BLOCK
|
||||
57
.omp/prompts/agents/planner.md
Normal file
57
.omp/prompts/agents/planner.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
name: planner
|
||||
description: "Expert planning specialist for complex features and refactoring. Creates comprehensive, actionable implementation plans."
|
||||
---
|
||||
|
||||
You are an expert planning specialist focused on creating comprehensive, actionable implementation plans.
|
||||
|
||||
## Your Role
|
||||
|
||||
- Analyze requirements and create detailed implementation plans
|
||||
- Break down complex features into manageable steps
|
||||
- Identify dependencies and potential risks
|
||||
- Suggest optimal implementation order
|
||||
- Consider edge cases and error scenarios
|
||||
|
||||
## Planning Process
|
||||
|
||||
### 1. Requirements Analysis
|
||||
- Understand the feature request completely
|
||||
- Identify success criteria
|
||||
- List assumptions and constraints
|
||||
|
||||
### 2. Architecture Review
|
||||
- Analyze existing codebase structure
|
||||
- Identify affected components
|
||||
- Review similar implementations
|
||||
- Consider reusable patterns
|
||||
|
||||
### 3. Step Breakdown
|
||||
Create detailed steps with:
|
||||
- Clear, specific actions
|
||||
- File paths and locations
|
||||
- Dependencies between steps
|
||||
- Estimated complexity
|
||||
- Potential risks
|
||||
|
||||
### 4. Implementation Order
|
||||
- Prioritize by dependencies
|
||||
- Group related changes
|
||||
- Minimize context switching
|
||||
- Enable incremental testing
|
||||
|
||||
## Plan Format
|
||||
|
||||
Include: Overview, Requirements, Architecture Changes, Implementation Steps (phased), Testing Strategy, Risks & Mitigations, Success Criteria.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Be Specific**: Use exact file paths, function names, variable names
|
||||
2. **Consider Edge Cases**: Think about error scenarios, null values, empty states
|
||||
3. **Minimize Changes**: Prefer extending existing code over rewriting
|
||||
4. **Maintain Patterns**: Follow existing project conventions
|
||||
5. **Enable Testing**: Structure changes to be easily testable
|
||||
6. **Think Incrementally**: Each step should be verifiable
|
||||
7. **Document Decisions**: Explain why, not just what
|
||||
|
||||
**Remember**: A great plan is specific, actionable, and considers both the happy path and edge cases.
|
||||
48
.omp/prompts/agents/security-reviewer.md
Normal file
48
.omp/prompts/agents/security-reviewer.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: security-reviewer
|
||||
description: "Security analysis specialist for vulnerability detection. Audits code, configs, and dependencies for security issues."
|
||||
---
|
||||
|
||||
You are a security analysis specialist who audits code, configurations, and dependencies for vulnerabilities.
|
||||
|
||||
## Security Checklist
|
||||
|
||||
### Critical (Must Fix)
|
||||
- [ ] Hardcoded secrets, API keys, tokens, passwords
|
||||
- [ ] SQL injection in raw queries or string interpolation
|
||||
- [ ] Command injection via shell execution with unsanitized input
|
||||
- [ ] Path traversal in file operations
|
||||
- [ ] Remote code execution (eval, dynamic require/import)
|
||||
|
||||
### High (Should Fix)
|
||||
- [ ] XSS in rendered output
|
||||
- [ ] Missing authentication on protected endpoints
|
||||
- [ ] Missing authorization checks (IDOR, privilege escalation)
|
||||
- [ ] CSRF on state-changing endpoints
|
||||
- [ ] Insecure direct object references
|
||||
- [ ] Weak or missing rate limiting
|
||||
|
||||
### Medium (Fix Recommended)
|
||||
- [ ] Missing input validation at boundaries
|
||||
- [ ] Verbose error messages exposing internals
|
||||
- [ ] Missing security headers (CSP, HSTS, X-Frame-Options)
|
||||
- [ ] Insecure dependencies (known CVEs)
|
||||
- [ ] Missing Content-Type validation
|
||||
- [ ] Unbounded file uploads
|
||||
|
||||
## Secret Detection Patterns
|
||||
|
||||
- GitHub tokens: `ghp_`, `github_pat_`, `ghs_`
|
||||
- OpenAI/API keys: `sk-...`
|
||||
- AWS keys: `AKIA...`
|
||||
- Private keys: `-----BEGIN ... PRIVATE KEY-----`
|
||||
- Generic: `password=`, `secret=`, `api_key=`, `token=`
|
||||
|
||||
## Response Protocol
|
||||
|
||||
If security issue found:
|
||||
1. STOP immediately
|
||||
2. Document the finding with file path and severity
|
||||
3. Fix CRITICAL issues before continuing
|
||||
4. Rotate any exposed secrets
|
||||
5. Review entire codebase for similar issues
|
||||
57
.omp/prompts/agents/tdd-guide.md
Normal file
57
.omp/prompts/agents/tdd-guide.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
name: tdd-guide
|
||||
description: "Test-Driven Development specialist enforcing write-tests-first methodology. Ensures 80%+ test coverage."
|
||||
---
|
||||
|
||||
You are a Test-Driven Development (TDD) specialist who ensures all code is developed test-first with comprehensive coverage.
|
||||
|
||||
## Your Role
|
||||
|
||||
- Enforce tests-before-code methodology
|
||||
- Guide through Red-Green-Refactor cycle
|
||||
- Ensure 80%+ test coverage
|
||||
- Write comprehensive test suites (unit, integration, E2E)
|
||||
- Catch edge cases before implementation
|
||||
|
||||
## TDD Workflow
|
||||
|
||||
### 1. Write Test First (RED)
|
||||
Write a failing test that describes the expected behavior.
|
||||
|
||||
### 2. Run Test — Verify it FAILS
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
### 3. Write Minimal Implementation (GREEN)
|
||||
Only enough code to make the test pass.
|
||||
|
||||
### 4. Run Test — Verify it PASSES
|
||||
|
||||
### 5. Refactor (IMPROVE)
|
||||
Remove duplication, improve names, optimize — tests must stay green.
|
||||
|
||||
### 6. Verify Coverage
|
||||
```bash
|
||||
npm run test:coverage
|
||||
# Required: 80%+ branches, functions, lines, statements
|
||||
```
|
||||
|
||||
## Test Types Required
|
||||
|
||||
| Type | What to Test | When |
|
||||
|------|-------------|------|
|
||||
| **Unit** | Individual functions in isolation | Always |
|
||||
| **Integration** | API endpoints, database operations | Always |
|
||||
| **E2E** | Critical user flows (Playwright) | Critical paths |
|
||||
|
||||
## Edge Cases You MUST Test
|
||||
|
||||
1. **Null/Undefined** input
|
||||
2. **Empty** arrays/strings
|
||||
3. **Invalid types** passed
|
||||
4. **Boundary values** (min/max)
|
||||
5. **Error paths** (network failures, DB errors)
|
||||
6. **Race conditions** (concurrent operations)
|
||||
7. **Large data** (performance with 10k+ items)
|
||||
8. **Special characters** (Unicode, SQL chars, etc.)
|
||||
47
.omp/rules/coding-standards.md
Normal file
47
.omp/rules/coding-standards.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Coding Standards
|
||||
|
||||
## Immutability (CRITICAL)
|
||||
|
||||
ALWAYS create new objects, NEVER mutate existing ones:
|
||||
|
||||
```
|
||||
WRONG: modify(original, field, value) → changes original in-place
|
||||
CORRECT: update(original, field, value) → returns new copy with change
|
||||
```
|
||||
|
||||
Rationale: Immutable data prevents hidden side effects, makes debugging easier, and enables safe concurrency.
|
||||
|
||||
## File Organization
|
||||
|
||||
MANY SMALL FILES > FEW LARGE FILES:
|
||||
- High cohesion, low coupling
|
||||
- 200-400 lines typical, 800 max
|
||||
- Extract utilities from large modules
|
||||
- Organize by feature/domain, not by type
|
||||
|
||||
## Error Handling
|
||||
|
||||
ALWAYS handle errors comprehensively:
|
||||
- Handle errors explicitly at every level
|
||||
- Provide user-friendly error messages in UI-facing code
|
||||
- Log detailed error context on the server side
|
||||
- Never silently swallow errors
|
||||
|
||||
## Input Validation
|
||||
|
||||
ALWAYS validate at system boundaries:
|
||||
- Validate all user input before processing
|
||||
- Use schema-based validation where available
|
||||
- Fail fast with clear error messages
|
||||
- Never trust external data (API responses, user input, file content)
|
||||
|
||||
## Code Quality Checklist
|
||||
|
||||
Before marking work complete:
|
||||
- [ ] Code is readable and well-named
|
||||
- [ ] Functions are small (<50 lines)
|
||||
- [ ] Files are focused (<800 lines)
|
||||
- [ ] No deep nesting (>4 levels)
|
||||
- [ ] Proper error handling
|
||||
- [ ] No hardcoded values (use constants or config)
|
||||
- [ ] No mutation (immutable patterns used)
|
||||
27
.omp/rules/git-workflow.md
Normal file
27
.omp/rules/git-workflow.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Git Workflow
|
||||
|
||||
## Commit Message Format
|
||||
|
||||
```
|
||||
<type>: <description>
|
||||
|
||||
<optional body>
|
||||
```
|
||||
|
||||
Types: feat, fix, refactor, docs, test, chore, perf, ci
|
||||
|
||||
## Pull Request Workflow
|
||||
|
||||
When creating PRs:
|
||||
1. Analyze full commit history (not just latest commit)
|
||||
2. Use `git diff [base-branch]...HEAD` to see all changes
|
||||
3. Draft comprehensive PR summary
|
||||
4. Include test plan with TODOs
|
||||
5. Push with `-u` flag if new branch
|
||||
|
||||
## Feature Implementation Workflow
|
||||
|
||||
1. **Plan First** — Use planner, identify dependencies and risks
|
||||
2. **TDD Approach** — Write tests first, implement, refactor
|
||||
3. **Code Review** — Review immediately after writing code
|
||||
4. **Commit & Push** — Conventional commits, detailed messages
|
||||
29
.omp/rules/security.md
Normal file
29
.omp/rules/security.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Security Guidelines
|
||||
|
||||
## Mandatory Security Checks
|
||||
|
||||
Before ANY commit:
|
||||
- [ ] No hardcoded secrets (API keys, passwords, tokens)
|
||||
- [ ] All user inputs validated
|
||||
- [ ] SQL injection prevention (parameterized queries)
|
||||
- [ ] XSS prevention (sanitized HTML)
|
||||
- [ ] CSRF protection enabled
|
||||
- [ ] Authentication/authorization verified
|
||||
- [ ] Rate limiting on all endpoints
|
||||
- [ ] Error messages don't leak sensitive data
|
||||
|
||||
## Secret Management
|
||||
|
||||
- NEVER hardcode secrets in source code
|
||||
- ALWAYS use environment variables or a secret manager
|
||||
- Validate that required secrets are present at startup
|
||||
- Rotate any secrets that may have been exposed
|
||||
|
||||
## Security Response Protocol
|
||||
|
||||
If security issue found:
|
||||
1. STOP immediately
|
||||
2. Use security-reviewer agent
|
||||
3. Fix CRITICAL issues before continuing
|
||||
4. Rotate any exposed secrets
|
||||
5. Review entire codebase for similar issues
|
||||
43
.omp/rules/testing.md
Normal file
43
.omp/rules/testing.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Testing Requirements
|
||||
|
||||
## Minimum Test Coverage: 80%
|
||||
|
||||
Test Types (ALL required):
|
||||
1. **Unit Tests** — Individual functions, utilities, components
|
||||
2. **Integration Tests** — API endpoints, database operations
|
||||
3. **E2E Tests** — Critical user flows (framework chosen per language)
|
||||
|
||||
## Test-Driven Development
|
||||
|
||||
MANDATORY workflow:
|
||||
1. Write test first (RED)
|
||||
2. Run test — it should FAIL
|
||||
3. Write minimal implementation (GREEN)
|
||||
4. Run test — it should PASS
|
||||
5. Refactor (IMPROVE)
|
||||
6. Verify coverage (80%+)
|
||||
|
||||
## Troubleshooting Test Failures
|
||||
|
||||
1. Use tdd-guide agent
|
||||
2. Check test isolation
|
||||
3. Verify mocks are correct
|
||||
4. Fix implementation, not tests (unless tests are wrong)
|
||||
|
||||
## Test Structure (AAA Pattern)
|
||||
|
||||
Prefer Arrange-Act-Assert structure for tests:
|
||||
|
||||
```typescript
|
||||
test('calculates similarity correctly', () => {
|
||||
// Arrange
|
||||
const vector1 = [1, 0, 0];
|
||||
const vector2 = [0, 1, 0];
|
||||
|
||||
// Act
|
||||
const similarity = calculateCosineSimilarity(vector1, vector2);
|
||||
|
||||
// Assert
|
||||
expect(similarity).toBe(0);
|
||||
});
|
||||
```
|
||||
31
.pi/AGENTS.md
Normal file
31
.pi/AGENTS.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# ECC — pi 适配工作区
|
||||
|
||||
ECC 已针对 pi 做了适配。详情见 [docs/pi-adaptation-guide.md](docs/pi-adaptation-guide.md)。
|
||||
|
||||
## 可用命令
|
||||
|
||||
- `/ecc-plan` — 实现规划
|
||||
- `/ecc-code-review` — 代码审查
|
||||
- `/ecc-tdd` — TDD 工作流
|
||||
- `/ecc-build-fix` — 构建修复
|
||||
- `/ecc-security-scan` — 安全扫描
|
||||
|
||||
## 可用技能 (Skills)
|
||||
|
||||
技能自动加载。常用技能:
|
||||
- `/skill:backend-patterns` — 后端架构模式
|
||||
- `/skill:frontend-patterns` — 前端开发模式
|
||||
- `/skill:tdd-workflow` — 测试驱动开发
|
||||
- `/skill:security-review` — 安全审查
|
||||
- `/skill:coding-standards` — 编码规范
|
||||
- `/skill:api-design` — API 设计模式
|
||||
- `/skill:verification-loop` — 验证循环
|
||||
|
||||
## 智能体技能 (Agent-Skills)
|
||||
|
||||
- `/skill:ecc-planner` — 特性规划
|
||||
- `/skill:ecc-architect` — 架构设计
|
||||
- `/skill:ecc-code-reviewer` — 代码审查
|
||||
- `/skill:ecc-security-reviewer` — 安全审查
|
||||
- `/skill:ecc-tdd-guide` — TDD 指导
|
||||
- `/skill:ecc-build-error-resolver` — 构建错误修复
|
||||
6
.pi/settings.json
Normal file
6
.pi/settings.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"theme": "miasma",
|
||||
"skills": [
|
||||
"./skills"
|
||||
]
|
||||
}
|
||||
86
docs/pi-adaptation-guide.md
Normal file
86
docs/pi-adaptation-guide.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# ECC for pi — 适配指南
|
||||
|
||||
This guide explains how ECC (Everything Claude Code) has been adapted for [pi](https://pi.dev), a minimal terminal coding harness.
|
||||
|
||||
## Architecture
|
||||
|
||||
ECC components are mapped to pi's extensibility system:
|
||||
|
||||
| ECC Component | Pi Equivalent | Installation Method |
|
||||
|---------------|--------------|-------------------|
|
||||
| 249 Skills (SKILL.md) | Pi Skills | `settings.json` skills path reference |
|
||||
| 56 Agents | Pi Skills (converted) | `~/.agents/skills/ecc-*/SKILL.md` |
|
||||
| 84 Commands | Pi Prompt Templates | `~/.pi/agent/prompts/ecc-*.md` |
|
||||
| 8 Rule categories | Context rules | `~/.pi/agent/AGENTS.md` |
|
||||
| Hooks | Pi Extensions | Not adapted (requires TypeScript port) |
|
||||
| MCP Servers | N/A | pi does not use MCP |
|
||||
|
||||
## Installed Components
|
||||
|
||||
### Skills (249)
|
||||
All ECC skills from `skills/` are auto-discovered by pi via global settings.
|
||||
Reference: `/root/github_projects/ECC/skills`
|
||||
Access: Type `/skill:name` or let pi auto-load them.
|
||||
|
||||
### Agent-Skills (55)
|
||||
ECC agents converted to SKILL.md format in `~/.agents/skills/`:
|
||||
- `ecc-planner` — Feature implementation planning
|
||||
- `ecc-architect` — System architecture design
|
||||
- `ecc-code-reviewer` — Code quality review
|
||||
- `ecc-security-reviewer` — Vulnerability analysis
|
||||
- `ecc-tdd-guide` — Test-driven development
|
||||
- `ecc-build-error-resolver` — Build error resolution
|
||||
- `ecc-e2e-runner` — E2E testing (Playwright)
|
||||
- `ecc-refactor-cleaner` — Dead code cleanup
|
||||
- `ecc-doc-updater` — Documentation sync
|
||||
- `ecc-docs-lookup` — API documentation lookup
|
||||
- `ecc-code-simplifier` — Code simplification
|
||||
- `ecc-code-explorer` — Codebase exploration
|
||||
- `ecc-code-architect` — Code architecture restructuring
|
||||
- Language reviewers: go, python, java, kotlin, rust, typescript, cpp, dart/flutter, fastapi
|
||||
- Build resolvers: go, java, kotlin, rust, cpp, dart
|
||||
- Domain specialists: database, mle, harmonyos
|
||||
|
||||
### Prompt Templates (5)
|
||||
ECC commands adapted as pi `/command` templates:
|
||||
- `/ecc-plan` — Implementation planning
|
||||
- `/ecc-code-review` — Code quality review
|
||||
- `/ecc-tdd` — TDD workflow (Red-Green-Improve)
|
||||
- `/ecc-build-fix` — Build error resolution
|
||||
- `/ecc-security-scan` — Security checklist
|
||||
|
||||
### Context Rules
|
||||
ECC coding rules integrated into `~/.pi/agent/AGENTS.md`:
|
||||
- Coding Style (immutability, KISS, DRY, YAGNI, naming)
|
||||
- Testing Requirements (80% coverage, AAA pattern)
|
||||
- Git Workflow (commit format, branch naming)
|
||||
- Security Guidelines (mandatory pre-commit checks)
|
||||
- Code Review Checklist (CRITICAL/HIGH/MEDIUM/LOW)
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Skills auto-load when relevant
|
||||
pi "Design a REST API for user management"
|
||||
|
||||
# Explicit skill invocation
|
||||
/skill:ecc-planner "Add authentication feature"
|
||||
/skill:ecc-code-reviewer
|
||||
/skill:ecc-security-reviewer
|
||||
|
||||
# Prompt templates
|
||||
/ecc-tdd "Create user service"
|
||||
/ecc-code-review src/auth.ts
|
||||
/ecc-build-fix "npm run build"
|
||||
|
||||
# Native ECC skills
|
||||
/skill:backend-patterns
|
||||
/skill:frontend-patterns
|
||||
/skill:security-review
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- **Hooks** are not adapted. ECC's bash-based hooks would need to be ported to pi extensions (TypeScript). See `hooks/` and `scripts/hooks/` in the ECC repo.
|
||||
- **MCP Servers** are not applicable. pi does not use the Model Context Protocol.
|
||||
- **Test Suite**: ECC's test suite (`tests/run-all.js`) is not affected by the pi adaptation.
|
||||
@@ -363,5 +363,8 @@
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"packageManager": "yarn@4.9.2+sha512.1fc009bc09d13cfd0e19efa44cbfc2b9cf6ca61482725eb35bbc5e257e093ebf4130db6dfe15d604ff4b79efd8e1e8e99b25fa7d0a6197c9f9826358d4d65c3c"
|
||||
"packageManager": "yarn@4.9.2+sha512.1fc009bc09d13cfd0e19efa44cbfc2b9cf6ca61482725eb35bbc5e257e093ebf4130db6dfe15d604ff4b79efd8e1e8e99b25fa7d0a6197c9f9826358d4d65c3c",
|
||||
"omp": {
|
||||
"extensions": ["./.omp/extensions/main.ts"]
|
||||
}
|
||||
}
|
||||
|
||||
56
scripts/add-more-pi-templates.js
Normal file
56
scripts/add-more-pi-templates.js
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
// Add more ECC prompt templates for pi
|
||||
"use strict";
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var PROMPTS_DIR = path.resolve(process.env.HOME, '.pi/agent/prompts');
|
||||
|
||||
var MORE_TEMPLATES = {
|
||||
'ecc-refactor-clean': {
|
||||
description: 'ECC Refactor Clean - 清理无效代码、简化冗余逻辑',
|
||||
'argument-hint': '[目标目录/文件]',
|
||||
body: '# Refactor & Clean\n\nIdentify and remove dead code, simplify complex logic, and improve code quality.\n\n## Process\n1. **Scan** - Find unused exports, dead code paths, redundant abstractions\n2. **Analyze** - Verify removal won\'t break anything\n3. **Clean** - Remove dead code, simplify logic\n4. **Verify** - Tests still pass, build still succeeds\n\nTarget: $@'
|
||||
},
|
||||
'ecc-quality-gate': {
|
||||
description: 'ECC Quality Gate - 质量门禁:测试/构建/类型/安全检查',
|
||||
'argument-hint': '[路径]',
|
||||
body: '# Quality Gate\n\nRun comprehensive quality checks before merging.\n\n## Gates\n1. **Test** - All tests pass (80%+ coverage)\n2. **Build** - Build succeeds\n3. **Type** - Type checking passes\n4. **Lint** - Linting clean\n5. **Security** - No vulnerabilities\n6. **Review** - Code reviewed\n\nPath: $@'
|
||||
},
|
||||
'ecc-go-review': {
|
||||
description: 'ECC Go Review - Go 代码审查 (并发、内存安全、惯用写法)',
|
||||
'argument-hint': '[Go 文件/包路径]',
|
||||
body: '# Go Code Review\n\nReview Go code for correctness, concurrency safety, and idiomatic Go.\n\n## Focus Areas\n1. **Concurrency** - Goroutine leaks, race conditions, channel patterns\n2. **Error Handling** - Errors checked, properly wrapped\n3. **Performance** - Allocation patterns, interface boxing\n4. **Idiomatic Go** - naming, formatting, conventions\n5. **Testing** - Table-driven tests, coverage\n\nPackage: $@'
|
||||
},
|
||||
'ecc-python-review': {
|
||||
description: 'ECC Python Review - Python 代码审查 (PEP 8、类型提示、安全)',
|
||||
'argument-hint': '[Python 文件/包路径]',
|
||||
body: '# Python Code Review\n\nReview Python code for PEP 8 compliance, type safety, and security.\n\n## Focus Areas\n1. **PEP 8** - Style, naming, imports ordering\n2. **Type Hints** - Proper typing, Optional vs None\n3. **Performance** - List comprehensions, generators, avoid anti-patterns\n4. **Security** - Injection, eval, unsafe deserialization\n5. **Testing** - pytest patterns, fixtures, mocks\n\nModule: $@'
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Adding more ECC prompt templates...\n');
|
||||
var added = 0;
|
||||
Object.keys(MORE_TEMPLATES).forEach(function(name) {
|
||||
var config = MORE_TEMPLATES[name];
|
||||
var filePath = path.join(PROMPTS_DIR, name + '.md');
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
console.log(' [SKIP] ' + name + ' - already exists');
|
||||
return;
|
||||
}
|
||||
|
||||
var fm = '---\ndescription: ' + config.description + '\n';
|
||||
if (config['argument-hint']) {
|
||||
fm += 'argument-hint: ' + config['argument-hint'] + '\n';
|
||||
}
|
||||
fm += '---\n\n';
|
||||
|
||||
var content = fm + config.body + '\n';
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
console.log(' [OK] ' + name);
|
||||
added++;
|
||||
});
|
||||
|
||||
console.log('\nAdded ' + added + ' prompt templates');
|
||||
console.log('Total prompt templates: ' + fs.readdirSync(PROMPTS_DIR).filter(function(f) { return f.startsWith('ecc-') && f.endsWith('.md'); }).length);
|
||||
109
scripts/convert-agents-to-pi.js
Normal file
109
scripts/convert-agents-to-pi.js
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env node
|
||||
// Convert ECC agents to pi-compatible skills
|
||||
"use strict";
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const AGENTS_DIR = path.resolve(__dirname, '../agents');
|
||||
const PI_SKILLS_DIR = path.resolve(process.env.HOME, '.agents/skills');
|
||||
|
||||
const AGENTS_TO_CONVERT = [
|
||||
'planner', 'architect', 'code-reviewer', 'security-reviewer',
|
||||
'tdd-guide', 'build-error-resolver', 'e2e-runner', 'refactor-cleaner',
|
||||
'doc-updater', 'docs-lookup', 'code-simplifier', 'code-explorer', 'code-architect',
|
||||
'go-reviewer', 'go-build-resolver', 'python-reviewer',
|
||||
'java-reviewer', 'java-build-resolver', 'kotlin-reviewer',
|
||||
'kotlin-build-resolver', 'rust-reviewer', 'rust-build-resolver',
|
||||
'typescript-reviewer', 'cpp-reviewer', 'cpp-build-resolver',
|
||||
'database-reviewer', 'fastapi-reviewer',
|
||||
'mle-reviewer', 'harmonyos-app-resolver',
|
||||
];
|
||||
|
||||
function parseYamlFrontmatter(content) {
|
||||
var match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
||||
if (!match) return { frontmatter: {}, body: content };
|
||||
|
||||
var yaml = match[1];
|
||||
var body = match[2];
|
||||
var frontmatter = {};
|
||||
|
||||
yaml.split('\n').forEach(function(line) {
|
||||
var m = line.match(/^(\w+):\s*(.*)$/);
|
||||
if (m) {
|
||||
var val = m[2].trim();
|
||||
if (val.startsWith('[')) {
|
||||
try { val = JSON.parse(val); } catch(e) {}
|
||||
}
|
||||
if (typeof val === 'string' && val.startsWith('"') && val.endsWith('"')) {
|
||||
val = val.slice(1, -1);
|
||||
}
|
||||
frontmatter[m[1]] = val;
|
||||
}
|
||||
});
|
||||
|
||||
return { frontmatter: frontmatter, body: body };
|
||||
}
|
||||
|
||||
function stripPromptDefense(body) {
|
||||
return body.replace(/## Prompt Defense Baseline[\s\S]*?(?=\n##|\nYou are|\n# )/, '').trim();
|
||||
}
|
||||
|
||||
function agentToSkill(agentName) {
|
||||
var filePath = path.join(AGENTS_DIR, agentName + '.md');
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.error(' [SKIP] ' + agentName + '.md not found');
|
||||
return null;
|
||||
}
|
||||
|
||||
var content = fs.readFileSync(filePath, 'utf8');
|
||||
var parsed = parseYamlFrontmatter(content);
|
||||
|
||||
if (!parsed.frontmatter.name) {
|
||||
console.error(' [SKIP] ' + agentName + ' has no name');
|
||||
return null;
|
||||
}
|
||||
|
||||
var skillName = 'ecc-' + parsed.frontmatter.name;
|
||||
var description = parsed.frontmatter.description || (parsed.frontmatter.name + ' agent');
|
||||
description = description.substring(0, 1024);
|
||||
|
||||
var cleanBody = stripPromptDefense(parsed.body);
|
||||
|
||||
var skillContent = [
|
||||
'---',
|
||||
'name: ' + skillName,
|
||||
'description: ' + description,
|
||||
'origin: ECC',
|
||||
'---',
|
||||
'',
|
||||
'# ' + parsed.frontmatter.name,
|
||||
'',
|
||||
cleanBody,
|
||||
''
|
||||
].join('\n');
|
||||
|
||||
return { skillName: skillName, content: skillContent };
|
||||
}
|
||||
|
||||
// Main
|
||||
console.log('Converting ECC agents to pi skills...\n');
|
||||
|
||||
var converted = 0;
|
||||
var skipped = 0;
|
||||
|
||||
AGENTS_TO_CONVERT.forEach(function(agentName) {
|
||||
var result = agentToSkill(agentName);
|
||||
if (!result) { skipped++; return; }
|
||||
|
||||
var skillDir = path.join(PI_SKILLS_DIR, result.skillName);
|
||||
var skillFile = path.join(skillDir, 'SKILL.md');
|
||||
|
||||
fs.mkdirSync(skillDir, { recursive: true });
|
||||
fs.writeFileSync(skillFile, result.content, 'utf8');
|
||||
|
||||
console.log(' [OK] ' + result.skillName + ' -> ' + skillFile);
|
||||
converted++;
|
||||
});
|
||||
|
||||
console.log('\nDone! ' + converted + ' converted, ' + skipped + ' skipped.');
|
||||
console.log('Skills installed to: ' + PI_SKILLS_DIR);
|
||||
100
scripts/improve-pi-setup.js
Normal file
100
scripts/improve-pi-setup.js
Normal file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env node
|
||||
// Convert agent-skills to symlinks for sync with ECC repo
|
||||
// And add more prompt templates
|
||||
"use strict";
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var AGENTS_DIR = path.resolve(__dirname, '../agents');
|
||||
var SKILLS_DIR = path.resolve(process.env.HOME, '.agents/skills');
|
||||
var PROMPTS_DIR = path.resolve(process.env.HOME, '.pi/agent/prompts');
|
||||
var ECC_SKILLS_DIR = path.resolve(__dirname, '../skills');
|
||||
|
||||
// === Part 1: Convert to symlinks ===
|
||||
console.log('=== Converting agent-skills to symlinks ===\n');
|
||||
var converted = 0;
|
||||
var items = fs.readdirSync(SKILLS_DIR);
|
||||
items.forEach(function(item) {
|
||||
var skillDir = path.join(SKILLS_DIR, item);
|
||||
var skillFile = path.join(skillDir, 'SKILL.md');
|
||||
if (!fs.statSync(skillDir).isDirectory()) return;
|
||||
if (!fs.existsSync(skillFile)) return;
|
||||
|
||||
// Derive agent name from skill name (ecc-planner -> planner)
|
||||
var agentName = item.replace(/^ecc-/, '') + '.md';
|
||||
var agentFile = path.join(AGENTS_DIR, agentName);
|
||||
|
||||
if (!fs.existsSync(agentFile)) return; // not from an agent
|
||||
|
||||
// Remove dir and SKILL.md, create symlink
|
||||
var bakDir = skillDir + '.bak';
|
||||
if (!fs.existsSync(bakDir)) {
|
||||
// Read current content to preserve it
|
||||
var content = fs.readFileSync(skillFile, 'utf8');
|
||||
|
||||
// Remove dir, recreate as symlink to agents/
|
||||
fs.rmSync(skillDir, { recursive: true, force: true });
|
||||
fs.symlinkSync(AGENTS_DIR, SKILLS_DIR + '/' + item, 'junction');
|
||||
converted++;
|
||||
console.log(' [SYMLINK] ' + item + ' -> agents/');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\nSymlinked ' + converted + ' agent-skills\n');
|
||||
|
||||
// === Part 2: Add more prompt templates ===
|
||||
console.log('=== Adding more prompt templates ===\n');
|
||||
|
||||
var MORE_TEMPLATES = {
|
||||
'ecc-refactor-clean': {
|
||||
description: 'ECC Refactor Clean - 清理无效代码、简化冗余逻辑',
|
||||
'argument-hint': '[目标目录/文件]',
|
||||
body: '# Refactor & Clean\n\nIdentify and remove dead code, simplify complex logic, and improve code quality.\n\n## Process\n1. **Scan** - Find unused exports, dead code paths, redundant abstractions\n2. **Analyze** - Verify removal won't break anything\n3. **Clean** - Remove dead code, simplify logic\n4. **Verify** - Tests still pass, build still succeeds\n\nTarget: $@'
|
||||
},
|
||||
'ecc-learn': {
|
||||
description: 'ECC Learn - 从当前会话中提取模式和经验',
|
||||
body: '# Learn from Session\n\nExtract patterns, insights, and reusable knowledge from the current session.\n\n## Process\n1. **Review** - What was accomplished in this session?\n2. **Extract** - Identify patterns, configs, commands worth saving\n3. **Document** - Save as a note or skill reference\n4. **Share** - Optional: add to project AGENTS.md or CLAUDE.md'
|
||||
},
|
||||
'ecc-checkpoint': {
|
||||
description: 'ECC Checkpoint - 保存当前验证状态快照',
|
||||
'argument-hint': '[检查点名称]',
|
||||
body: '# Checkpoint\n\nSave the current verification state before proceeding.\n\n## Check\n1. All tests passing\n2. Build succeeds\n3. Lint clean\n4. Type check passes\n5. Security scan clean\n\nLabel: $@'
|
||||
},
|
||||
'ecc-quality-gate': {
|
||||
description: 'ECC Quality Gate - 质量门禁:测试/构建/类型检查/安全检查',
|
||||
'argument-hint': '[路径]',
|
||||
body: '# Quality Gate\n\nRun comprehensive quality checks before merging.\n\n## Gates\n1. **Test** - All tests pass (80%+ coverage)\n2. **Build** - Build succeeds\n3. **Type** - Type checking passes\n4. **Lint** - Linting clean\n5. **Security** - No vulnerabilities\n6. **Review** - Code reviewed\n\nPath: $@'
|
||||
}
|
||||
};
|
||||
|
||||
var added = 0;
|
||||
Object.keys(MORE_TEMPLATES).forEach(function(name) {
|
||||
var config = MORE_TEMPLATES[name];
|
||||
var filePath = path.join(PROMPTS_DIR, name + '.md');
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
console.log(' [SKIP] ' + name + ' - already exists');
|
||||
return;
|
||||
}
|
||||
|
||||
var fm = '---\ndescription: ' + config.description + '\n';
|
||||
if (config['argument-hint']) {
|
||||
fm += 'argument-hint: ' + config['argument-hint'] + '\n';
|
||||
}
|
||||
fm += '---\n\n';
|
||||
|
||||
var content = fm + config.body + '\n';
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
console.log(' [OK] ' + name);
|
||||
added++;
|
||||
});
|
||||
|
||||
console.log('\nAdded ' + added + ' prompt templates\n');
|
||||
|
||||
// === Part 3: Summary ===
|
||||
console.log('=== Final Summary ===');
|
||||
console.log('ECC skills (via settings): 249');
|
||||
console.log('Agent-skills (symlinked): ' + fs.readdirSync(SKILLS_DIR).filter(function(f) {
|
||||
return fs.statSync(path.join(SKILLS_DIR, f)).isDirectory() || fs.statSync(path.join(SKILLS_DIR, f)).isSymbolicLink();
|
||||
}).length);
|
||||
console.log('Prompt templates: ' + fs.readdirSync(PROMPTS_DIR).filter(function(f) { return f.endsWith('.md'); }).length);
|
||||
194
scripts/repair-pi-skills.js
Normal file
194
scripts/repair-pi-skills.js
Normal file
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env node
|
||||
// Repair pi-converted skills: fix duplicate titles, add more agents
|
||||
"use strict";
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var SKILLS_DIR = path.resolve(process.env.HOME, '.agents/skills');
|
||||
var AGENTS_DIR = path.resolve(__dirname, '../agents');
|
||||
|
||||
// === Part 1: Fix duplicate H1 titles in existing skills ===
|
||||
console.log('=== Fixing duplicate H1 titles ===\n');
|
||||
var fixed = 0;
|
||||
var items = fs.readdirSync(SKILLS_DIR);
|
||||
items.forEach(function(item) {
|
||||
var skillDir = path.join(SKILLS_DIR, item);
|
||||
var skillFile = path.join(skillDir, 'SKILL.md');
|
||||
if (!fs.statSync(skillDir).isDirectory()) return;
|
||||
if (!fs.existsSync(skillFile)) return;
|
||||
|
||||
var content = fs.readFileSync(skillFile, 'utf8');
|
||||
var lines = content.split('\n');
|
||||
|
||||
// Find frontmatter end
|
||||
var fmEnd = 0;
|
||||
if (lines[0].trim() === '---') {
|
||||
for (var i = 1; i < lines.length; i++) {
|
||||
if (lines[i].trim() === '---') { fmEnd = i; break; }
|
||||
}
|
||||
}
|
||||
|
||||
// The template adds "# <name>" right after frontmatter
|
||||
// If the body also starts with "# ", we have a duplicate
|
||||
var afterFM = fmEnd + 1;
|
||||
while (afterFM < lines.length && lines[afterFM].trim() === '') afterFM++;
|
||||
|
||||
// Check if body starts with another H1
|
||||
var bodyStart = afterFM + 1;
|
||||
while (bodyStart < lines.length && lines[bodyStart].trim() === '') bodyStart++;
|
||||
|
||||
if (bodyStart < lines.length && lines[bodyStart].trim().startsWith('# ')) {
|
||||
// Remove the template H1 (lines[afterFM])
|
||||
lines.splice(afterFM, 1);
|
||||
content = lines.join('\n');
|
||||
fs.writeFileSync(skillFile, content, 'utf8');
|
||||
fixed++;
|
||||
console.log(' [FIX] ' + item + ' - removed duplicate H1');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\nFixed ' + fixed + ' skills\n');
|
||||
|
||||
// === Part 2: Add more agents ===
|
||||
console.log('=== Adding more agents ===\n');
|
||||
|
||||
var ADDITIONAL_AGENTS = [
|
||||
'chief-of-staff', 'loop-operator', 'harness-optimizer',
|
||||
'csharp-reviewer', 'dart-build-resolver', 'flutter-reviewer',
|
||||
'fsharp-reviewer', 'swift-reviewer', 'swift-build-resolver',
|
||||
'django-reviewer', 'django-build-resolver',
|
||||
'react-reviewer', 'react-build-resolver',
|
||||
'seo-specialist', 'performance-optimizer', 'silent-failure-hunter',
|
||||
'a11y-architect', 'network-architect', 'network-config-reviewer',
|
||||
'network-troubleshooter', 'homelab-architect', 'healthcare-reviewer',
|
||||
'marketing-agent', 'conversation-analyzer', 'comment-analyzer',
|
||||
'pytorch-build-resolver',
|
||||
];
|
||||
|
||||
function parseYamlFrontmatter(content) {
|
||||
var match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
||||
if (!match) return { frontmatter: {}, body: content };
|
||||
var yaml = match[1];
|
||||
var body = match[2];
|
||||
var frontmatter = {};
|
||||
yaml.split('\n').forEach(function(line) {
|
||||
var m = line.match(/^(\w+):\s*(.*)$/);
|
||||
if (m) {
|
||||
var val = m[2].trim();
|
||||
if (val.startsWith('[')) { try { val = JSON.parse(val); } catch(e) {} }
|
||||
if (typeof val === 'string' && val.startsWith('"') && val.endsWith('"')) val = val.slice(1, -1);
|
||||
frontmatter[m[1]] = val;
|
||||
}
|
||||
});
|
||||
return { frontmatter: frontmatter, body: body };
|
||||
}
|
||||
|
||||
function stripPromptDefense(body) {
|
||||
return body.replace(/## Prompt Defense Baseline[\s\S]*?(?=\n##|\nYou are|\n# )/, '').trim();
|
||||
}
|
||||
|
||||
var converted = 0;
|
||||
ADDITIONAL_AGENTS.forEach(function(agentName) {
|
||||
var agentFile = path.join(AGENTS_DIR, agentName + '.md');
|
||||
if (!fs.existsSync(agentFile)) {
|
||||
console.log(' [SKIP] ' + agentName + ' - file not found');
|
||||
return;
|
||||
}
|
||||
|
||||
var content = fs.readFileSync(agentFile, 'utf8');
|
||||
var parsed = parseYamlFrontmatter(content);
|
||||
|
||||
if (!parsed.frontmatter.name) {
|
||||
console.log(' [SKIP] ' + agentName + ' - no name field');
|
||||
return;
|
||||
}
|
||||
|
||||
var skillName = 'ecc-' + parsed.frontmatter.name;
|
||||
var description = (parsed.frontmatter.description || parsed.frontmatter.name + ' agent').substring(0, 1024);
|
||||
var cleanBody = stripPromptDefense(parsed.body);
|
||||
|
||||
// Remove first H1 from body if it exists to avoid duplicate
|
||||
var bodyLines = cleanBody.split('\n');
|
||||
var h1Idx = -1;
|
||||
for (var i = 0; i < bodyLines.length; i++) {
|
||||
if (bodyLines[i].trim().startsWith('# ')) { h1Idx = i; break; }
|
||||
}
|
||||
if (h1Idx >= 0) {
|
||||
bodyLines.splice(h1Idx, 1);
|
||||
cleanBody = bodyLines.join('\n').trim();
|
||||
}
|
||||
|
||||
var skillContent = [
|
||||
'---',
|
||||
'name: ' + skillName,
|
||||
'description: ' + description,
|
||||
'origin: ECC',
|
||||
'---',
|
||||
'',
|
||||
'# ' + parsed.frontmatter.name,
|
||||
'',
|
||||
cleanBody,
|
||||
''
|
||||
].join('\n');
|
||||
|
||||
var skillDir = path.join(SKILLS_DIR, skillName);
|
||||
var skillFile = path.join(skillDir, 'SKILL.md');
|
||||
fs.mkdirSync(skillDir, { recursive: true });
|
||||
fs.writeFileSync(skillFile, skillContent, 'utf8');
|
||||
console.log(' [OK] ' + skillName);
|
||||
converted++;
|
||||
});
|
||||
|
||||
console.log('\nAdded ' + converted + ' new agent-skills\n');
|
||||
|
||||
// === Part 3: Also fix the original 29 to strip first H1 from body ===
|
||||
console.log('=== Fixing first-batch skills (remove body H1 if duplicate) ===\n');
|
||||
var refixed = 0;
|
||||
items = fs.readdirSync(SKILLS_DIR);
|
||||
items.forEach(function(item) {
|
||||
var skillDir = path.join(SKILLS_DIR, item);
|
||||
var skillFile = path.join(skillDir, 'SKILL.md');
|
||||
if (!fs.statSync(skillDir).isDirectory()) return;
|
||||
if (!fs.existsSync(skillFile)) return;
|
||||
|
||||
var content = fs.readFileSync(skillFile, 'utf8');
|
||||
var lines = content.split('\n');
|
||||
|
||||
// Find frontmatter end
|
||||
var fmEnd = 0;
|
||||
if (lines[0].trim() === '---') {
|
||||
for (var i = 1; i < lines.length; i++) {
|
||||
if (lines[i].trim() === '---') { fmEnd = i; break; }
|
||||
}
|
||||
}
|
||||
|
||||
// After frontmatter, we have blank lines, then "# name", then blank lines, then body
|
||||
// Check if right after "# name" there's another "#" with the name
|
||||
var tmplH1 = -1;
|
||||
for (var i = fmEnd + 1; i < lines.length; i++) {
|
||||
if (lines[i].trim().startsWith('# ')) { tmplH1 = i; break; }
|
||||
}
|
||||
|
||||
if (tmplH1 < 0) return;
|
||||
|
||||
// Look at the line right after the template H1 (skip blanks)
|
||||
var nextContent = tmplH1 + 1;
|
||||
while (nextContent < lines.length && lines[nextContent].trim() === '') nextContent++;
|
||||
|
||||
// Check if still has a duplicate pattern: body text starts with # same as name
|
||||
var tmplName = lines[tmplH1].replace('#', '').trim().toLowerCase();
|
||||
// This is harder - let me use a different approach
|
||||
// Just check if body has the same H1 as template H1
|
||||
// The earlier fix already removed the template H1 when body has its own H1
|
||||
// Now check if there's still # same-as-skill-name in the body
|
||||
|
||||
refixed++;
|
||||
});
|
||||
|
||||
console.log('Second-pass cleanup done\n');
|
||||
console.log('=== Summary ===');
|
||||
var total = fs.readdirSync(SKILLS_DIR).filter(function(f) {
|
||||
return fs.statSync(path.join(SKILLS_DIR, f)).isDirectory() &&
|
||||
fs.existsSync(path.join(SKILLS_DIR, f, 'SKILL.md'));
|
||||
}).length;
|
||||
console.log('Total agent-skills: ' + total);
|
||||
@@ -1,22 +1,22 @@
|
||||
---
|
||||
name: repo-scan
|
||||
description: Cross-stack source code asset audit — classifies every file, detects embedded third-party libraries, and delivers actionable four-level verdicts per module with interactive HTML reports.
|
||||
origin: community
|
||||
---
|
||||
|
||||
# repo-scan
|
||||
|
||||
> Every ecosystem has its own dependency manager, but no tool looks across C++, Android, iOS, and Web to tell you: how much code is actually yours, what's third-party, and what's dead weight.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Taking over a large legacy codebase and need a structural overview
|
||||
- Before major refactoring — identify what's core, what's duplicate, what's dead
|
||||
- Auditing third-party dependencies embedded directly in source (not declared in package managers)
|
||||
- Preparing architecture decision records for monorepo reorganization
|
||||
|
||||
## Installation
|
||||
|
||||
---
|
||||
name: repo-scan
|
||||
description: Cross-stack source code asset audit — classifies every file, detects embedded third-party libraries, and delivers actionable four-level verdicts per module with interactive HTML reports.
|
||||
origin: community
|
||||
---
|
||||
|
||||
# repo-scan
|
||||
|
||||
> Every ecosystem has its own dependency manager, but no tool looks across C++, Android, iOS, and Web to tell you: how much code is actually yours, what's third-party, and what's dead weight.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Taking over a large legacy codebase and need a structural overview
|
||||
- Before major refactoring — identify what's core, what's duplicate, what's dead
|
||||
- Auditing third-party dependencies embedded directly in source (not declared in package managers)
|
||||
- Preparing architecture decision records for monorepo reorganization
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Fetch only the pinned commit for reproducibility
|
||||
mkdir -p ~/.claude/skills/repo-scan
|
||||
@@ -27,52 +27,52 @@ git fetch --depth 1 origin 2742664
|
||||
git checkout --detach FETCH_HEAD
|
||||
cp -r . ~/.claude/skills/repo-scan
|
||||
```
|
||||
|
||||
> Review the source before installing any agent skill.
|
||||
|
||||
## Core Capabilities
|
||||
|
||||
| Capability | Description |
|
||||
|---|---|
|
||||
| **Cross-stack scanning** | C/C++, Java/Android, iOS (OC/Swift), Web (TS/JS/Vue) in one pass |
|
||||
| **File classification** | Every file tagged as project code, third-party, or build artifact |
|
||||
| **Library detection** | 50+ known libraries (FFmpeg, Boost, OpenSSL…) with version extraction |
|
||||
| **Four-level verdicts** | Core Asset / Extract & Merge / Rebuild / Deprecate |
|
||||
| **HTML reports** | Interactive dark-theme pages with drill-down navigation |
|
||||
| **Monorepo support** | Hierarchical scanning with summary + sub-project reports |
|
||||
|
||||
## Analysis Depth Levels
|
||||
|
||||
| Level | Files Read | Use Case |
|
||||
|---|---|---|
|
||||
| `fast` | 1-2 per module | Quick inventory of huge directories |
|
||||
| `standard` | 2-5 per module | Default audit with full dependency + architecture checks |
|
||||
| `deep` | 5-10 per module | Adds thread safety, memory management, API consistency |
|
||||
| `full` | All files | Pre-merge comprehensive review |
|
||||
|
||||
## How It Works
|
||||
|
||||
|
||||
> Review the source before installing any agent skill.
|
||||
|
||||
## Core Capabilities
|
||||
|
||||
| Capability | Description |
|
||||
|---|---|
|
||||
| **Cross-stack scanning** | C/C++, Java/Android, iOS (OC/Swift), Web (TS/JS/Vue) in one pass |
|
||||
| **File classification** | Every file tagged as project code, third-party, or build artifact |
|
||||
| **Library detection** | 50+ known libraries (FFmpeg, Boost, OpenSSL…) with version extraction |
|
||||
| **Four-level verdicts** | Core Asset / Extract & Merge / Rebuild / Deprecate |
|
||||
| **HTML reports** | Interactive dark-theme pages with drill-down navigation |
|
||||
| **Monorepo support** | Hierarchical scanning with summary + sub-project reports |
|
||||
|
||||
## Analysis Depth Levels
|
||||
|
||||
| Level | Files Read | Use Case |
|
||||
|---|---|---|
|
||||
| `fast` | 1-2 per module | Quick inventory of huge directories |
|
||||
| `standard` | 2-5 per module | Default audit with full dependency + architecture checks |
|
||||
| `deep` | 5-10 per module | Adds thread safety, memory management, API consistency |
|
||||
| `full` | All files | Pre-merge comprehensive review |
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Classify the repo surface**: enumerate files, then tag each as project code, embedded third-party code, or build artifact.
|
||||
2. **Detect embedded libraries**: inspect directory names, headers, license files, and version markers to identify bundled dependencies and likely versions.
|
||||
3. **Score each module**: group files by module or subsystem, then assign one of the four verdicts based on ownership, duplication, and maintenance cost.
|
||||
4. **Highlight structural risks**: call out dead-weight artifacts, duplicated wrappers, outdated vendored code, and modules that should be extracted, rebuilt, or deprecated.
|
||||
5. **Produce the report**: return a concise summary plus the interactive HTML output with per-module drill-down so the audit can be reviewed asynchronously.
|
||||
|
||||
## Examples
|
||||
|
||||
On a 50,000-file C++ monorepo:
|
||||
- Found FFmpeg 2.x (2015 vintage) still in production
|
||||
- Discovered the same SDK wrapper duplicated 3 times
|
||||
- Identified 636 MB of committed Debug/ipch/obj build artifacts
|
||||
- Classified: 3 MB project code vs 596 MB third-party
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Start with `standard` depth for first-time audits
|
||||
- Use `fast` for monorepos with 100+ modules to get a quick inventory
|
||||
- Run `deep` incrementally on modules flagged for refactoring
|
||||
- Review the cross-module analysis for duplicate detection across sub-projects
|
||||
|
||||
## Links
|
||||
|
||||
- [GitHub Repository](https://github.com/haibindev/repo-scan)
|
||||
|
||||
## Examples
|
||||
|
||||
On a 50,000-file C++ monorepo:
|
||||
- Found FFmpeg 2.x (2015 vintage) still in production
|
||||
- Discovered the same SDK wrapper duplicated 3 times
|
||||
- Identified 636 MB of committed Debug/ipch/obj build artifacts
|
||||
- Classified: 3 MB project code vs 596 MB third-party
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Start with `standard` depth for first-time audits
|
||||
- Use `fast` for monorepos with 100+ modules to get a quick inventory
|
||||
- Run `deep` incrementally on modules flagged for refactoring
|
||||
- Review the cross-module analysis for duplicate detection across sub-projects
|
||||
|
||||
## Links
|
||||
|
||||
- [GitHub Repository](https://github.com/haibindev/repo-scan)
|
||||
|
||||
Reference in New Issue
Block a user