@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.
Files changed (328) hide show
  1. package/.claude/commands/{doctor.md → doctor-agent-skills.md} +1 -1
  2. package/.pi/extensions/agent-skills-update-check/README.md +58 -0
  3. package/.pi/extensions/agent-skills-update-check/index.ts +161 -0
  4. package/.pi/extensions/agent-skills-update-check/package.json +6 -0
  5. package/.pi/prompts/{doctor.md → doctor-agent-skills.md} +1 -1
  6. package/.versions/0.2.0/.claude/commands/build.md +18 -0
  7. package/.versions/0.2.0/.claude/commands/code-simplify.md +22 -0
  8. package/.versions/0.2.0/.claude/commands/design-agent.md +14 -0
  9. package/.versions/0.2.0/.claude/commands/doctor-agent-skills.md +13 -0
  10. package/.versions/0.2.0/.claude/commands/plan.md +16 -0
  11. package/.versions/0.2.0/.claude/commands/prime.md +22 -0
  12. package/.versions/0.2.0/.claude/commands/review.md +16 -0
  13. package/.versions/0.2.0/.claude/commands/setup-agent-skills.md +19 -0
  14. package/.versions/0.2.0/.claude/commands/ship.md +17 -0
  15. package/.versions/0.2.0/.claude/commands/spec.md +15 -0
  16. package/.versions/0.2.0/.claude/commands/test.md +19 -0
  17. package/.versions/0.2.0/.opencode/commands/as-build.md +17 -0
  18. package/.versions/0.2.0/.opencode/commands/as-code-simplify.md +16 -0
  19. package/.versions/0.2.0/.opencode/commands/as-design-agent.md +15 -0
  20. package/.versions/0.2.0/.opencode/commands/as-doctor-agent-skills.md +11 -0
  21. package/.versions/0.2.0/.opencode/commands/as-plan.md +16 -0
  22. package/.versions/0.2.0/.opencode/commands/as-prime.md +22 -0
  23. package/.versions/0.2.0/.opencode/commands/as-review.md +15 -0
  24. package/.versions/0.2.0/.opencode/commands/as-setup-agent-skills.md +11 -0
  25. package/.versions/0.2.0/.opencode/commands/as-ship.md +16 -0
  26. package/.versions/0.2.0/.opencode/commands/as-spec.md +16 -0
  27. package/.versions/0.2.0/.opencode/commands/as-test.md +21 -0
  28. package/.versions/0.2.0/.pi/agents/agent-chain.yaml +49 -0
  29. package/.versions/0.2.0/.pi/agents/bowser.md +19 -0
  30. package/.versions/0.2.0/.pi/agents/pi-pi/agent-expert.md +98 -0
  31. package/.versions/0.2.0/.pi/agents/pi-pi/cli-expert.md +41 -0
  32. package/.versions/0.2.0/.pi/agents/pi-pi/config-expert.md +63 -0
  33. package/.versions/0.2.0/.pi/agents/pi-pi/ext-expert.md +43 -0
  34. package/.versions/0.2.0/.pi/agents/pi-pi/keybinding-expert.md +134 -0
  35. package/.versions/0.2.0/.pi/agents/pi-pi/pi-orchestrator.md +57 -0
  36. package/.versions/0.2.0/.pi/agents/pi-pi/prompt-expert.md +70 -0
  37. package/.versions/0.2.0/.pi/agents/pi-pi/skill-expert.md +42 -0
  38. package/.versions/0.2.0/.pi/agents/pi-pi/theme-expert.md +40 -0
  39. package/.versions/0.2.0/.pi/agents/pi-pi/tui-expert.md +85 -0
  40. package/.versions/0.2.0/.pi/agents/teams.yaml +31 -0
  41. package/.versions/0.2.0/.pi/damage-control-rules.yaml +278 -0
  42. package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/README.md +58 -0
  43. package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/index.ts +161 -0
  44. package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/package.json +6 -0
  45. package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/README.md +39 -0
  46. package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/index.ts +61 -0
  47. package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/package.json +6 -0
  48. package/.versions/0.2.0/.pi/extensions/compact-and-continue/README.md +42 -0
  49. package/.versions/0.2.0/.pi/extensions/compact-and-continue/index.ts +120 -0
  50. package/.versions/0.2.0/.pi/extensions/compact-and-continue/package.json +6 -0
  51. package/.versions/0.2.0/.pi/extensions/mcp-bridge/README.md +46 -0
  52. package/.versions/0.2.0/.pi/extensions/mcp-bridge/index.ts +206 -0
  53. package/.versions/0.2.0/.pi/extensions/mcp-bridge/package.json +6 -0
  54. package/.versions/0.2.0/.pi/extensions/package-lock.json +1143 -0
  55. package/.versions/0.2.0/.pi/extensions/package.json +9 -0
  56. package/.versions/0.2.0/.pi/harnesses/agent-chain/README.md +37 -0
  57. package/.versions/0.2.0/.pi/harnesses/agent-chain/index.ts +795 -0
  58. package/.versions/0.2.0/.pi/harnesses/agent-chain/package.json +6 -0
  59. package/.versions/0.2.0/.pi/harnesses/agent-team/README.md +38 -0
  60. package/.versions/0.2.0/.pi/harnesses/agent-team/index.ts +732 -0
  61. package/.versions/0.2.0/.pi/harnesses/agent-team/package.json +6 -0
  62. package/.versions/0.2.0/.pi/harnesses/coms/README.md +36 -0
  63. package/.versions/0.2.0/.pi/harnesses/coms/index.ts +1595 -0
  64. package/.versions/0.2.0/.pi/harnesses/coms/package.json +6 -0
  65. package/.versions/0.2.0/.pi/harnesses/coms-net/README.md +46 -0
  66. package/.versions/0.2.0/.pi/harnesses/coms-net/index.ts +1637 -0
  67. package/.versions/0.2.0/.pi/harnesses/coms-net/package.json +6 -0
  68. package/.versions/0.2.0/.pi/harnesses/damage-control/README.md +38 -0
  69. package/.versions/0.2.0/.pi/harnesses/damage-control/index.ts +207 -0
  70. package/.versions/0.2.0/.pi/harnesses/damage-control/package.json +6 -0
  71. package/.versions/0.2.0/.pi/harnesses/damage-control-continue/README.md +37 -0
  72. package/.versions/0.2.0/.pi/harnesses/damage-control-continue/index.ts +234 -0
  73. package/.versions/0.2.0/.pi/harnesses/damage-control-continue/package.json +6 -0
  74. package/.versions/0.2.0/.pi/harnesses/minimal/README.md +27 -0
  75. package/.versions/0.2.0/.pi/harnesses/minimal/index.ts +32 -0
  76. package/.versions/0.2.0/.pi/harnesses/minimal/package.json +6 -0
  77. package/.versions/0.2.0/.pi/harnesses/package-lock.json +35 -0
  78. package/.versions/0.2.0/.pi/harnesses/package.json +9 -0
  79. package/.versions/0.2.0/.pi/harnesses/pi-pi/README.md +39 -0
  80. package/.versions/0.2.0/.pi/harnesses/pi-pi/index.ts +631 -0
  81. package/.versions/0.2.0/.pi/harnesses/pi-pi/package.json +6 -0
  82. package/.versions/0.2.0/.pi/harnesses/purpose-gate/README.md +27 -0
  83. package/.versions/0.2.0/.pi/harnesses/purpose-gate/index.ts +82 -0
  84. package/.versions/0.2.0/.pi/harnesses/purpose-gate/package.json +6 -0
  85. package/.versions/0.2.0/.pi/harnesses/session-replay/README.md +28 -0
  86. package/.versions/0.2.0/.pi/harnesses/session-replay/index.ts +214 -0
  87. package/.versions/0.2.0/.pi/harnesses/session-replay/package.json +6 -0
  88. package/.versions/0.2.0/.pi/harnesses/subagent-widget/README.md +36 -0
  89. package/.versions/0.2.0/.pi/harnesses/subagent-widget/index.ts +479 -0
  90. package/.versions/0.2.0/.pi/harnesses/subagent-widget/package.json +6 -0
  91. package/.versions/0.2.0/.pi/harnesses/system-select/README.md +39 -0
  92. package/.versions/0.2.0/.pi/harnesses/system-select/index.ts +165 -0
  93. package/.versions/0.2.0/.pi/harnesses/system-select/package.json +6 -0
  94. package/.versions/0.2.0/.pi/harnesses/tilldone/README.md +35 -0
  95. package/.versions/0.2.0/.pi/harnesses/tilldone/index.ts +724 -0
  96. package/.versions/0.2.0/.pi/harnesses/tilldone/package.json +6 -0
  97. package/.versions/0.2.0/.pi/harnesses/tool-counter/README.md +31 -0
  98. package/.versions/0.2.0/.pi/harnesses/tool-counter/index.ts +100 -0
  99. package/.versions/0.2.0/.pi/harnesses/tool-counter/package.json +6 -0
  100. package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/README.md +27 -0
  101. package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/index.ts +66 -0
  102. package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/package.json +6 -0
  103. package/.versions/0.2.0/.pi/prompts/build.md +24 -0
  104. package/.versions/0.2.0/.pi/prompts/code-simplify.md +22 -0
  105. package/.versions/0.2.0/.pi/prompts/doctor-agent-skills.md +13 -0
  106. package/.versions/0.2.0/.pi/prompts/plan.md +16 -0
  107. package/.versions/0.2.0/.pi/prompts/review.md +16 -0
  108. package/.versions/0.2.0/.pi/prompts/setup-agent-skills.md +19 -0
  109. package/.versions/0.2.0/.pi/prompts/ship.md +17 -0
  110. package/.versions/0.2.0/.pi/prompts/spec.md +15 -0
  111. package/.versions/0.2.0/.pi/prompts/test.md +19 -0
  112. package/.versions/0.2.0/.pi/skills/bowser/SKILL.md +114 -0
  113. package/.versions/0.2.0/.version +1 -0
  114. package/.versions/0.2.0/agents/builder.md +6 -0
  115. package/.versions/0.2.0/agents/code-reviewer.md +93 -0
  116. package/.versions/0.2.0/agents/documenter.md +6 -0
  117. package/.versions/0.2.0/agents/plan-reviewer.md +22 -0
  118. package/.versions/0.2.0/agents/planner.md +6 -0
  119. package/.versions/0.2.0/agents/scout.md +6 -0
  120. package/.versions/0.2.0/agents/security-auditor.md +97 -0
  121. package/.versions/0.2.0/agents/test-engineer.md +89 -0
  122. package/.versions/0.2.0/hooks/SIMPLIFY-IGNORE.md +90 -0
  123. package/.versions/0.2.0/hooks/hooks.json +14 -0
  124. package/.versions/0.2.0/hooks/session-start.sh +74 -0
  125. package/.versions/0.2.0/hooks/simplify-ignore-test.sh +247 -0
  126. package/.versions/0.2.0/hooks/simplify-ignore.sh +302 -0
  127. package/.versions/0.2.0/references/accessibility-checklist.md +159 -0
  128. package/.versions/0.2.0/references/performance-checklist.md +121 -0
  129. package/.versions/0.2.0/references/prompting-patterns.md +380 -0
  130. package/.versions/0.2.0/references/security-checklist.md +134 -0
  131. package/.versions/0.2.0/references/testing-patterns.md +236 -0
  132. package/.versions/0.2.0/skills/api-and-interface-design/SKILL.md +294 -0
  133. package/.versions/0.2.0/skills/browser-testing-with-devtools/SKILL.md +335 -0
  134. package/.versions/0.2.0/skills/ci-cd-and-automation/SKILL.md +390 -0
  135. package/.versions/0.2.0/skills/code-review-and-quality/SKILL.md +347 -0
  136. package/.versions/0.2.0/skills/code-simplification/SKILL.md +331 -0
  137. package/.versions/0.2.0/skills/context-engineering/SKILL.md +291 -0
  138. package/.versions/0.2.0/skills/debugging-and-error-recovery/SKILL.md +300 -0
  139. package/.versions/0.2.0/skills/deprecation-and-migration/SKILL.md +206 -0
  140. package/.versions/0.2.0/skills/designing-agents/SKILL.md +394 -0
  141. package/.versions/0.2.0/skills/designing-agents/pi-harness-authoring.md +213 -0
  142. package/.versions/0.2.0/skills/documentation-and-adrs/SKILL.md +278 -0
  143. package/.versions/0.2.0/skills/frontend-ui-engineering/SKILL.md +322 -0
  144. package/.versions/0.2.0/skills/git-workflow-and-versioning/SKILL.md +316 -0
  145. package/.versions/0.2.0/skills/guided-workspace-setup/SKILL.md +331 -0
  146. package/.versions/0.2.0/skills/idea-refine/SKILL.md +178 -0
  147. package/.versions/0.2.0/skills/idea-refine/examples.md +238 -0
  148. package/.versions/0.2.0/skills/idea-refine/frameworks.md +99 -0
  149. package/.versions/0.2.0/skills/idea-refine/refinement-criteria.md +113 -0
  150. package/.versions/0.2.0/skills/idea-refine/scripts/idea-refine.sh +15 -0
  151. package/.versions/0.2.0/skills/incremental-implementation/SKILL.md +279 -0
  152. package/.versions/0.2.0/skills/performance-optimization/SKILL.md +350 -0
  153. package/.versions/0.2.0/skills/planning-and-task-breakdown/SKILL.md +237 -0
  154. package/.versions/0.2.0/skills/security-and-hardening/SKILL.md +349 -0
  155. package/.versions/0.2.0/skills/shipping-and-launch/SKILL.md +309 -0
  156. package/.versions/0.2.0/skills/source-driven-development/SKILL.md +194 -0
  157. package/.versions/0.2.0/skills/spec-driven-development/SKILL.md +237 -0
  158. package/.versions/0.2.0/skills/test-driven-development/SKILL.md +379 -0
  159. package/.versions/0.2.0/skills/using-agent-skills/SKILL.md +176 -0
  160. package/.versions/0.3.0/.claude/commands/build.md +18 -0
  161. package/.versions/0.3.0/.claude/commands/code-simplify.md +22 -0
  162. package/.versions/0.3.0/.claude/commands/design-agent.md +14 -0
  163. package/.versions/0.3.0/.claude/commands/doctor-agent-skills.md +13 -0
  164. package/.versions/0.3.0/.claude/commands/plan.md +16 -0
  165. package/.versions/0.3.0/.claude/commands/prime.md +22 -0
  166. package/.versions/0.3.0/.claude/commands/review.md +16 -0
  167. package/.versions/0.3.0/.claude/commands/setup-agent-skills.md +19 -0
  168. package/.versions/0.3.0/.claude/commands/ship.md +17 -0
  169. package/.versions/0.3.0/.claude/commands/spec.md +15 -0
  170. package/.versions/0.3.0/.claude/commands/test.md +19 -0
  171. package/.versions/0.3.0/.opencode/commands/as-build.md +17 -0
  172. package/.versions/0.3.0/.opencode/commands/as-code-simplify.md +16 -0
  173. package/.versions/0.3.0/.opencode/commands/as-design-agent.md +15 -0
  174. package/.versions/0.3.0/.opencode/commands/as-doctor-agent-skills.md +11 -0
  175. package/.versions/0.3.0/.opencode/commands/as-plan.md +16 -0
  176. package/.versions/0.3.0/.opencode/commands/as-prime.md +22 -0
  177. package/.versions/0.3.0/.opencode/commands/as-review.md +15 -0
  178. package/.versions/0.3.0/.opencode/commands/as-setup-agent-skills.md +11 -0
  179. package/.versions/0.3.0/.opencode/commands/as-ship.md +16 -0
  180. package/.versions/0.3.0/.opencode/commands/as-spec.md +16 -0
  181. package/.versions/0.3.0/.opencode/commands/as-test.md +21 -0
  182. package/.versions/0.3.0/.pi/agents/agent-chain.yaml +49 -0
  183. package/.versions/0.3.0/.pi/agents/bowser.md +19 -0
  184. package/.versions/0.3.0/.pi/agents/pi-pi/agent-expert.md +98 -0
  185. package/.versions/0.3.0/.pi/agents/pi-pi/cli-expert.md +41 -0
  186. package/.versions/0.3.0/.pi/agents/pi-pi/config-expert.md +63 -0
  187. package/.versions/0.3.0/.pi/agents/pi-pi/ext-expert.md +43 -0
  188. package/.versions/0.3.0/.pi/agents/pi-pi/keybinding-expert.md +134 -0
  189. package/.versions/0.3.0/.pi/agents/pi-pi/pi-orchestrator.md +57 -0
  190. package/.versions/0.3.0/.pi/agents/pi-pi/prompt-expert.md +70 -0
  191. package/.versions/0.3.0/.pi/agents/pi-pi/skill-expert.md +42 -0
  192. package/.versions/0.3.0/.pi/agents/pi-pi/theme-expert.md +40 -0
  193. package/.versions/0.3.0/.pi/agents/pi-pi/tui-expert.md +85 -0
  194. package/.versions/0.3.0/.pi/agents/teams.yaml +31 -0
  195. package/.versions/0.3.0/.pi/damage-control-rules.yaml +278 -0
  196. package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/README.md +58 -0
  197. package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/index.ts +161 -0
  198. package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/package.json +6 -0
  199. package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/README.md +39 -0
  200. package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/index.ts +61 -0
  201. package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/package.json +6 -0
  202. package/.versions/0.3.0/.pi/extensions/compact-and-continue/README.md +42 -0
  203. package/.versions/0.3.0/.pi/extensions/compact-and-continue/index.ts +120 -0
  204. package/.versions/0.3.0/.pi/extensions/compact-and-continue/package.json +6 -0
  205. package/.versions/0.3.0/.pi/extensions/mcp-bridge/README.md +46 -0
  206. package/.versions/0.3.0/.pi/extensions/mcp-bridge/index.ts +206 -0
  207. package/.versions/0.3.0/.pi/extensions/mcp-bridge/package.json +6 -0
  208. package/.versions/0.3.0/.pi/extensions/package-lock.json +1143 -0
  209. package/.versions/0.3.0/.pi/extensions/package.json +9 -0
  210. package/.versions/0.3.0/.pi/harnesses/agent-chain/README.md +37 -0
  211. package/.versions/0.3.0/.pi/harnesses/agent-chain/index.ts +795 -0
  212. package/.versions/0.3.0/.pi/harnesses/agent-chain/package.json +6 -0
  213. package/.versions/0.3.0/.pi/harnesses/agent-team/README.md +38 -0
  214. package/.versions/0.3.0/.pi/harnesses/agent-team/index.ts +732 -0
  215. package/.versions/0.3.0/.pi/harnesses/agent-team/package.json +6 -0
  216. package/.versions/0.3.0/.pi/harnesses/coms/README.md +36 -0
  217. package/.versions/0.3.0/.pi/harnesses/coms/index.ts +1595 -0
  218. package/.versions/0.3.0/.pi/harnesses/coms/package.json +6 -0
  219. package/.versions/0.3.0/.pi/harnesses/coms-net/README.md +46 -0
  220. package/.versions/0.3.0/.pi/harnesses/coms-net/index.ts +1637 -0
  221. package/.versions/0.3.0/.pi/harnesses/coms-net/package.json +6 -0
  222. package/.versions/0.3.0/.pi/harnesses/damage-control/README.md +38 -0
  223. package/.versions/0.3.0/.pi/harnesses/damage-control/index.ts +207 -0
  224. package/.versions/0.3.0/.pi/harnesses/damage-control/package.json +6 -0
  225. package/.versions/0.3.0/.pi/harnesses/damage-control-continue/README.md +37 -0
  226. package/.versions/0.3.0/.pi/harnesses/damage-control-continue/index.ts +234 -0
  227. package/.versions/0.3.0/.pi/harnesses/damage-control-continue/package.json +6 -0
  228. package/.versions/0.3.0/.pi/harnesses/minimal/README.md +27 -0
  229. package/.versions/0.3.0/.pi/harnesses/minimal/index.ts +32 -0
  230. package/.versions/0.3.0/.pi/harnesses/minimal/package.json +6 -0
  231. package/.versions/0.3.0/.pi/harnesses/package-lock.json +35 -0
  232. package/.versions/0.3.0/.pi/harnesses/package.json +9 -0
  233. package/.versions/0.3.0/.pi/harnesses/pi-pi/README.md +39 -0
  234. package/.versions/0.3.0/.pi/harnesses/pi-pi/index.ts +631 -0
  235. package/.versions/0.3.0/.pi/harnesses/pi-pi/package.json +6 -0
  236. package/.versions/0.3.0/.pi/harnesses/purpose-gate/README.md +27 -0
  237. package/.versions/0.3.0/.pi/harnesses/purpose-gate/index.ts +82 -0
  238. package/.versions/0.3.0/.pi/harnesses/purpose-gate/package.json +6 -0
  239. package/.versions/0.3.0/.pi/harnesses/session-replay/README.md +28 -0
  240. package/.versions/0.3.0/.pi/harnesses/session-replay/index.ts +214 -0
  241. package/.versions/0.3.0/.pi/harnesses/session-replay/package.json +6 -0
  242. package/.versions/0.3.0/.pi/harnesses/subagent-widget/README.md +36 -0
  243. package/.versions/0.3.0/.pi/harnesses/subagent-widget/index.ts +479 -0
  244. package/.versions/0.3.0/.pi/harnesses/subagent-widget/package.json +6 -0
  245. package/.versions/0.3.0/.pi/harnesses/system-select/README.md +39 -0
  246. package/.versions/0.3.0/.pi/harnesses/system-select/index.ts +165 -0
  247. package/.versions/0.3.0/.pi/harnesses/system-select/package.json +6 -0
  248. package/.versions/0.3.0/.pi/harnesses/tilldone/README.md +35 -0
  249. package/.versions/0.3.0/.pi/harnesses/tilldone/index.ts +724 -0
  250. package/.versions/0.3.0/.pi/harnesses/tilldone/package.json +6 -0
  251. package/.versions/0.3.0/.pi/harnesses/tool-counter/README.md +31 -0
  252. package/.versions/0.3.0/.pi/harnesses/tool-counter/index.ts +100 -0
  253. package/.versions/0.3.0/.pi/harnesses/tool-counter/package.json +6 -0
  254. package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/README.md +27 -0
  255. package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/index.ts +66 -0
  256. package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/package.json +6 -0
  257. package/.versions/0.3.0/.pi/prompts/build.md +24 -0
  258. package/.versions/0.3.0/.pi/prompts/code-simplify.md +22 -0
  259. package/.versions/0.3.0/.pi/prompts/doctor-agent-skills.md +13 -0
  260. package/.versions/0.3.0/.pi/prompts/plan.md +16 -0
  261. package/.versions/0.3.0/.pi/prompts/review.md +16 -0
  262. package/.versions/0.3.0/.pi/prompts/setup-agent-skills.md +19 -0
  263. package/.versions/0.3.0/.pi/prompts/ship.md +17 -0
  264. package/.versions/0.3.0/.pi/prompts/spec.md +15 -0
  265. package/.versions/0.3.0/.pi/prompts/test.md +19 -0
  266. package/.versions/0.3.0/.pi/skills/bowser/SKILL.md +114 -0
  267. package/.versions/0.3.0/.version +1 -0
  268. package/.versions/0.3.0/agents/builder.md +6 -0
  269. package/.versions/0.3.0/agents/code-reviewer.md +93 -0
  270. package/.versions/0.3.0/agents/documenter.md +6 -0
  271. package/.versions/0.3.0/agents/plan-reviewer.md +22 -0
  272. package/.versions/0.3.0/agents/planner.md +6 -0
  273. package/.versions/0.3.0/agents/scout.md +6 -0
  274. package/.versions/0.3.0/agents/security-auditor.md +97 -0
  275. package/.versions/0.3.0/agents/test-engineer.md +89 -0
  276. package/.versions/0.3.0/hooks/SIMPLIFY-IGNORE.md +90 -0
  277. package/.versions/0.3.0/hooks/hooks.json +14 -0
  278. package/.versions/0.3.0/hooks/session-start.sh +74 -0
  279. package/.versions/0.3.0/hooks/simplify-ignore-test.sh +247 -0
  280. package/.versions/0.3.0/hooks/simplify-ignore.sh +302 -0
  281. package/.versions/0.3.0/references/accessibility-checklist.md +159 -0
  282. package/.versions/0.3.0/references/performance-checklist.md +121 -0
  283. package/.versions/0.3.0/references/prompting-patterns.md +380 -0
  284. package/.versions/0.3.0/references/security-checklist.md +134 -0
  285. package/.versions/0.3.0/references/testing-patterns.md +236 -0
  286. package/.versions/0.3.0/skills/api-and-interface-design/SKILL.md +294 -0
  287. package/.versions/0.3.0/skills/browser-testing-with-devtools/SKILL.md +335 -0
  288. package/.versions/0.3.0/skills/ci-cd-and-automation/SKILL.md +390 -0
  289. package/.versions/0.3.0/skills/code-review-and-quality/SKILL.md +347 -0
  290. package/.versions/0.3.0/skills/code-simplification/SKILL.md +331 -0
  291. package/.versions/0.3.0/skills/context-engineering/SKILL.md +291 -0
  292. package/.versions/0.3.0/skills/debugging-and-error-recovery/SKILL.md +300 -0
  293. package/.versions/0.3.0/skills/deprecation-and-migration/SKILL.md +206 -0
  294. package/.versions/0.3.0/skills/designing-agents/SKILL.md +394 -0
  295. package/.versions/0.3.0/skills/designing-agents/pi-harness-authoring.md +213 -0
  296. package/.versions/0.3.0/skills/documentation-and-adrs/SKILL.md +278 -0
  297. package/.versions/0.3.0/skills/frontend-ui-engineering/SKILL.md +322 -0
  298. package/.versions/0.3.0/skills/git-workflow-and-versioning/SKILL.md +316 -0
  299. package/.versions/0.3.0/skills/guided-workspace-setup/SKILL.md +331 -0
  300. package/.versions/0.3.0/skills/idea-refine/SKILL.md +178 -0
  301. package/.versions/0.3.0/skills/idea-refine/examples.md +238 -0
  302. package/.versions/0.3.0/skills/idea-refine/frameworks.md +99 -0
  303. package/.versions/0.3.0/skills/idea-refine/refinement-criteria.md +113 -0
  304. package/.versions/0.3.0/skills/idea-refine/scripts/idea-refine.sh +15 -0
  305. package/.versions/0.3.0/skills/incremental-implementation/SKILL.md +279 -0
  306. package/.versions/0.3.0/skills/performance-optimization/SKILL.md +350 -0
  307. package/.versions/0.3.0/skills/planning-and-task-breakdown/SKILL.md +237 -0
  308. package/.versions/0.3.0/skills/security-and-hardening/SKILL.md +349 -0
  309. package/.versions/0.3.0/skills/shipping-and-launch/SKILL.md +309 -0
  310. package/.versions/0.3.0/skills/source-driven-development/SKILL.md +194 -0
  311. package/.versions/0.3.0/skills/spec-driven-development/SKILL.md +237 -0
  312. package/.versions/0.3.0/skills/test-driven-development/SKILL.md +379 -0
  313. package/.versions/0.3.0/skills/using-agent-skills/SKILL.md +176 -0
  314. package/CHANGELOG.md +108 -0
  315. package/README.md +5 -5
  316. package/bin/cli.js +133 -22
  317. package/bin/lib/bootstrap.js +254 -0
  318. package/bin/lib/doctor.js +1 -1
  319. package/bin/lib/update-notifier.js +195 -0
  320. package/docs/getting-started.md +2 -2
  321. package/docs/npm-install.md +91 -8
  322. package/hooks/session-start.sh +66 -12
  323. package/package.json +1 -1
  324. package/skills/guided-workspace-setup/SKILL.md +41 -3
  325. /package/.claude/commands/{setup.md → setup-agent-skills.md} +0 -0
  326. /package/.opencode/commands/{as-doctor.md → as-doctor-agent-skills.md} +0 -0
  327. /package/.opencode/commands/{as-setup.md → as-setup-agent-skills.md} +0 -0
  328. /package/.pi/prompts/{setup.md → setup-agent-skills.md} +0 -0
