@chankov/agent-skills 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/{doctor.md → doctor-agent-skills.md} +1 -1
- package/.pi/extensions/agent-skills-update-check/README.md +58 -0
- package/.pi/extensions/agent-skills-update-check/index.ts +161 -0
- package/.pi/extensions/agent-skills-update-check/package.json +6 -0
- package/.pi/prompts/{doctor.md → doctor-agent-skills.md} +1 -1
- package/.versions/0.2.0/.claude/commands/build.md +18 -0
- package/.versions/0.2.0/.claude/commands/code-simplify.md +22 -0
- package/.versions/0.2.0/.claude/commands/design-agent.md +14 -0
- package/.versions/0.2.0/.claude/commands/doctor-agent-skills.md +13 -0
- package/.versions/0.2.0/.claude/commands/plan.md +16 -0
- package/.versions/0.2.0/.claude/commands/prime.md +22 -0
- package/.versions/0.2.0/.claude/commands/review.md +16 -0
- package/.versions/0.2.0/.claude/commands/setup-agent-skills.md +19 -0
- package/.versions/0.2.0/.claude/commands/ship.md +17 -0
- package/.versions/0.2.0/.claude/commands/spec.md +15 -0
- package/.versions/0.2.0/.claude/commands/test.md +19 -0
- package/.versions/0.2.0/.opencode/commands/as-build.md +17 -0
- package/.versions/0.2.0/.opencode/commands/as-code-simplify.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-design-agent.md +15 -0
- package/.versions/0.2.0/.opencode/commands/as-doctor-agent-skills.md +11 -0
- package/.versions/0.2.0/.opencode/commands/as-plan.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-prime.md +22 -0
- package/.versions/0.2.0/.opencode/commands/as-review.md +15 -0
- package/.versions/0.2.0/.opencode/commands/as-setup-agent-skills.md +11 -0
- package/.versions/0.2.0/.opencode/commands/as-ship.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-spec.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-test.md +21 -0
- package/.versions/0.2.0/.pi/agents/agent-chain.yaml +49 -0
- package/.versions/0.2.0/.pi/agents/bowser.md +19 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/agent-expert.md +98 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/cli-expert.md +41 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/config-expert.md +63 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/ext-expert.md +43 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/keybinding-expert.md +134 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/pi-orchestrator.md +57 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/prompt-expert.md +70 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/skill-expert.md +42 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/theme-expert.md +40 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/tui-expert.md +85 -0
- package/.versions/0.2.0/.pi/agents/teams.yaml +31 -0
- package/.versions/0.2.0/.pi/damage-control-rules.yaml +278 -0
- package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/README.md +58 -0
- package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/index.ts +161 -0
- package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/README.md +39 -0
- package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/index.ts +61 -0
- package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/compact-and-continue/README.md +42 -0
- package/.versions/0.2.0/.pi/extensions/compact-and-continue/index.ts +120 -0
- package/.versions/0.2.0/.pi/extensions/compact-and-continue/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/mcp-bridge/README.md +46 -0
- package/.versions/0.2.0/.pi/extensions/mcp-bridge/index.ts +206 -0
- package/.versions/0.2.0/.pi/extensions/mcp-bridge/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/package-lock.json +1143 -0
- package/.versions/0.2.0/.pi/extensions/package.json +9 -0
- package/.versions/0.2.0/.pi/harnesses/agent-chain/README.md +37 -0
- package/.versions/0.2.0/.pi/harnesses/agent-chain/index.ts +795 -0
- package/.versions/0.2.0/.pi/harnesses/agent-chain/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/agent-team/README.md +38 -0
- package/.versions/0.2.0/.pi/harnesses/agent-team/index.ts +732 -0
- package/.versions/0.2.0/.pi/harnesses/agent-team/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/coms/README.md +36 -0
- package/.versions/0.2.0/.pi/harnesses/coms/index.ts +1595 -0
- package/.versions/0.2.0/.pi/harnesses/coms/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/coms-net/README.md +46 -0
- package/.versions/0.2.0/.pi/harnesses/coms-net/index.ts +1637 -0
- package/.versions/0.2.0/.pi/harnesses/coms-net/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control/README.md +38 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control/index.ts +207 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control-continue/README.md +37 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control-continue/index.ts +234 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control-continue/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/minimal/README.md +27 -0
- package/.versions/0.2.0/.pi/harnesses/minimal/index.ts +32 -0
- package/.versions/0.2.0/.pi/harnesses/minimal/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/package-lock.json +35 -0
- package/.versions/0.2.0/.pi/harnesses/package.json +9 -0
- package/.versions/0.2.0/.pi/harnesses/pi-pi/README.md +39 -0
- package/.versions/0.2.0/.pi/harnesses/pi-pi/index.ts +631 -0
- package/.versions/0.2.0/.pi/harnesses/pi-pi/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/purpose-gate/README.md +27 -0
- package/.versions/0.2.0/.pi/harnesses/purpose-gate/index.ts +82 -0
- package/.versions/0.2.0/.pi/harnesses/purpose-gate/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/session-replay/README.md +28 -0
- package/.versions/0.2.0/.pi/harnesses/session-replay/index.ts +214 -0
- package/.versions/0.2.0/.pi/harnesses/session-replay/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/subagent-widget/README.md +36 -0
- package/.versions/0.2.0/.pi/harnesses/subagent-widget/index.ts +479 -0
- package/.versions/0.2.0/.pi/harnesses/subagent-widget/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/system-select/README.md +39 -0
- package/.versions/0.2.0/.pi/harnesses/system-select/index.ts +165 -0
- package/.versions/0.2.0/.pi/harnesses/system-select/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/tilldone/README.md +35 -0
- package/.versions/0.2.0/.pi/harnesses/tilldone/index.ts +724 -0
- package/.versions/0.2.0/.pi/harnesses/tilldone/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter/README.md +31 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter/index.ts +100 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/README.md +27 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/index.ts +66 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/package.json +6 -0
- package/.versions/0.2.0/.pi/prompts/build.md +24 -0
- package/.versions/0.2.0/.pi/prompts/code-simplify.md +22 -0
- package/.versions/0.2.0/.pi/prompts/doctor-agent-skills.md +13 -0
- package/.versions/0.2.0/.pi/prompts/plan.md +16 -0
- package/.versions/0.2.0/.pi/prompts/review.md +16 -0
- package/.versions/0.2.0/.pi/prompts/setup-agent-skills.md +19 -0
- package/.versions/0.2.0/.pi/prompts/ship.md +17 -0
- package/.versions/0.2.0/.pi/prompts/spec.md +15 -0
- package/.versions/0.2.0/.pi/prompts/test.md +19 -0
- package/.versions/0.2.0/.pi/skills/bowser/SKILL.md +114 -0
- package/.versions/0.2.0/.version +1 -0
- package/.versions/0.2.0/agents/builder.md +6 -0
- package/.versions/0.2.0/agents/code-reviewer.md +93 -0
- package/.versions/0.2.0/agents/documenter.md +6 -0
- package/.versions/0.2.0/agents/plan-reviewer.md +22 -0
- package/.versions/0.2.0/agents/planner.md +6 -0
- package/.versions/0.2.0/agents/scout.md +6 -0
- package/.versions/0.2.0/agents/security-auditor.md +97 -0
- package/.versions/0.2.0/agents/test-engineer.md +89 -0
- package/.versions/0.2.0/hooks/SIMPLIFY-IGNORE.md +90 -0
- package/.versions/0.2.0/hooks/hooks.json +14 -0
- package/.versions/0.2.0/hooks/session-start.sh +74 -0
- package/.versions/0.2.0/hooks/simplify-ignore-test.sh +247 -0
- package/.versions/0.2.0/hooks/simplify-ignore.sh +302 -0
- package/.versions/0.2.0/references/accessibility-checklist.md +159 -0
- package/.versions/0.2.0/references/performance-checklist.md +121 -0
- package/.versions/0.2.0/references/prompting-patterns.md +380 -0
- package/.versions/0.2.0/references/security-checklist.md +134 -0
- package/.versions/0.2.0/references/testing-patterns.md +236 -0
- package/.versions/0.2.0/skills/api-and-interface-design/SKILL.md +294 -0
- package/.versions/0.2.0/skills/browser-testing-with-devtools/SKILL.md +335 -0
- package/.versions/0.2.0/skills/ci-cd-and-automation/SKILL.md +390 -0
- package/.versions/0.2.0/skills/code-review-and-quality/SKILL.md +347 -0
- package/.versions/0.2.0/skills/code-simplification/SKILL.md +331 -0
- package/.versions/0.2.0/skills/context-engineering/SKILL.md +291 -0
- package/.versions/0.2.0/skills/debugging-and-error-recovery/SKILL.md +300 -0
- package/.versions/0.2.0/skills/deprecation-and-migration/SKILL.md +206 -0
- package/.versions/0.2.0/skills/designing-agents/SKILL.md +394 -0
- package/.versions/0.2.0/skills/designing-agents/pi-harness-authoring.md +213 -0
- package/.versions/0.2.0/skills/documentation-and-adrs/SKILL.md +278 -0
- package/.versions/0.2.0/skills/frontend-ui-engineering/SKILL.md +322 -0
- package/.versions/0.2.0/skills/git-workflow-and-versioning/SKILL.md +316 -0
- package/.versions/0.2.0/skills/guided-workspace-setup/SKILL.md +331 -0
- package/.versions/0.2.0/skills/idea-refine/SKILL.md +178 -0
- package/.versions/0.2.0/skills/idea-refine/examples.md +238 -0
- package/.versions/0.2.0/skills/idea-refine/frameworks.md +99 -0
- package/.versions/0.2.0/skills/idea-refine/refinement-criteria.md +113 -0
- package/.versions/0.2.0/skills/idea-refine/scripts/idea-refine.sh +15 -0
- package/.versions/0.2.0/skills/incremental-implementation/SKILL.md +279 -0
- package/.versions/0.2.0/skills/performance-optimization/SKILL.md +350 -0
- package/.versions/0.2.0/skills/planning-and-task-breakdown/SKILL.md +237 -0
- package/.versions/0.2.0/skills/security-and-hardening/SKILL.md +349 -0
- package/.versions/0.2.0/skills/shipping-and-launch/SKILL.md +309 -0
- package/.versions/0.2.0/skills/source-driven-development/SKILL.md +194 -0
- package/.versions/0.2.0/skills/spec-driven-development/SKILL.md +237 -0
- package/.versions/0.2.0/skills/test-driven-development/SKILL.md +379 -0
- package/.versions/0.2.0/skills/using-agent-skills/SKILL.md +176 -0
- package/.versions/0.3.0/.claude/commands/build.md +18 -0
- package/.versions/0.3.0/.claude/commands/code-simplify.md +22 -0
- package/.versions/0.3.0/.claude/commands/design-agent.md +14 -0
- package/.versions/0.3.0/.claude/commands/doctor-agent-skills.md +13 -0
- package/.versions/0.3.0/.claude/commands/plan.md +16 -0
- package/.versions/0.3.0/.claude/commands/prime.md +22 -0
- package/.versions/0.3.0/.claude/commands/review.md +16 -0
- package/.versions/0.3.0/.claude/commands/setup-agent-skills.md +19 -0
- package/.versions/0.3.0/.claude/commands/ship.md +17 -0
- package/.versions/0.3.0/.claude/commands/spec.md +15 -0
- package/.versions/0.3.0/.claude/commands/test.md +19 -0
- package/.versions/0.3.0/.opencode/commands/as-build.md +17 -0
- package/.versions/0.3.0/.opencode/commands/as-code-simplify.md +16 -0
- package/.versions/0.3.0/.opencode/commands/as-design-agent.md +15 -0
- package/.versions/0.3.0/.opencode/commands/as-doctor-agent-skills.md +11 -0
- package/.versions/0.3.0/.opencode/commands/as-plan.md +16 -0
- package/.versions/0.3.0/.opencode/commands/as-prime.md +22 -0
- package/.versions/0.3.0/.opencode/commands/as-review.md +15 -0
- package/.versions/0.3.0/.opencode/commands/as-setup-agent-skills.md +11 -0
- package/.versions/0.3.0/.opencode/commands/as-ship.md +16 -0
- package/.versions/0.3.0/.opencode/commands/as-spec.md +16 -0
- package/.versions/0.3.0/.opencode/commands/as-test.md +21 -0
- package/.versions/0.3.0/.pi/agents/agent-chain.yaml +49 -0
- package/.versions/0.3.0/.pi/agents/bowser.md +19 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/agent-expert.md +98 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/cli-expert.md +41 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/config-expert.md +63 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/ext-expert.md +43 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/keybinding-expert.md +134 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/pi-orchestrator.md +57 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/prompt-expert.md +70 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/skill-expert.md +42 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/theme-expert.md +40 -0
- package/.versions/0.3.0/.pi/agents/pi-pi/tui-expert.md +85 -0
- package/.versions/0.3.0/.pi/agents/teams.yaml +31 -0
- package/.versions/0.3.0/.pi/damage-control-rules.yaml +278 -0
- package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/README.md +58 -0
- package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/index.ts +161 -0
- package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/package.json +6 -0
- package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/README.md +39 -0
- package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/index.ts +61 -0
- package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/package.json +6 -0
- package/.versions/0.3.0/.pi/extensions/compact-and-continue/README.md +42 -0
- package/.versions/0.3.0/.pi/extensions/compact-and-continue/index.ts +120 -0
- package/.versions/0.3.0/.pi/extensions/compact-and-continue/package.json +6 -0
- package/.versions/0.3.0/.pi/extensions/mcp-bridge/README.md +46 -0
- package/.versions/0.3.0/.pi/extensions/mcp-bridge/index.ts +206 -0
- package/.versions/0.3.0/.pi/extensions/mcp-bridge/package.json +6 -0
- package/.versions/0.3.0/.pi/extensions/package-lock.json +1143 -0
- package/.versions/0.3.0/.pi/extensions/package.json +9 -0
- package/.versions/0.3.0/.pi/harnesses/agent-chain/README.md +37 -0
- package/.versions/0.3.0/.pi/harnesses/agent-chain/index.ts +795 -0
- package/.versions/0.3.0/.pi/harnesses/agent-chain/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/agent-team/README.md +38 -0
- package/.versions/0.3.0/.pi/harnesses/agent-team/index.ts +732 -0
- package/.versions/0.3.0/.pi/harnesses/agent-team/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/coms/README.md +36 -0
- package/.versions/0.3.0/.pi/harnesses/coms/index.ts +1595 -0
- package/.versions/0.3.0/.pi/harnesses/coms/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/coms-net/README.md +46 -0
- package/.versions/0.3.0/.pi/harnesses/coms-net/index.ts +1637 -0
- package/.versions/0.3.0/.pi/harnesses/coms-net/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/damage-control/README.md +38 -0
- package/.versions/0.3.0/.pi/harnesses/damage-control/index.ts +207 -0
- package/.versions/0.3.0/.pi/harnesses/damage-control/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/damage-control-continue/README.md +37 -0
- package/.versions/0.3.0/.pi/harnesses/damage-control-continue/index.ts +234 -0
- package/.versions/0.3.0/.pi/harnesses/damage-control-continue/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/minimal/README.md +27 -0
- package/.versions/0.3.0/.pi/harnesses/minimal/index.ts +32 -0
- package/.versions/0.3.0/.pi/harnesses/minimal/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/package-lock.json +35 -0
- package/.versions/0.3.0/.pi/harnesses/package.json +9 -0
- package/.versions/0.3.0/.pi/harnesses/pi-pi/README.md +39 -0
- package/.versions/0.3.0/.pi/harnesses/pi-pi/index.ts +631 -0
- package/.versions/0.3.0/.pi/harnesses/pi-pi/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/purpose-gate/README.md +27 -0
- package/.versions/0.3.0/.pi/harnesses/purpose-gate/index.ts +82 -0
- package/.versions/0.3.0/.pi/harnesses/purpose-gate/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/session-replay/README.md +28 -0
- package/.versions/0.3.0/.pi/harnesses/session-replay/index.ts +214 -0
- package/.versions/0.3.0/.pi/harnesses/session-replay/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/subagent-widget/README.md +36 -0
- package/.versions/0.3.0/.pi/harnesses/subagent-widget/index.ts +479 -0
- package/.versions/0.3.0/.pi/harnesses/subagent-widget/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/system-select/README.md +39 -0
- package/.versions/0.3.0/.pi/harnesses/system-select/index.ts +165 -0
- package/.versions/0.3.0/.pi/harnesses/system-select/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/tilldone/README.md +35 -0
- package/.versions/0.3.0/.pi/harnesses/tilldone/index.ts +724 -0
- package/.versions/0.3.0/.pi/harnesses/tilldone/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/tool-counter/README.md +31 -0
- package/.versions/0.3.0/.pi/harnesses/tool-counter/index.ts +100 -0
- package/.versions/0.3.0/.pi/harnesses/tool-counter/package.json +6 -0
- package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/README.md +27 -0
- package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/index.ts +66 -0
- package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/package.json +6 -0
- package/.versions/0.3.0/.pi/prompts/build.md +24 -0
- package/.versions/0.3.0/.pi/prompts/code-simplify.md +22 -0
- package/.versions/0.3.0/.pi/prompts/doctor-agent-skills.md +13 -0
- package/.versions/0.3.0/.pi/prompts/plan.md +16 -0
- package/.versions/0.3.0/.pi/prompts/review.md +16 -0
- package/.versions/0.3.0/.pi/prompts/setup-agent-skills.md +19 -0
- package/.versions/0.3.0/.pi/prompts/ship.md +17 -0
- package/.versions/0.3.0/.pi/prompts/spec.md +15 -0
- package/.versions/0.3.0/.pi/prompts/test.md +19 -0
- package/.versions/0.3.0/.pi/skills/bowser/SKILL.md +114 -0
- package/.versions/0.3.0/.version +1 -0
- package/.versions/0.3.0/agents/builder.md +6 -0
- package/.versions/0.3.0/agents/code-reviewer.md +93 -0
- package/.versions/0.3.0/agents/documenter.md +6 -0
- package/.versions/0.3.0/agents/plan-reviewer.md +22 -0
- package/.versions/0.3.0/agents/planner.md +6 -0
- package/.versions/0.3.0/agents/scout.md +6 -0
- package/.versions/0.3.0/agents/security-auditor.md +97 -0
- package/.versions/0.3.0/agents/test-engineer.md +89 -0
- package/.versions/0.3.0/hooks/SIMPLIFY-IGNORE.md +90 -0
- package/.versions/0.3.0/hooks/hooks.json +14 -0
- package/.versions/0.3.0/hooks/session-start.sh +74 -0
- package/.versions/0.3.0/hooks/simplify-ignore-test.sh +247 -0
- package/.versions/0.3.0/hooks/simplify-ignore.sh +302 -0
- package/.versions/0.3.0/references/accessibility-checklist.md +159 -0
- package/.versions/0.3.0/references/performance-checklist.md +121 -0
- package/.versions/0.3.0/references/prompting-patterns.md +380 -0
- package/.versions/0.3.0/references/security-checklist.md +134 -0
- package/.versions/0.3.0/references/testing-patterns.md +236 -0
- package/.versions/0.3.0/skills/api-and-interface-design/SKILL.md +294 -0
- package/.versions/0.3.0/skills/browser-testing-with-devtools/SKILL.md +335 -0
- package/.versions/0.3.0/skills/ci-cd-and-automation/SKILL.md +390 -0
- package/.versions/0.3.0/skills/code-review-and-quality/SKILL.md +347 -0
- package/.versions/0.3.0/skills/code-simplification/SKILL.md +331 -0
- package/.versions/0.3.0/skills/context-engineering/SKILL.md +291 -0
- package/.versions/0.3.0/skills/debugging-and-error-recovery/SKILL.md +300 -0
- package/.versions/0.3.0/skills/deprecation-and-migration/SKILL.md +206 -0
- package/.versions/0.3.0/skills/designing-agents/SKILL.md +394 -0
- package/.versions/0.3.0/skills/designing-agents/pi-harness-authoring.md +213 -0
- package/.versions/0.3.0/skills/documentation-and-adrs/SKILL.md +278 -0
- package/.versions/0.3.0/skills/frontend-ui-engineering/SKILL.md +322 -0
- package/.versions/0.3.0/skills/git-workflow-and-versioning/SKILL.md +316 -0
- package/.versions/0.3.0/skills/guided-workspace-setup/SKILL.md +331 -0
- package/.versions/0.3.0/skills/idea-refine/SKILL.md +178 -0
- package/.versions/0.3.0/skills/idea-refine/examples.md +238 -0
- package/.versions/0.3.0/skills/idea-refine/frameworks.md +99 -0
- package/.versions/0.3.0/skills/idea-refine/refinement-criteria.md +113 -0
- package/.versions/0.3.0/skills/idea-refine/scripts/idea-refine.sh +15 -0
- package/.versions/0.3.0/skills/incremental-implementation/SKILL.md +279 -0
- package/.versions/0.3.0/skills/performance-optimization/SKILL.md +350 -0
- package/.versions/0.3.0/skills/planning-and-task-breakdown/SKILL.md +237 -0
- package/.versions/0.3.0/skills/security-and-hardening/SKILL.md +349 -0
- package/.versions/0.3.0/skills/shipping-and-launch/SKILL.md +309 -0
- package/.versions/0.3.0/skills/source-driven-development/SKILL.md +194 -0
- package/.versions/0.3.0/skills/spec-driven-development/SKILL.md +237 -0
- package/.versions/0.3.0/skills/test-driven-development/SKILL.md +379 -0
- package/.versions/0.3.0/skills/using-agent-skills/SKILL.md +176 -0
- package/CHANGELOG.md +108 -0
- package/README.md +5 -5
- package/bin/cli.js +133 -22
- package/bin/lib/bootstrap.js +254 -0
- package/bin/lib/doctor.js +1 -1
- package/bin/lib/update-notifier.js +195 -0
- package/docs/getting-started.md +2 -2
- package/docs/npm-install.md +91 -8
- package/hooks/session-start.sh +66 -12
- package/package.json +1 -1
- package/skills/guided-workspace-setup/SKILL.md +41 -3
- /package/.claude/commands/{setup.md → setup-agent-skills.md} +0 -0
- /package/.opencode/commands/{as-doctor.md → as-doctor-agent-skills.md} +0 -0
- /package/.opencode/commands/{as-setup.md → as-setup-agent-skills.md} +0 -0
- /package/.pi/prompts/{setup.md → setup-agent-skills.md} +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# damage-control
|
|
2
|
+
|
|
3
|
+
Safety auditing — blocks destructive tool calls.
|
|
4
|
+
|
|
5
|
+
> Ported from [`pi-vs-claude-code`](https://github.com/disler/pi-vs-claude-code) by [disler](https://github.com/disler) (MIT). See the [extension catalog](../../../docs/pi-extensions.md).
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
Intercepts every tool call and checks it against rules in `.pi/damage-control-rules.yaml`:
|
|
10
|
+
|
|
11
|
+
- `bashToolPatterns` — destructive shell commands (`rm -rf`, `git reset --hard`,
|
|
12
|
+
`DROP TABLE`, cloud-resource deletes, …); some are hard-blocked, some marked `ask`
|
|
13
|
+
- `zeroAccessPaths` — secrets and credentials that must never be read (`.env`, `*.pem`, …)
|
|
14
|
+
- `readOnlyPaths` — paths that may be read but not written (lockfiles, build output, …)
|
|
15
|
+
- `noDeletePaths` — paths that may be edited but not deleted (`README`, `.git/`, …)
|
|
16
|
+
|
|
17
|
+
On a match the tool result is replaced with a block message and the agent's turn is
|
|
18
|
+
aborted (`ctx.abort()`). For a variant that lets the agent keep working with corrective
|
|
19
|
+
feedback instead of aborting, use [`damage-control-continue`](../damage-control-continue/README.md).
|
|
20
|
+
|
|
21
|
+
## Commands & tools
|
|
22
|
+
|
|
23
|
+
None — it runs passively on the `tool_call` event.
|
|
24
|
+
|
|
25
|
+
## Requires
|
|
26
|
+
|
|
27
|
+
- `.pi/damage-control-rules.yaml` — the rule set (shipped in this repo)
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pi -e .pi/harnesses/damage-control/index.ts
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Upstream changes
|
|
36
|
+
|
|
37
|
+
- Theme integration removed — the `themeMap.ts` import and the `applyExtensionDefaults()`
|
|
38
|
+
call were stripped (this repo does not ship pi themes).
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type { ExtensionAPI, ToolCallEvent } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
3
|
+
import { parse as yamlParse } from "yaml";
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as os from "os";
|
|
7
|
+
|
|
8
|
+
interface Rule {
|
|
9
|
+
pattern: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
ask?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface Rules {
|
|
15
|
+
bashToolPatterns: Rule[];
|
|
16
|
+
zeroAccessPaths: string[];
|
|
17
|
+
readOnlyPaths: string[];
|
|
18
|
+
noDeletePaths: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function (pi: ExtensionAPI) {
|
|
22
|
+
let rules: Rules = {
|
|
23
|
+
bashToolPatterns: [],
|
|
24
|
+
zeroAccessPaths: [],
|
|
25
|
+
readOnlyPaths: [],
|
|
26
|
+
noDeletePaths: [],
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function resolvePath(p: string, cwd: string): string {
|
|
30
|
+
if (p.startsWith("~")) {
|
|
31
|
+
p = path.join(os.homedir(), p.slice(1));
|
|
32
|
+
}
|
|
33
|
+
return path.resolve(cwd, p);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isPathMatch(targetPath: string, pattern: string, cwd: string): boolean {
|
|
37
|
+
// Simple glob-to-regex or substring match
|
|
38
|
+
// Expand tilde in pattern if present
|
|
39
|
+
const resolvedPattern = pattern.startsWith("~") ? path.join(os.homedir(), pattern.slice(1)) : pattern;
|
|
40
|
+
|
|
41
|
+
// If pattern ends with /, it's a directory match
|
|
42
|
+
if (resolvedPattern.endsWith("/")) {
|
|
43
|
+
const absolutePattern = path.isAbsolute(resolvedPattern) ? resolvedPattern : path.resolve(cwd, resolvedPattern);
|
|
44
|
+
return targetPath.startsWith(absolutePattern);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Handle basic wildcards *
|
|
48
|
+
const regexPattern = resolvedPattern
|
|
49
|
+
.replace(/[.+^${}()|[\]\\]/g, "\\$&") // escape regex chars
|
|
50
|
+
.replace(/\*/g, ".*"); // convert * to .*
|
|
51
|
+
|
|
52
|
+
const regex = new RegExp(`^${regexPattern}$|^${regexPattern}/|/${regexPattern}$|/${regexPattern}/`);
|
|
53
|
+
|
|
54
|
+
// Match against absolute path and relative-to-cwd path
|
|
55
|
+
const relativePath = path.relative(cwd, targetPath);
|
|
56
|
+
|
|
57
|
+
return regex.test(targetPath) || regex.test(relativePath) || targetPath.includes(resolvedPattern) || relativePath.includes(resolvedPattern);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
61
|
+
const projectRulesPath = path.join(ctx.cwd, ".pi", "damage-control-rules.yaml");
|
|
62
|
+
const globalRulesPath = path.join(os.homedir(), ".pi", "damage-control-rules.yaml");
|
|
63
|
+
const rulesPath = fs.existsSync(projectRulesPath) ? projectRulesPath : fs.existsSync(globalRulesPath) ? globalRulesPath : null;
|
|
64
|
+
try {
|
|
65
|
+
if (rulesPath) {
|
|
66
|
+
const content = fs.readFileSync(rulesPath, "utf8");
|
|
67
|
+
const loaded = yamlParse(content) as Partial<Rules>;
|
|
68
|
+
rules = {
|
|
69
|
+
bashToolPatterns: loaded.bashToolPatterns || [],
|
|
70
|
+
zeroAccessPaths: loaded.zeroAccessPaths || [],
|
|
71
|
+
readOnlyPaths: loaded.readOnlyPaths || [],
|
|
72
|
+
noDeletePaths: loaded.noDeletePaths || [],
|
|
73
|
+
};
|
|
74
|
+
const source = rulesPath === projectRulesPath ? "project" : "global";
|
|
75
|
+
ctx.ui.notify(`🛡️ Damage-Control: Loaded ${rules.bashToolPatterns.length + rules.zeroAccessPaths.length + rules.readOnlyPaths.length + rules.noDeletePaths.length} rules (${source}).`);
|
|
76
|
+
} else {
|
|
77
|
+
ctx.ui.notify("🛡️ Damage-Control: No rules found at .pi/damage-control-rules.yaml (project or global)");
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
ctx.ui.notify(`🛡️ Damage-Control: Failed to load rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
ctx.ui.setStatus(`🛡️ Damage-Control Active: ${rules.bashToolPatterns.length + rules.zeroAccessPaths.length + rules.readOnlyPaths.length + rules.noDeletePaths.length} Rules`);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
87
|
+
let violationReason: string | null = null;
|
|
88
|
+
let shouldAsk = false;
|
|
89
|
+
|
|
90
|
+
// 1. Check Zero Access Paths for all tools that use path or glob
|
|
91
|
+
const checkPaths = (pathsToCheck: string[]) => {
|
|
92
|
+
for (const p of pathsToCheck) {
|
|
93
|
+
const resolved = resolvePath(p, ctx.cwd);
|
|
94
|
+
for (const zap of rules.zeroAccessPaths) {
|
|
95
|
+
if (isPathMatch(resolved, zap, ctx.cwd)) {
|
|
96
|
+
return `Access to zero-access path restricted: ${zap}`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// Extract paths from tool input
|
|
104
|
+
const inputPaths: string[] = [];
|
|
105
|
+
if (isToolCallEventType("read", event) || isToolCallEventType("write", event) || isToolCallEventType("edit", event)) {
|
|
106
|
+
inputPaths.push(event.input.path);
|
|
107
|
+
} else if (isToolCallEventType("grep", event) || isToolCallEventType("find", event) || isToolCallEventType("ls", event)) {
|
|
108
|
+
inputPaths.push(event.input.path || ".");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (isToolCallEventType("grep", event) && event.input.glob) {
|
|
112
|
+
// Check glob field as well
|
|
113
|
+
for (const zap of rules.zeroAccessPaths) {
|
|
114
|
+
if (event.input.glob.includes(zap) || isPathMatch(event.input.glob, zap, ctx.cwd)) {
|
|
115
|
+
violationReason = `Glob matches zero-access path: ${zap}`;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!violationReason) {
|
|
122
|
+
violationReason = checkPaths(inputPaths);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 2. Tool-specific logic
|
|
126
|
+
if (!violationReason) {
|
|
127
|
+
if (isToolCallEventType("bash", event)) {
|
|
128
|
+
const command = event.input.command;
|
|
129
|
+
|
|
130
|
+
// Check bashToolPatterns
|
|
131
|
+
for (const rule of rules.bashToolPatterns) {
|
|
132
|
+
const regex = new RegExp(rule.pattern);
|
|
133
|
+
if (regex.test(command)) {
|
|
134
|
+
violationReason = rule.reason;
|
|
135
|
+
shouldAsk = !!rule.ask;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check if bash command interacts with restricted paths
|
|
141
|
+
if (!violationReason) {
|
|
142
|
+
for (const zap of rules.zeroAccessPaths) {
|
|
143
|
+
if (command.includes(zap)) {
|
|
144
|
+
violationReason = `Bash command references zero-access path: ${zap}`;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!violationReason) {
|
|
151
|
+
for (const rop of rules.readOnlyPaths) {
|
|
152
|
+
// Heuristic: check if command might modify a read-only path
|
|
153
|
+
// Redirects, sed -i, rm, mv to, etc.
|
|
154
|
+
if (command.includes(rop) && (/[\s>|]/.test(command) || command.includes("rm") || command.includes("mv") || command.includes("sed"))) {
|
|
155
|
+
violationReason = `Bash command may modify read-only path: ${rop}`;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!violationReason) {
|
|
162
|
+
for (const ndp of rules.noDeletePaths) {
|
|
163
|
+
if (command.includes(ndp) && (command.includes("rm") || command.includes("mv"))) {
|
|
164
|
+
violationReason = `Bash command attempts to delete/move protected path: ${ndp}`;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} else if (isToolCallEventType("write", event) || isToolCallEventType("edit", event)) {
|
|
170
|
+
// Check Read-Only paths
|
|
171
|
+
for (const p of inputPaths) {
|
|
172
|
+
const resolved = resolvePath(p, ctx.cwd);
|
|
173
|
+
for (const rop of rules.readOnlyPaths) {
|
|
174
|
+
if (isPathMatch(resolved, rop, ctx.cwd)) {
|
|
175
|
+
violationReason = `Modification of read-only path restricted: ${rop}`;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (violationReason) {
|
|
184
|
+
if (shouldAsk) {
|
|
185
|
+
const confirmed = await ctx.ui.confirm("🛡️ Damage-Control Confirmation", `Dangerous command detected: ${violationReason}\n\nCommand: ${isToolCallEventType("bash", event) ? event.input.command : JSON.stringify(event.input)}\n\nDo you want to proceed?`, { timeout: 30000 });
|
|
186
|
+
|
|
187
|
+
if (!confirmed) {
|
|
188
|
+
ctx.ui.setStatus(`⚠️ Last Violation Blocked: ${violationReason.slice(0, 30)}...`);
|
|
189
|
+
pi.appendEntry("damage-control-log", { tool: event.toolName, input: event.input, rule: violationReason, action: "blocked_by_user" });
|
|
190
|
+
ctx.abort();
|
|
191
|
+
return { block: true, reason: `🛑 BLOCKED by Damage-Control: ${violationReason} (User denied)\n\nDO NOT attempt to work around this restriction. DO NOT retry with alternative commands, paths, or approaches that achieve the same result. Report this block to the user exactly as stated and ask how they would like to proceed.` };
|
|
192
|
+
} else {
|
|
193
|
+
pi.appendEntry("damage-control-log", { tool: event.toolName, input: event.input, rule: violationReason, action: "confirmed_by_user" });
|
|
194
|
+
return { block: false };
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
ctx.ui.notify(`🛑 Damage-Control: Blocked ${event.toolName} due to ${violationReason}`);
|
|
198
|
+
ctx.ui.setStatus(`⚠️ Last Violation: ${violationReason.slice(0, 30)}...`);
|
|
199
|
+
pi.appendEntry("damage-control-log", { tool: event.toolName, input: event.input, rule: violationReason, action: "blocked" });
|
|
200
|
+
ctx.abort();
|
|
201
|
+
return { block: true, reason: `🛑 BLOCKED by Damage-Control: ${violationReason}\n\nDO NOT attempt to work around this restriction. DO NOT retry with alternative commands, paths, or approaches that achieve the same result. Report this block to the user exactly as stated and ask how they would like to proceed.` };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return { block: false };
|
|
206
|
+
});
|
|
207
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# damage-control-continue
|
|
2
|
+
|
|
3
|
+
Safety auditing that lets the agent recover instead of aborting.
|
|
4
|
+
|
|
5
|
+
> Ported from [`pi-vs-claude-code`](https://github.com/disler/pi-vs-claude-code) by [disler](https://github.com/disler) (MIT). See the [extension catalog](../../../docs/pi-extensions.md).
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
Same rule engine as [`damage-control`](../damage-control/README.md) — it reads the same
|
|
10
|
+
`.pi/damage-control-rules.yaml` — but it differs in how a blocked call is handled:
|
|
11
|
+
|
|
12
|
+
- the blocked tool result is replaced with **actionable feedback** that distinguishes
|
|
13
|
+
destructive intent from merely non-destructive intent and tells the agent how to adapt;
|
|
14
|
+
- it does **not** call `ctx.abort()`, so the agent's turn continues and it can try an
|
|
15
|
+
alternate path (e.g. assume a `.env` key exists rather than reading the file to verify).
|
|
16
|
+
|
|
17
|
+
Use this when you want guard rails without killing the turn; use plain `damage-control`
|
|
18
|
+
when a hard stop is preferred.
|
|
19
|
+
|
|
20
|
+
## Commands & tools
|
|
21
|
+
|
|
22
|
+
None — it runs passively on the `tool_call` event.
|
|
23
|
+
|
|
24
|
+
## Requires
|
|
25
|
+
|
|
26
|
+
- `.pi/damage-control-rules.yaml` — the rule set (shipped in this repo)
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pi -e .pi/harnesses/damage-control-continue/index.ts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Upstream changes
|
|
35
|
+
|
|
36
|
+
- Theme integration removed — the `themeMap.ts` import and the `applyExtensionDefaults()`
|
|
37
|
+
call were stripped (this repo does not ship pi themes).
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Damage-Control (continue) — same rules, but the agent keeps working
|
|
3
|
+
*
|
|
4
|
+
* Difference from damage-control.ts:
|
|
5
|
+
* - The blocked tool result is replaced with actionable feedback that
|
|
6
|
+
* distinguishes destructive vs non-destructive intent and tells the
|
|
7
|
+
* agent how to adapt.
|
|
8
|
+
* - We do NOT call ctx.abort(), so the agent's turn continues and can
|
|
9
|
+
* try an alternate path (e.g. assume a .env key exists instead of
|
|
10
|
+
* reading it to verify).
|
|
11
|
+
*
|
|
12
|
+
* Usage: pi -e extensions/damage-control-continue.ts
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
16
|
+
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
17
|
+
import { parse as yamlParse } from "yaml";
|
|
18
|
+
import * as fs from "fs";
|
|
19
|
+
import * as path from "path";
|
|
20
|
+
import * as os from "os";
|
|
21
|
+
|
|
22
|
+
interface Rule {
|
|
23
|
+
pattern: string;
|
|
24
|
+
reason: string;
|
|
25
|
+
ask?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface Rules {
|
|
29
|
+
bashToolPatterns: Rule[];
|
|
30
|
+
zeroAccessPaths: string[];
|
|
31
|
+
readOnlyPaths: string[];
|
|
32
|
+
noDeletePaths: string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function continueFeedback(toolName: string, violationReason: string, invocation: string): string {
|
|
36
|
+
return [
|
|
37
|
+
`🛡️ Damage-Control: ${toolName} blocked — ${violationReason}`,
|
|
38
|
+
``,
|
|
39
|
+
`Attempted: ${invocation}`,
|
|
40
|
+
``,
|
|
41
|
+
`Don't call ${toolName} directly like this. Decide which case you're in and continue:`,
|
|
42
|
+
``,
|
|
43
|
+
`→ NON-DESTRUCTIVE (e.g. reading .env to verify a key, listing a protected dir, peeking at config):`,
|
|
44
|
+
` Assume the data is present and correct. Skip the verification step and move on with the task.`,
|
|
45
|
+
` Example: if you were reading .env to confirm a key exists, just assume it does — the user has`,
|
|
46
|
+
` configured their environment. If you actually need a value, ask the user for it explicitly.`,
|
|
47
|
+
``,
|
|
48
|
+
`→ DESTRUCTIVE (delete, overwrite, force-push, drop, rm, truncate, sudo, kill, etc.):`,
|
|
49
|
+
` STOP. Tell the user exactly what you need to ship this task and ask how they want to proceed.`,
|
|
50
|
+
` Do not invent a workaround that achieves the same destructive effect.`,
|
|
51
|
+
``,
|
|
52
|
+
`Pick the right path above and continue working. Do not retry this exact call.`,
|
|
53
|
+
].join("\n");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default function (pi: ExtensionAPI) {
|
|
57
|
+
let rules: Rules = {
|
|
58
|
+
bashToolPatterns: [],
|
|
59
|
+
zeroAccessPaths: [],
|
|
60
|
+
readOnlyPaths: [],
|
|
61
|
+
noDeletePaths: [],
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
function resolvePath(p: string, cwd: string): string {
|
|
65
|
+
if (p.startsWith("~")) {
|
|
66
|
+
p = path.join(os.homedir(), p.slice(1));
|
|
67
|
+
}
|
|
68
|
+
return path.resolve(cwd, p);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function isPathMatch(targetPath: string, pattern: string, cwd: string): boolean {
|
|
72
|
+
const resolvedPattern = pattern.startsWith("~") ? path.join(os.homedir(), pattern.slice(1)) : pattern;
|
|
73
|
+
|
|
74
|
+
if (resolvedPattern.endsWith("/")) {
|
|
75
|
+
const absolutePattern = path.isAbsolute(resolvedPattern) ? resolvedPattern : path.resolve(cwd, resolvedPattern);
|
|
76
|
+
return targetPath.startsWith(absolutePattern);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const regexPattern = resolvedPattern
|
|
80
|
+
.replace(/[.+^${}()|[\]\\]/g, "\\$&")
|
|
81
|
+
.replace(/\*/g, ".*");
|
|
82
|
+
|
|
83
|
+
const regex = new RegExp(`^${regexPattern}$|^${regexPattern}/|/${regexPattern}$|/${regexPattern}/`);
|
|
84
|
+
|
|
85
|
+
const relativePath = path.relative(cwd, targetPath);
|
|
86
|
+
|
|
87
|
+
return regex.test(targetPath) || regex.test(relativePath) || targetPath.includes(resolvedPattern) || relativePath.includes(resolvedPattern);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
91
|
+
const projectRulesPath = path.join(ctx.cwd, ".pi", "damage-control-rules.yaml");
|
|
92
|
+
const globalRulesPath = path.join(os.homedir(), ".pi", "damage-control-rules.yaml");
|
|
93
|
+
const rulesPath = fs.existsSync(projectRulesPath) ? projectRulesPath : fs.existsSync(globalRulesPath) ? globalRulesPath : null;
|
|
94
|
+
try {
|
|
95
|
+
if (rulesPath) {
|
|
96
|
+
const content = fs.readFileSync(rulesPath, "utf8");
|
|
97
|
+
const loaded = yamlParse(content) as Partial<Rules>;
|
|
98
|
+
rules = {
|
|
99
|
+
bashToolPatterns: loaded.bashToolPatterns || [],
|
|
100
|
+
zeroAccessPaths: loaded.zeroAccessPaths || [],
|
|
101
|
+
readOnlyPaths: loaded.readOnlyPaths || [],
|
|
102
|
+
noDeletePaths: loaded.noDeletePaths || [],
|
|
103
|
+
};
|
|
104
|
+
const source = rulesPath === projectRulesPath ? "project" : "global";
|
|
105
|
+
const total = rules.bashToolPatterns.length + rules.zeroAccessPaths.length + rules.readOnlyPaths.length + rules.noDeletePaths.length;
|
|
106
|
+
ctx.ui.notify(`🛡️ Damage-Control (continue): Loaded ${total} rules (${source}). Blocks deliver feedback so the agent can adapt and keep working.`);
|
|
107
|
+
} else {
|
|
108
|
+
ctx.ui.notify("🛡️ Damage-Control (continue): No rules found at .pi/damage-control-rules.yaml (project or global)");
|
|
109
|
+
}
|
|
110
|
+
} catch (err) {
|
|
111
|
+
ctx.ui.notify(`🛡️ Damage-Control (continue): Failed to load rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const total = rules.bashToolPatterns.length + rules.zeroAccessPaths.length + rules.readOnlyPaths.length + rules.noDeletePaths.length;
|
|
115
|
+
ctx.ui.setStatus(`🛡️ Damage-Control (continue): ${total} Rules`);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
119
|
+
let violationReason: string | null = null;
|
|
120
|
+
let shouldAsk = false;
|
|
121
|
+
|
|
122
|
+
const checkPaths = (pathsToCheck: string[]) => {
|
|
123
|
+
for (const p of pathsToCheck) {
|
|
124
|
+
const resolved = resolvePath(p, ctx.cwd);
|
|
125
|
+
for (const zap of rules.zeroAccessPaths) {
|
|
126
|
+
if (isPathMatch(resolved, zap, ctx.cwd)) {
|
|
127
|
+
return `Access to zero-access path restricted: ${zap}`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const inputPaths: string[] = [];
|
|
135
|
+
if (isToolCallEventType("read", event) || isToolCallEventType("write", event) || isToolCallEventType("edit", event)) {
|
|
136
|
+
inputPaths.push(event.input.path);
|
|
137
|
+
} else if (isToolCallEventType("grep", event) || isToolCallEventType("find", event) || isToolCallEventType("ls", event)) {
|
|
138
|
+
inputPaths.push(event.input.path || ".");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (isToolCallEventType("grep", event) && event.input.glob) {
|
|
142
|
+
for (const zap of rules.zeroAccessPaths) {
|
|
143
|
+
if (event.input.glob.includes(zap) || isPathMatch(event.input.glob, zap, ctx.cwd)) {
|
|
144
|
+
violationReason = `Glob matches zero-access path: ${zap}`;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!violationReason) {
|
|
151
|
+
violationReason = checkPaths(inputPaths);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!violationReason) {
|
|
155
|
+
if (isToolCallEventType("bash", event)) {
|
|
156
|
+
const command = event.input.command;
|
|
157
|
+
|
|
158
|
+
for (const rule of rules.bashToolPatterns) {
|
|
159
|
+
const regex = new RegExp(rule.pattern);
|
|
160
|
+
if (regex.test(command)) {
|
|
161
|
+
violationReason = rule.reason;
|
|
162
|
+
shouldAsk = !!rule.ask;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (!violationReason) {
|
|
168
|
+
for (const zap of rules.zeroAccessPaths) {
|
|
169
|
+
if (command.includes(zap)) {
|
|
170
|
+
violationReason = `Bash command references zero-access path: ${zap}`;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!violationReason) {
|
|
177
|
+
for (const rop of rules.readOnlyPaths) {
|
|
178
|
+
if (command.includes(rop) && (/[\s>|]/.test(command) || command.includes("rm") || command.includes("mv") || command.includes("sed"))) {
|
|
179
|
+
violationReason = `Bash command may modify read-only path: ${rop}`;
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (!violationReason) {
|
|
186
|
+
for (const ndp of rules.noDeletePaths) {
|
|
187
|
+
if (command.includes(ndp) && (command.includes("rm") || command.includes("mv"))) {
|
|
188
|
+
violationReason = `Bash command attempts to delete/move protected path: ${ndp}`;
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
} else if (isToolCallEventType("write", event) || isToolCallEventType("edit", event)) {
|
|
194
|
+
for (const p of inputPaths) {
|
|
195
|
+
const resolved = resolvePath(p, ctx.cwd);
|
|
196
|
+
for (const rop of rules.readOnlyPaths) {
|
|
197
|
+
if (isPathMatch(resolved, rop, ctx.cwd)) {
|
|
198
|
+
violationReason = `Modification of read-only path restricted: ${rop}`;
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (violationReason) {
|
|
207
|
+
const invocation = isToolCallEventType("bash", event) ? event.input.command : JSON.stringify(event.input);
|
|
208
|
+
|
|
209
|
+
if (shouldAsk) {
|
|
210
|
+
const confirmed = await ctx.ui.confirm(
|
|
211
|
+
"🛡️ Damage-Control Confirmation",
|
|
212
|
+
`Dangerous command detected: ${violationReason}\n\nCommand: ${invocation}\n\nDo you want to proceed?`,
|
|
213
|
+
{ timeout: 30000 },
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
if (!confirmed) {
|
|
217
|
+
ctx.ui.setStatus(`⚠️ Last Violation Blocked: ${violationReason.slice(0, 30)}...`);
|
|
218
|
+
pi.appendEntry("damage-control-log", { tool: event.toolName, input: event.input, rule: violationReason, action: "blocked_by_user" });
|
|
219
|
+
return { block: true, reason: continueFeedback(event.toolName, `${violationReason} (user denied)`, invocation) };
|
|
220
|
+
} else {
|
|
221
|
+
pi.appendEntry("damage-control-log", { tool: event.toolName, input: event.input, rule: violationReason, action: "confirmed_by_user" });
|
|
222
|
+
return { block: false };
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
ctx.ui.notify(`🛑 Damage-Control: Blocked ${event.toolName} (${violationReason}) — agent will adapt and continue.`);
|
|
226
|
+
ctx.ui.setStatus(`⚠️ Last Violation: ${violationReason.slice(0, 30)}...`);
|
|
227
|
+
pi.appendEntry("damage-control-log", { tool: event.toolName, input: event.input, rule: violationReason, action: "blocked" });
|
|
228
|
+
return { block: true, reason: continueFeedback(event.toolName, violationReason, invocation) };
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return { block: false };
|
|
233
|
+
});
|
|
234
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# minimal
|
|
2
|
+
|
|
3
|
+
Model name + context meter in a compact footer.
|
|
4
|
+
|
|
5
|
+
> Ported from [`pi-vs-claude-code`](https://github.com/disler/pi-vs-claude-code) by [disler](https://github.com/disler) (MIT). See the [extension catalog](../../../docs/pi-extensions.md).
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
Replaces the pi footer with a single compact line showing the active model ID and a
|
|
10
|
+
10-block context usage meter — e.g. `claude-opus-4-7 [###-------] 30%`. Useful on its
|
|
11
|
+
own or stacked behind another extension as a lightweight status surface.
|
|
12
|
+
|
|
13
|
+
## Commands & tools
|
|
14
|
+
|
|
15
|
+
None — footer only.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pi -e .pi/harnesses/minimal/index.ts
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Upstream changes
|
|
24
|
+
|
|
25
|
+
- Theme integration removed — the `themeMap.ts` import and the `applyExtensionDefaults()`
|
|
26
|
+
call in `session_start` were stripped (this repo does not ship pi themes). The footer
|
|
27
|
+
now renders against pi's active theme.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal — Model name + context meter in a compact footer
|
|
3
|
+
*
|
|
4
|
+
* Shows model ID and a 10-block context usage bar: [###-------] 30%
|
|
5
|
+
*
|
|
6
|
+
* Usage: pi -e extensions/minimal.ts
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
10
|
+
import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
|
|
11
|
+
|
|
12
|
+
export default function (pi: ExtensionAPI) {
|
|
13
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
14
|
+
ctx.ui.setFooter((_tui, theme, _footerData) => ({
|
|
15
|
+
dispose: () => {},
|
|
16
|
+
invalidate() {},
|
|
17
|
+
render(width: number): string[] {
|
|
18
|
+
const model = ctx.model?.id || "no-model";
|
|
19
|
+
const usage = ctx.getContextUsage();
|
|
20
|
+
const pct = (usage && usage.percent !== null) ? usage.percent : 0;
|
|
21
|
+
const filled = Math.round(pct / 10);
|
|
22
|
+
const bar = "#".repeat(filled) + "-".repeat(10 - filled);
|
|
23
|
+
|
|
24
|
+
const left = theme.fg("dim", ` ${model}`);
|
|
25
|
+
const right = theme.fg("dim", `[${bar}] ${Math.round(pct)}% `);
|
|
26
|
+
const pad = " ".repeat(Math.max(1, width - visibleWidth(left) - visibleWidth(right)));
|
|
27
|
+
|
|
28
|
+
return [truncateToWidth(left + pad + right, width)];
|
|
29
|
+
},
|
|
30
|
+
}));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-skills-pi-harnesses-runtime-deps",
|
|
3
|
+
"lockfileVersion": 3,
|
|
4
|
+
"requires": true,
|
|
5
|
+
"packages": {
|
|
6
|
+
"": {
|
|
7
|
+
"name": "agent-skills-pi-harnesses-runtime-deps",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@sinclair/typebox": "^0.34.0",
|
|
10
|
+
"yaml": "^2.8.0"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"node_modules/@sinclair/typebox": {
|
|
14
|
+
"version": "0.34.49",
|
|
15
|
+
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz",
|
|
16
|
+
"integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==",
|
|
17
|
+
"license": "MIT"
|
|
18
|
+
},
|
|
19
|
+
"node_modules/yaml": {
|
|
20
|
+
"version": "2.9.0",
|
|
21
|
+
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
|
|
22
|
+
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"bin": {
|
|
25
|
+
"yaml": "bin.mjs"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">= 14.6"
|
|
29
|
+
},
|
|
30
|
+
"funding": {
|
|
31
|
+
"url": "https://github.com/sponsors/eemeli"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|