@@ -0,0 +1,479 @@
1
+ /**
2
+ * Subagent Widget — /sub, /subclear, /subrm, /subcont commands with stacking live widgets
3
+ *
4
+ * Each /sub spawns a background Pi subagent with its own persistent session,
5
+ * enabling conversation continuations via /subcont.
6
+ *
7
+ * Usage: pi -e extensions/subagent-widget.ts
8
+ * Then:
9
+ * /sub list files and summarize — spawn a new subagent
10
+ * /subcont 1 now write tests for it — continue subagent #1's conversation
11
+ * /subrm 2 — remove subagent #2 widget
12
+ * /subclear — clear all subagent widgets
13
+ */
14
+
15
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
16
+ import { DynamicBorder } from "@mariozechner/pi-coding-agent";
17
+ import { Container, Text } from "@mariozechner/pi-tui";
18
+ import { Type } from "@sinclair/typebox";
19
+ const { spawn } = require("child_process") as any;
20
+ import * as fs from "fs";
21
+ import * as os from "os";
22
+ import * as path from "path";
23
+
24
+ interface SubState {
25
+ id: number;
26
+ status: "running" | "done" | "error";
27
+ task: string;
28
+ textChunks: string[];
29
+ toolCount: number;
30
+ elapsed: number;
31
+ sessionFile: string; // persistent JSONL session path — used by /subcont to resume
32
+ turnCount: number; // increments each time /subcont continues this agent
33
+ proc?: any; // active ChildProcess ref (for kill on /subrm)
34
+ }
35
+
36
+ export default function (pi: ExtensionAPI) {
37
+ const agents: Map<number, SubState> = new Map();
38
+ let nextId = 1;
39
+ let widgetCtx: any;
40
+
41
+ // ── Session file helpers ──────────────────────────────────────────────────
42
+
43
+ function makeSessionFile(id: number): string {
44
+ const dir = path.join(os.homedir(), ".pi", "agent", "sessions", "subagents");
45
+ fs.mkdirSync(dir, { recursive: true });
46
+ return path.join(dir, `subagent-${id}-${Date.now()}.jsonl`);
47
+ }
48
+
49
+ // ── Widget rendering ──────────────────────────────────────────────────────
50
+
51
+ function updateWidgets() {
52
+ if (!widgetCtx) return;
53
+
54
+ for (const [id, state] of Array.from(agents.entries())) {
55
+ const key = `sub-${id}`;
56
+ widgetCtx.ui.setWidget(key, (_tui: any, theme: any) => {
57
+ const container = new Container();
58
+ const borderFn = (s: string) => theme.fg("dim", s);
59
+
60
+ container.addChild(new Text("", 0, 0)); // top margin
61
+ container.addChild(new DynamicBorder(borderFn));
62
+ const content = new Text("", 1, 0);
63
+ container.addChild(content);
64
+ container.addChild(new DynamicBorder(borderFn));
65
+
66
+ return {
67
+ render(width: number): string[] {
68
+ const lines: string[] = [];
69
+ const statusColor = state.status === "running" ? "accent"
70
+ : state.status === "done" ? "success" : "error";
71
+ const statusIcon = state.status === "running" ? "●"
72
+ : state.status === "done" ? "✓" : "✗";
73
+
74
+ const taskPreview = state.task.length > 40
75
+ ? state.task.slice(0, 37) + "..."
76
+ : state.task;
77
+
78
+ const turnLabel = state.turnCount > 1
79
+ ? theme.fg("dim", ` · Turn ${state.turnCount}`)
80
+ : "";
81
+
82
+ lines.push(
83
+ theme.fg(statusColor, `${statusIcon} Subagent #${state.id}`) +
84
+ turnLabel +
85
+ theme.fg("dim", ` ${taskPreview}`) +
86
+ theme.fg("dim", ` (${Math.round(state.elapsed / 1000)}s)`) +
87
+ theme.fg("dim", ` | Tools: ${state.toolCount}`)
88
+ );
89
+
90
+ const fullText = state.textChunks.join("");
91
+ const lastLine = fullText.split("\n").filter((l: string) => l.trim()).pop() || "";
92
+ if (lastLine) {
93
+ const trimmed = lastLine.length > width - 10
94
+ ? lastLine.slice(0, width - 13) + "..."
95
+ : lastLine;
96
+ lines.push(theme.fg("muted", ` ${trimmed}`));
97
+ }
98
+
99
+ content.setText(lines.join("\n"));
100
+ return container.render(width);
101
+ },
102
+ invalidate() {
103
+ container.invalidate();
104
+ },
105
+ };
106
+ });
107
+ }
108
+ }
109
+
110
+ // ── Streaming helpers ─────────────────────────────────────────────────────
111
+
112
+ function processLine(state: SubState, line: string) {
113
+ if (!line.trim()) return;
114
+ try {
115
+ const event = JSON.parse(line);
116
+ const type = event.type;
117
+
118
+ if (type === "message_update") {
119
+ const delta = event.assistantMessageEvent;
120
+ if (delta?.type === "text_delta") {
121
+ state.textChunks.push(delta.delta || "");
122
+ updateWidgets();
123
+ }
124
+ } else if (type === "tool_execution_start") {
125
+ state.toolCount++;
126
+ updateWidgets();
127
+ }
128
+ } catch {}
129
+ }
130
+
131
+ function spawnAgent(
132
+ state: SubState,
133
+ prompt: string,
134
+ ctx: any,
135
+ ): Promise<void> {
136
+ const model = ctx.model
137
+ ? `${ctx.model.provider}/${ctx.model.id}`
138
+ : "openrouter/google/gemini-3-flash-preview";
139
+
140
+ return new Promise<void>((resolve) => {
141
+ const proc = spawn("pi", [
142
+ "--mode", "json",
143
+ "-p",
144
+ "--session", state.sessionFile, // persistent session for /subcont resumption
145
+ "--no-extensions",
146
+ "--model", model,
147
+ "--tools", "read,bash,grep,find,ls",
148
+ "--thinking", "off",
149
+ prompt,
150
+ ], {
151
+ stdio: ["ignore", "pipe", "pipe"],
152
+ env: { ...process.env },
153
+ });
154
+
155
+ state.proc = proc;
156
+
157
+ const startTime = Date.now();
158
+ const timer = setInterval(() => {
159
+ state.elapsed = Date.now() - startTime;
160
+ updateWidgets();
161
+ }, 1000);
162
+
163
+ let buffer = "";
164
+
165
+ proc.stdout!.setEncoding("utf-8");
166
+ proc.stdout!.on("data", (chunk: string) => {
167
+ buffer += chunk;
168
+ const lines = buffer.split("\n");
169
+ buffer = lines.pop() || "";
170
+ for (const line of lines) processLine(state, line);
171
+ });
172
+
173
+ proc.stderr!.setEncoding("utf-8");
174
+ proc.stderr!.on("data", (chunk: string) => {
175
+ if (chunk.trim()) {
176
+ state.textChunks.push(chunk);
177
+ updateWidgets();
178
+ }
179
+ });
180
+
181
+ proc.on("close", (code) => {
182
+ if (buffer.trim()) processLine(state, buffer);
183
+ clearInterval(timer);
184
+ state.elapsed = Date.now() - startTime;
185
+ state.status = code === 0 ? "done" : "error";
186
+ state.proc = undefined;
187
+ updateWidgets();
188
+
189
+ const result = state.textChunks.join("");
190
+ ctx.ui.notify(
191
+ `Subagent #${state.id} ${state.status} in ${Math.round(state.elapsed / 1000)}s`,
192
+ state.status === "done" ? "success" : "error"
193
+ );
194
+
195
+ pi.sendMessage({
196
+ customType: "subagent-result",
197
+ content: `Subagent #${state.id}${state.turnCount > 1 ? ` (Turn ${state.turnCount})` : ""} finished "${prompt}" in ${Math.round(state.elapsed / 1000)}s.\n\nResult:\n${result.slice(0, 8000)}${result.length > 8000 ? "\n\n... [truncated]" : ""}`,
198
+ display: true,
199
+ }, { deliverAs: "followUp", triggerTurn: true });
200
+
201
+ resolve();
202
+ });
203
+
204
+ proc.on("error", (err) => {
205
+ clearInterval(timer);
206
+ state.status = "error";
207
+ state.proc = undefined;
208
+ state.textChunks.push(`Error: ${err.message}`);
209
+ updateWidgets();
210
+ resolve();
211
+ });
212
+ });
213
+ }
214
+
215
+ // ── Tools for the Main Agent ──────────────────────────────────────────────
216
+
217
+ pi.registerTool({
218
+ name: "subagent_create",
219
+ description: "Spawn a background subagent to perform a task. Returns the subagent ID immediately while it runs in the background. Results will be delivered as a follow-up message when finished.",
220
+ parameters: Type.Object({
221
+ task: Type.String({ description: "The complete task description for the subagent to perform" }),
222
+ }),
223
+ execute: async (callId, args, _signal, _onUpdate, ctx) => {
224
+ widgetCtx = ctx;
225
+ const id = nextId++;
226
+ const state: SubState = {
227
+ id,
228
+ status: "running",
229
+ task: args.task,
230
+ textChunks: [],
231
+ toolCount: 0,
232
+ elapsed: 0,
233
+ sessionFile: makeSessionFile(id),
234
+ turnCount: 1,
235
+ };
236
+ agents.set(id, state);
237
+ updateWidgets();
238
+
239
+ // Fire-and-forget
240
+ spawnAgent(state, args.task, ctx);
241
+
242
+ return {
243
+ content: [{ type: "text", text: `Subagent #${id} spawned and running in background.` }],
244
+ };
245
+ },
246
+ });
247
+
248
+ pi.registerTool({
249
+ name: "subagent_continue",
250
+ description: "Continue an existing subagent's conversation. Use this to give further instructions to a finished subagent. Returns immediately while it runs in the background.",
251
+ parameters: Type.Object({
252
+ id: Type.Number({ description: "The ID of the subagent to continue" }),
253
+ prompt: Type.String({ description: "The follow-up prompt or new instructions" }),
254
+ }),
255
+ execute: async (callId, args, _signal, _onUpdate, ctx) => {
256
+ widgetCtx = ctx;
257
+ const state = agents.get(args.id);
258
+ if (!state) {
259
+ return { content: [{ type: "text", text: `Error: No subagent #${args.id} found.` }] };
260
+ }
261
+ if (state.status === "running") {
262
+ return { content: [{ type: "text", text: `Error: Subagent #${args.id} is still running.` }] };
263
+ }
264
+
265
+ state.status = "running";
266
+ state.task = args.prompt;
267
+ state.textChunks = [];
268
+ state.elapsed = 0;
269
+ state.turnCount++;
270
+ updateWidgets();
271
+
272
+ ctx.ui.notify(`Continuing Subagent #${args.id} (Turn ${state.turnCount})…`, "info");
273
+ spawnAgent(state, args.prompt, ctx);
274
+
275
+ return {
276
+ content: [{ type: "text", text: `Subagent #${args.id} continuing conversation in background.` }],
277
+ };
278
+ },
279
+ });
280
+
281
+ pi.registerTool({
282
+ name: "subagent_remove",
283
+ description: "Remove a specific subagent. Kills it if it's currently running.",
284
+ parameters: Type.Object({
285
+ id: Type.Number({ description: "The ID of the subagent to remove" }),
286
+ }),
287
+ execute: async (callId, args, _signal, _onUpdate, ctx) => {
288
+ widgetCtx = ctx;
289
+ const state = agents.get(args.id);
290
+ if (!state) {
291
+ return { content: [{ type: "text", text: `Error: No subagent #${args.id} found.` }] };
292
+ }
293
+
294
+ if (state.proc && state.status === "running") {
295
+ state.proc.kill("SIGTERM");
296
+ }
297
+ ctx.ui.setWidget(`sub-${args.id}`, undefined);
298
+ agents.delete(args.id);
299
+
300
+ return {
301
+ content: [{ type: "text", text: `Subagent #${args.id} removed successfully.` }],
302
+ };
303
+ },
304
+ });
305
+
306
+ pi.registerTool({
307
+ name: "subagent_list",
308
+ description: "List all active and finished subagents, showing their IDs, tasks, and status.",
309
+ parameters: Type.Object({}),
310
+ execute: async () => {
311
+ if (agents.size === 0) {
312
+ return { content: [{ type: "text", text: "No active subagents." }] };
313
+ }
314
+
315
+ const list = Array.from(agents.values()).map(s =>
316
+ `#${s.id} [${s.status.toUpperCase()}] (Turn ${s.turnCount}) - ${s.task}`
317
+ ).join("\n");
318
+
319
+ return {
320
+ content: [{ type: "text", text: `Subagents:\n${list}` }],
321
+ };
322
+ },
323
+ });
324
+
325
+
326
+
327
+ // ── /sub <task> ───────────────────────────────────────────────────────────
328
+
329
+ pi.registerCommand("sub", {
330
+ description: "Spawn a subagent with live widget: /sub <task>",
331
+ handler: async (args, ctx) => {
332
+ widgetCtx = ctx;
333
+
334
+ const task = args?.trim();
335
+ if (!task) {
336
+ ctx.ui.notify("Usage: /sub <task>", "error");
337
+ return;
338
+ }
339
+
340
+ const id = nextId++;
341
+ const state: SubState = {
342
+ id,
343
+ status: "running",
344
+ task,
345
+ textChunks: [],
346
+ toolCount: 0,
347
+ elapsed: 0,
348
+ sessionFile: makeSessionFile(id),
349
+ turnCount: 1,
350
+ };
351
+ agents.set(id, state);
352
+ updateWidgets();
353
+
354
+ // Fire-and-forget
355
+ spawnAgent(state, task, ctx);
356
+ },
357
+ });
358
+
359
+ // ── /subcont <number> <prompt> ────────────────────────────────────────────
360
+
361
+ pi.registerCommand("subcont", {
362
+ description: "Continue an existing subagent's conversation: /subcont <number> <prompt>",
363
+ handler: async (args, ctx) => {
364
+ widgetCtx = ctx;
365
+
366
+ const trimmed = args?.trim() ?? "";
367
+ const spaceIdx = trimmed.indexOf(" ");
368
+ if (spaceIdx === -1) {
369
+ ctx.ui.notify("Usage: /subcont <number> <prompt>", "error");
370
+ return;
371
+ }
372
+
373
+ const num = parseInt(trimmed.slice(0, spaceIdx), 10);
374
+ const prompt = trimmed.slice(spaceIdx + 1).trim();
375
+
376
+ if (isNaN(num) || !prompt) {
377
+ ctx.ui.notify("Usage: /subcont <number> <prompt>", "error");
378
+ return;
379
+ }
380
+
381
+ const state = agents.get(num);
382
+ if (!state) {
383
+ ctx.ui.notify(`No subagent #${num} found. Use /sub to create one.`, "error");
384
+ return;
385
+ }
386
+
387
+ if (state.status === "running") {
388
+ ctx.ui.notify(`Subagent #${num} is still running — wait for it to finish first.`, "warning");
389
+ return;
390
+ }
391
+
392
+ // Resume: update state for a new turn
393
+ state.status = "running";
394
+ state.task = prompt;
395
+ state.textChunks = [];
396
+ state.elapsed = 0;
397
+ state.turnCount++;
398
+ updateWidgets();
399
+
400
+ ctx.ui.notify(`Continuing Subagent #${num} (Turn ${state.turnCount})…`, "info");
401
+
402
+ // Fire-and-forget — reuses the same sessionFile for conversation history
403
+ spawnAgent(state, prompt, ctx);
404
+ },
405
+ });
406
+
407
+ // ── /subrm <number> ───────────────────────────────────────────────────────
408
+
409
+ pi.registerCommand("subrm", {
410
+ description: "Remove a specific subagent widget: /subrm <number>",
411
+ handler: async (args, ctx) => {
412
+ widgetCtx = ctx;
413
+
414
+ const num = parseInt(args?.trim() ?? "", 10);
415
+ if (isNaN(num)) {
416
+ ctx.ui.notify("Usage: /subrm <number>", "error");
417
+ return;
418
+ }
419
+
420
+ const state = agents.get(num);
421
+ if (!state) {
422
+ ctx.ui.notify(`No subagent #${num} found.`, "error");
423
+ return;
424
+ }
425
+
426
+ // Kill the process if still running
427
+ if (state.proc && state.status === "running") {
428
+ state.proc.kill("SIGTERM");
429
+ ctx.ui.notify(`Subagent #${num} killed and removed.`, "warning");
430
+ } else {
431
+ ctx.ui.notify(`Subagent #${num} removed.`, "info");
432
+ }
433
+
434
+ ctx.ui.setWidget(`sub-${num}`, undefined);
435
+ agents.delete(num);
436
+ },
437
+ });
438
+
439
+ // ── /subclear ─────────────────────────────────────────────────────────────
440
+
441
+ pi.registerCommand("subclear", {
442
+ description: "Clear all subagent widgets",
443
+ handler: async (_args, ctx) => {
444
+ widgetCtx = ctx;
445
+
446
+ let killed = 0;
447
+ for (const [id, state] of Array.from(agents.entries())) {
448
+ if (state.proc && state.status === "running") {
449
+ state.proc.kill("SIGTERM");
450
+ killed++;
451
+ }
452
+ ctx.ui.setWidget(`sub-${id}`, undefined);
453
+ }
454
+
455
+ const total = agents.size;
456
+ agents.clear();
457
+ nextId = 1;
458
+
459
+ const msg = total === 0
460
+ ? "No subagents to clear."
461
+ : `Cleared ${total} subagent${total !== 1 ? "s" : ""}${killed > 0 ? ` (${killed} killed)` : ""}.`;
462
+ ctx.ui.notify(msg, total === 0 ? "info" : "success");
463
+ },
464
+ });
465
+
466
+ // ── Session lifecycle ─────────────────────────────────────────────────────
467
+
468
+ pi.on("session_start", async (_event, ctx) => {
469
+ for (const [id, state] of Array.from(agents.entries())) {
470
+ if (state.proc && state.status === "running") {
471
+ state.proc.kill("SIGTERM");
472
+ }
473
+ ctx.ui.setWidget(`sub-${id}`, undefined);
474
+ }
475
+ agents.clear();
476
+ nextId = 1;
477
+ widgetCtx = ctx;
478
+ });
479
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "agent-skills-pi-subagent-widget",
3
+ "private": true,
4
+ "type": "module",
5
+ "main": "index.ts"
6
+ }
@@ -0,0 +1,39 @@
1
+ # system-select
2
+
3
+ Switch the system prompt via `/system`.
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
+ Scans `.pi/agents/`, `.claude/agents/`, `.gemini/agents/`, and `.codex/agents/` — both
10
+ project-local and global — for agent definition `.md` files. `/system` opens a select
11
+ dialog to pick one; the chosen agent's body is prepended to pi's default instructions so
12
+ tool usage still works, and tools are restricted to the agent's declared tool set when
13
+ one is specified.
14
+
15
+ ## Commands & tools
16
+
17
+ - `/system` — open the agent-persona picker
18
+
19
+ ## Requires
20
+
21
+ - Agent definition `.md` files in any scanned directory. This repo ships a set under
22
+ `.pi/agents/` (`scout`, `planner`, `builder`, `reviewer`, `documenter`, `red-team`, …).
23
+
24
+ ## Usage
25
+
26
+ ```bash
27
+ pi -e .pi/harnesses/system-select/index.ts
28
+ ```
29
+
30
+ Pairs well with `minimal` as a lightweight footer:
31
+
32
+ ```bash
33
+ pi -e .pi/harnesses/system-select/index.ts -e .pi/harnesses/minimal/index.ts
34
+ ```
35
+
36
+ ## Upstream changes
37
+
38
+ - Theme integration removed — the `themeMap.ts` import and the `applyExtensionDefaults()`
39
+ call were stripped (this repo does not ship pi themes).
@@ -0,0 +1,165 @@
1
+ /**
2
+ * System Select — Switch the system prompt via /system
3
+ *
4
+ * Scans .pi/agents/, .claude/agents/, .gemini/agents/, .codex/agents/
5
+ * (project-local and global) for agent definition .md files.
6
+ *
7
+ * /system opens a select dialog to pick a system prompt. The selected
8
+ * agent's body is prepended to Pi's default instructions so tool usage
9
+ * still works. Tools are restricted to the agent's declared tool set
10
+ * if specified.
11
+ *
12
+ * Usage: pi -e extensions/system-select.ts -e extensions/minimal.ts
13
+ */
14
+
15
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
16
+ import { readdirSync, readFileSync, existsSync } from "node:fs";
17
+ import { join, basename } from "node:path";
18
+ import { homedir } from "node:os";
19
+
20
+ interface AgentDef {
21
+ name: string;
22
+ description: string;
23
+ tools: string[];
24
+ body: string;
25
+ source: string;
26
+ }
27
+
28
+ function parseFrontmatter(raw: string): { fields: Record<string, string>; body: string } {
29
+ const match = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
30
+ if (!match) return { fields: {}, body: raw };
31
+ const fields: Record<string, string> = {};
32
+ for (const line of match[1].split("\n")) {
33
+ const idx = line.indexOf(":");
34
+ if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim();
35
+ }
36
+ return { fields, body: match[2] };
37
+ }
38
+
39
+ function scanAgents(dir: string, source: string): AgentDef[] {
40
+ if (!existsSync(dir)) return [];
41
+ const agents: AgentDef[] = [];
42
+ try {
43
+ for (const file of readdirSync(dir)) {
44
+ if (!file.endsWith(".md")) continue;
45
+ const raw = readFileSync(join(dir, file), "utf-8");
46
+ const { fields, body } = parseFrontmatter(raw);
47
+ agents.push({
48
+ name: fields.name || basename(file, ".md"),
49
+ description: fields.description || "",
50
+ tools: fields.tools ? fields.tools.split(",").map((t) => t.trim()) : [],
51
+ body: body.trim(),
52
+ source,
53
+ });
54
+ }
55
+ } catch {}
56
+ return agents;
57
+ }
58
+
59
+ function displayName(name: string): string {
60
+ return name.split("-").map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
61
+ }
62
+
63
+ export default function (pi: ExtensionAPI) {
64
+ let activeAgent: AgentDef | null = null;
65
+ let allAgents: AgentDef[] = [];
66
+ let defaultTools: string[] = [];
67
+
68
+ pi.on("session_start", async (_event, ctx) => {
69
+ activeAgent = null;
70
+ allAgents = [];
71
+
72
+ const home = homedir();
73
+ const cwd = ctx.cwd;
74
+
75
+ const dirs: [string, string][] = [
76
+ [join(cwd, ".pi", "agents"), ".pi"],
77
+ [join(cwd, ".claude", "agents"), ".claude"],
78
+ [join(cwd, ".gemini", "agents"), ".gemini"],
79
+ [join(cwd, ".codex", "agents"), ".codex"],
80
+ [join(home, ".pi", "agent", "agents"), "~/.pi"],
81
+ [join(home, ".claude", "agents"), "~/.claude"],
82
+ [join(home, ".gemini", "agents"), "~/.gemini"],
83
+ [join(home, ".codex", "agents"), "~/.codex"],
84
+ ];
85
+
86
+ const seen = new Set<string>();
87
+ const sourceCounts: Record<string, number> = {};
88
+
89
+ for (const [dir, source] of dirs) {
90
+ const agents = scanAgents(dir, source);
91
+ for (const agent of agents) {
92
+ const key = agent.name.toLowerCase();
93
+ if (seen.has(key)) continue;
94
+ seen.add(key);
95
+ allAgents.push(agent);
96
+ sourceCounts[source] = (sourceCounts[source] || 0) + 1;
97
+ }
98
+ }
99
+
100
+ defaultTools = pi.getActiveTools();
101
+ ctx.ui.setStatus("system-prompt", "System Prompt: Default");
102
+
103
+ const defaultPrompt = ctx.getSystemPrompt();
104
+ const lines = defaultPrompt.split("\n").length;
105
+ const chars = defaultPrompt.length;
106
+
107
+ const loadedSources = Object.entries(sourceCounts)
108
+ .map(([src, count]) => `${count} from ${src}`)
109
+ .join(", ");
110
+
111
+ const notifyLines = [];
112
+ if (allAgents.length > 0) {
113
+ notifyLines.push(`Loaded ${allAgents.length} agents (${loadedSources})`);
114
+ }
115
+ notifyLines.push(`System Prompt: Default (${lines} lines, ${chars} chars)`);
116
+
117
+ ctx.ui.notify(notifyLines.join("\n"), "info");
118
+ });
119
+
120
+ pi.registerCommand("system", {
121
+ description: "Select a system prompt from discovered agents",
122
+ handler: async (_args, ctx) => {
123
+ if (allAgents.length === 0) {
124
+ ctx.ui.notify("No agents found in .*/agents/*.md", "warning");
125
+ return;
126
+ }
127
+
128
+ const options = [
129
+ "Reset to Default",
130
+ ...allAgents.map((a) => `${a.name} — ${a.description} [${a.source}]`),
131
+ ];
132
+
133
+ const choice = await ctx.ui.select("Select System Prompt", options);
134
+ if (choice === undefined) return;
135
+
136
+ if (choice === options[0]) {
137
+ activeAgent = null;
138
+ pi.setActiveTools(defaultTools);
139
+ ctx.ui.setStatus("system-prompt", "System Prompt: Default");
140
+ ctx.ui.notify("System Prompt reset to Default", "success");
141
+ return;
142
+ }
143
+
144
+ const idx = options.indexOf(choice) - 1;
145
+ const agent = allAgents[idx];
146
+ activeAgent = agent;
147
+
148
+ if (agent.tools.length > 0) {
149
+ pi.setActiveTools(agent.tools);
150
+ } else {
151
+ pi.setActiveTools(defaultTools);
152
+ }
153
+
154
+ ctx.ui.setStatus("system-prompt", `System Prompt: ${displayName(agent.name)}`);
155
+ ctx.ui.notify(`System Prompt switched to: ${displayName(agent.name)}`, "success");
156
+ },
157
+ });
158
+
159
+ pi.on("before_agent_start", async (event, _ctx) => {
160
+ if (!activeAgent) return;
161
+ return {
162
+ systemPrompt: activeAgent.body + "\n\n" + event.systemPrompt,
163
+ };
164
+ });
165
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "agent-skills-pi-system-select",
3
+ "private": true,
4
+ "type": "module",
5
+ "main": "index.ts"
6
+ }