@selesai/code 0.5.13 → 0.5.15

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 (297) hide show
  1. package/README.md +186 -0
  2. package/dist/bun/cli.d.ts.map +1 -1
  3. package/dist/bun/cli.js +2 -0
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +3 -1
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/cli/list-models.d.ts +2 -2
  9. package/dist/cli/list-models.d.ts.map +1 -1
  10. package/dist/cli/list-models.js +3 -3
  11. package/dist/cli/list-models.js.map +1 -1
  12. package/dist/config.d.ts +1 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +2 -2
  15. package/dist/config.js.map +1 -1
  16. package/dist/core/agent-session-auto-handoff.test.d.ts.map +1 -1
  17. package/dist/core/agent-session-auto-handoff.test.js +2 -2
  18. package/dist/core/agent-session-auto-handoff.test.js.map +1 -1
  19. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  20. package/dist/core/agent-session-runtime.js +3 -0
  21. package/dist/core/agent-session-runtime.js.map +1 -1
  22. package/dist/core/agent-session-services.d.ts +3 -6
  23. package/dist/core/agent-session-services.d.ts.map +1 -1
  24. package/dist/core/agent-session-services.js +23 -9
  25. package/dist/core/agent-session-services.js.map +1 -1
  26. package/dist/core/agent-session.d.ts +28 -10
  27. package/dist/core/agent-session.d.ts.map +1 -1
  28. package/dist/core/agent-session.js +136 -90
  29. package/dist/core/agent-session.js.map +1 -1
  30. package/dist/core/auth-storage.d.ts +20 -98
  31. package/dist/core/auth-storage.d.ts.map +1 -1
  32. package/dist/core/auth-storage.js +59 -251
  33. package/dist/core/auth-storage.js.map +1 -1
  34. package/dist/core/built-in-extensions.d.ts +3 -0
  35. package/dist/core/built-in-extensions.d.ts.map +1 -0
  36. package/dist/core/built-in-extensions.js +3 -0
  37. package/dist/core/built-in-extensions.js.map +1 -0
  38. package/dist/core/cache-stats.d.ts +2 -2
  39. package/dist/core/cache-stats.d.ts.map +1 -1
  40. package/dist/core/cache-stats.js +1 -1
  41. package/dist/core/cache-stats.js.map +1 -1
  42. package/dist/core/compaction/branch-summarization.d.ts +8 -2
  43. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  44. package/dist/core/compaction/branch-summarization.js +8 -11
  45. package/dist/core/compaction/branch-summarization.js.map +1 -1
  46. package/dist/core/compaction/compaction.d.ts +19 -3
  47. package/dist/core/compaction/compaction.d.ts.map +1 -1
  48. package/dist/core/compaction/compaction.js +63 -26
  49. package/dist/core/compaction/compaction.js.map +1 -1
  50. package/dist/core/compaction/utils.d.ts +1 -1
  51. package/dist/core/compaction/utils.d.ts.map +1 -1
  52. package/dist/core/compaction/utils.js +6 -17
  53. package/dist/core/compaction/utils.js.map +1 -1
  54. package/dist/core/extensions/loader.d.ts.map +1 -1
  55. package/dist/core/extensions/loader.js +21 -4
  56. package/dist/core/extensions/loader.js.map +1 -1
  57. package/dist/core/extensions/runner.d.ts +4 -1
  58. package/dist/core/extensions/runner.d.ts.map +1 -1
  59. package/dist/core/extensions/runner.js +39 -0
  60. package/dist/core/extensions/runner.js.map +1 -1
  61. package/dist/core/extensions/types.d.ts +24 -3
  62. package/dist/core/extensions/types.d.ts.map +1 -1
  63. package/dist/core/extensions/types.js.map +1 -1
  64. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  65. package/dist/core/extensions/wrapper.js +22 -3
  66. package/dist/core/extensions/wrapper.js.map +1 -1
  67. package/dist/core/keybindings.d.ts +8 -3
  68. package/dist/core/keybindings.d.ts.map +1 -1
  69. package/dist/core/keybindings.js +7 -3
  70. package/dist/core/keybindings.js.map +1 -1
  71. package/dist/core/llama/client.d.ts +61 -0
  72. package/dist/core/llama/client.d.ts.map +1 -0
  73. package/dist/core/llama/client.js +302 -0
  74. package/dist/core/llama/client.js.map +1 -0
  75. package/dist/core/llama/huggingface.d.ts +23 -0
  76. package/dist/core/llama/huggingface.d.ts.map +1 -0
  77. package/dist/core/llama/huggingface.js +141 -0
  78. package/dist/core/llama/huggingface.js.map +1 -0
  79. package/dist/core/llama/index.d.ts +3 -0
  80. package/dist/core/llama/index.d.ts.map +1 -0
  81. package/dist/core/llama/index.js +208 -0
  82. package/dist/core/llama/index.js.map +1 -0
  83. package/dist/core/llama/provider.d.ts +10 -0
  84. package/dist/core/llama/provider.d.ts.map +1 -0
  85. package/dist/core/llama/provider.js +102 -0
  86. package/dist/core/llama/provider.js.map +1 -0
  87. package/dist/core/llama/ui.d.ts +42 -0
  88. package/dist/core/llama/ui.d.ts.map +1 -0
  89. package/dist/core/llama/ui.js +416 -0
  90. package/dist/core/llama/ui.js.map +1 -0
  91. package/dist/core/model-config.d.ts +513 -0
  92. package/dist/core/model-config.d.ts.map +1 -0
  93. package/dist/core/model-config.js +272 -0
  94. package/dist/core/model-config.js.map +1 -0
  95. package/dist/core/model-registry.d.ts +20 -126
  96. package/dist/core/model-registry.d.ts.map +1 -1
  97. package/dist/core/model-registry.js +62 -780
  98. package/dist/core/model-registry.js.map +1 -1
  99. package/dist/core/model-resolver.d.ts +6 -6
  100. package/dist/core/model-resolver.d.ts.map +1 -1
  101. package/dist/core/model-resolver.js +21 -18
  102. package/dist/core/model-resolver.js.map +1 -1
  103. package/dist/core/model-runtime.d.ts +83 -0
  104. package/dist/core/model-runtime.d.ts.map +1 -0
  105. package/dist/core/model-runtime.js +451 -0
  106. package/dist/core/model-runtime.js.map +1 -0
  107. package/dist/core/models-store.d.ts +17 -0
  108. package/dist/core/models-store.d.ts.map +1 -0
  109. package/dist/core/models-store.js +45 -0
  110. package/dist/core/models-store.js.map +1 -0
  111. package/dist/core/package-manager.d.ts.map +1 -1
  112. package/dist/core/package-manager.js +7 -2
  113. package/dist/core/package-manager.js.map +1 -1
  114. package/dist/core/prompt-templates.d.ts +1 -0
  115. package/dist/core/prompt-templates.d.ts.map +1 -1
  116. package/dist/core/prompt-templates.js +4 -4
  117. package/dist/core/prompt-templates.js.map +1 -1
  118. package/dist/core/provider-composer.d.ts +55 -0
  119. package/dist/core/provider-composer.d.ts.map +1 -0
  120. package/dist/core/provider-composer.js +375 -0
  121. package/dist/core/provider-composer.js.map +1 -0
  122. package/dist/core/radius.d.ts +2 -0
  123. package/dist/core/radius.d.ts.map +1 -0
  124. package/dist/core/radius.js +2 -0
  125. package/dist/core/radius.js.map +1 -0
  126. package/dist/core/remote-catalog-provider.d.ts +5 -0
  127. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  128. package/dist/core/remote-catalog-provider.js +102 -0
  129. package/dist/core/remote-catalog-provider.js.map +1 -0
  130. package/dist/core/resource-loader.d.ts.map +1 -1
  131. package/dist/core/resource-loader.js +1 -0
  132. package/dist/core/resource-loader.js.map +1 -1
  133. package/dist/core/runtime-credentials.d.ts +17 -0
  134. package/dist/core/runtime-credentials.d.ts.map +1 -0
  135. package/dist/core/runtime-credentials.js +42 -0
  136. package/dist/core/runtime-credentials.js.map +1 -0
  137. package/dist/core/sdk.d.ts +4 -7
  138. package/dist/core/sdk.d.ts.map +1 -1
  139. package/dist/core/sdk.js +18 -25
  140. package/dist/core/sdk.js.map +1 -1
  141. package/dist/core/session-manager.d.ts +12 -7
  142. package/dist/core/session-manager.d.ts.map +1 -1
  143. package/dist/core/session-manager.js +103 -27
  144. package/dist/core/session-manager.js.map +1 -1
  145. package/dist/core/system-prompt.d.ts.map +1 -1
  146. package/dist/core/system-prompt.js +2 -12
  147. package/dist/core/system-prompt.js.map +1 -1
  148. package/dist/core/tools/read.d.ts.map +1 -1
  149. package/dist/core/tools/read.js +1 -1
  150. package/dist/core/tools/read.js.map +1 -1
  151. package/dist/core/usage-totals.d.ts +19 -0
  152. package/dist/core/usage-totals.d.ts.map +1 -0
  153. package/dist/core/usage-totals.js +52 -0
  154. package/dist/core/usage-totals.js.map +1 -0
  155. package/dist/extensions/index.d.ts +3 -0
  156. package/dist/extensions/index.d.ts.map +1 -0
  157. package/dist/extensions/index.js +9 -0
  158. package/dist/extensions/index.js.map +1 -0
  159. package/dist/extensions/llama/client.d.ts +61 -0
  160. package/dist/extensions/llama/client.d.ts.map +1 -0
  161. package/dist/extensions/llama/client.js +309 -0
  162. package/dist/extensions/llama/client.js.map +1 -0
  163. package/dist/extensions/llama/huggingface.d.ts +23 -0
  164. package/dist/extensions/llama/huggingface.d.ts.map +1 -0
  165. package/dist/extensions/llama/huggingface.js +146 -0
  166. package/dist/extensions/llama/huggingface.js.map +1 -0
  167. package/dist/extensions/llama/index.d.ts +3 -0
  168. package/dist/extensions/llama/index.d.ts.map +1 -0
  169. package/dist/extensions/llama/index.js +211 -0
  170. package/dist/extensions/llama/index.js.map +1 -0
  171. package/dist/extensions/llama/provider.d.ts +10 -0
  172. package/dist/extensions/llama/provider.d.ts.map +1 -0
  173. package/dist/extensions/llama/provider.js +106 -0
  174. package/dist/extensions/llama/provider.js.map +1 -0
  175. package/dist/extensions/llama/ui.d.ts +42 -0
  176. package/dist/extensions/llama/ui.d.ts.map +1 -0
  177. package/dist/extensions/llama/ui.js +420 -0
  178. package/dist/extensions/llama/ui.js.map +1 -0
  179. package/dist/extensions/package.json +4 -3
  180. package/dist/extensions/pi-powerline-footer/README.md +1 -1
  181. package/dist/extensions/pi-powerline-footer/guide.ts +227 -0
  182. package/dist/extensions/pi-powerline-footer/index.ts +88 -55
  183. package/dist/extensions/pi-powerline-footer/tests/editor-responsiveness.test.ts +0 -78
  184. package/dist/extensions/pi-powerline-footer/tests/guide.test.ts +102 -0
  185. package/dist/extensions/pi-powerline-footer/welcome.ts +65 -30
  186. package/dist/extensions/tokenin-onboarding.ts +3 -3
  187. package/dist/index.d.ts +4 -3
  188. package/dist/index.d.ts.map +1 -1
  189. package/dist/index.js +3 -3
  190. package/dist/index.js.map +1 -1
  191. package/dist/main.d.ts.map +1 -1
  192. package/dist/main.js +21 -19
  193. package/dist/main.js.map +1 -1
  194. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  195. package/dist/modes/interactive/components/assistant-message.js +22 -10
  196. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  197. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  198. package/dist/modes/interactive/components/custom-editor.js +1 -1
  199. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  200. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  201. package/dist/modes/interactive/components/footer.js +24 -23
  202. package/dist/modes/interactive/components/footer.js.map +1 -1
  203. package/dist/modes/interactive/components/login-dialog.d.ts +5 -5
  204. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  205. package/dist/modes/interactive/components/login-dialog.js +17 -8
  206. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  207. package/dist/modes/interactive/components/model-selector.d.ts +11 -4
  208. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  209. package/dist/modes/interactive/components/model-selector.js +72 -41
  210. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  211. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
  212. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  213. package/dist/modes/interactive/components/oauth-selector.js +14 -27
  214. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  215. package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
  216. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  217. package/dist/modes/interactive/components/tree-selector.js +49 -12
  218. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  219. package/dist/modes/interactive/interactive-mode.d.ts +8 -5
  220. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  221. package/dist/modes/interactive/interactive-mode.js +253 -225
  222. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  223. package/dist/modes/rpc/rpc-client.d.ts +4 -0
  224. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  225. package/dist/modes/rpc/rpc-client.js +7 -0
  226. package/dist/modes/rpc/rpc-client.js.map +1 -1
  227. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  228. package/dist/modes/rpc/rpc-mode.js +6 -2
  229. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  230. package/dist/modes/rpc/rpc-types.d.ts +11 -0
  231. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  232. package/dist/modes/rpc/rpc-types.js.map +1 -1
  233. package/dist/package-manager-cli.d.ts.map +1 -1
  234. package/dist/package-manager-cli.js +67 -5
  235. package/dist/package-manager-cli.js.map +1 -1
  236. package/dist/skills/caveman/SKILL.md +1 -0
  237. package/dist/skills/handoff/SKILL.md +1 -0
  238. package/dist/skills/handoff-text/SKILL.md +1 -0
  239. package/dist/skills/implanger/SKILL.md +1 -0
  240. package/dist/skills/improve-codebase/SKILL.md +1 -0
  241. package/dist/skills/planger/SKILL.md +1 -0
  242. package/dist/skills/ponytail/SKILL.md +1 -0
  243. package/dist/skills/ponytail-audit/SKILL.md +1 -0
  244. package/dist/skills/ponytail-debt/SKILL.md +1 -0
  245. package/dist/skills/ponytail-gain/SKILL.md +1 -0
  246. package/dist/skills/ponytail-help/SKILL.md +1 -0
  247. package/dist/skills/ponytail-review/SKILL.md +1 -0
  248. package/dist/skills/workflow-creation/SKILL.md +1 -0
  249. package/dist/utils/clipboard-native.d.ts +1 -0
  250. package/dist/utils/clipboard-native.d.ts.map +1 -1
  251. package/dist/utils/clipboard-native.js.map +1 -1
  252. package/dist/utils/clipboard.d.ts +2 -0
  253. package/dist/utils/clipboard.d.ts.map +1 -1
  254. package/dist/utils/clipboard.js +13 -0
  255. package/dist/utils/clipboard.js.map +1 -1
  256. package/package.json +26 -5
  257. package/dist/agents/architect.md +0 -217
  258. package/dist/agents/builder.md +0 -120
  259. package/dist/agents/commentator.md +0 -130
  260. package/dist/agents/explorer.md +0 -51
  261. package/dist/agents/recapper.md +0 -26
  262. package/dist/extensions/gitignore-guard.ts +0 -132
  263. package/dist/extensions/hooks/claude-codex-hooks.json +0 -44
  264. package/dist/extensions/hooks/copilot-hooks.json +0 -21
  265. package/dist/extensions/hooks/ponytail-activate.js +0 -91
  266. package/dist/extensions/hooks/ponytail-config.js +0 -122
  267. package/dist/extensions/hooks/ponytail-instructions.js +0 -94
  268. package/dist/extensions/hooks/ponytail-mode-tracker.js +0 -55
  269. package/dist/extensions/hooks/ponytail-runtime.js +0 -68
  270. package/dist/extensions/hooks/ponytail-statusline.ps1 +0 -21
  271. package/dist/extensions/hooks/ponytail-statusline.sh +0 -12
  272. package/dist/extensions/hooks/ponytail-subagent.js +0 -22
  273. package/dist/extensions/pi-extension/index.js +0 -189
  274. package/dist/extensions/pi-extension/package.json +0 -8
  275. package/dist/extensions/pi-extension/test/extension.test.js +0 -167
  276. package/dist/extensions/pi-extension/test/helpers.test.js +0 -92
  277. package/dist/extensions/pi-powerline-footer/welcome-dismiss.ts +0 -34
  278. package/dist/extensions/pi-subagents/agents/context-builder.md +0 -46
  279. package/dist/extensions/pi-subagents/agents/delegate.md +0 -12
  280. package/dist/extensions/pi-subagents/agents/oracle.md +0 -73
  281. package/dist/extensions/pi-subagents/agents/planner.md +0 -55
  282. package/dist/extensions/pi-subagents/agents/reviewer.md +0 -79
  283. package/dist/extensions/pi-subagents/agents/scout.md +0 -50
  284. package/dist/extensions/pi-subagents/agents/worker.md +0 -55
  285. package/dist/extensions/pi-subagents/src/runs/shared/spawn-timing.ts +0 -46
  286. package/dist/extensions/pi-subagents/test/unit/spawn-timing.test.ts +0 -45
  287. package/dist/extensions/pi-subagents/tsconfig.runner.json +0 -17
  288. package/dist/extensions/ponytail-pi-extension/index.js +0 -189
  289. package/dist/extensions/ponytail-pi-extension/package.json +0 -8
  290. package/dist/extensions/ponytail-pi-extension/test/extension.test.js +0 -167
  291. package/dist/extensions/ponytail-pi-extension/test/helpers.test.js +0 -92
  292. package/dist/extensions/prototype.ts +0 -713
  293. package/dist/extensions/question.ts +0 -350
  294. package/dist/extensions/quick.ts +0 -630
  295. package/dist/extensions/tps-tracker.ts +0 -280
  296. package/dist/extensions/workflow/task-validators.ts +0 -69
  297. package/dist/skills/selesai-default/SKILL.md +0 -16
@@ -1,130 +0,0 @@
1
- ---
2
- name: commentator
3
- model: tokenin/kimi-k2.7-code
4
- thinking: high
5
- skill: ponytail, ponytail-review, ponytail-audit
6
- description: Versatile review specialist for code diffs, plans, proposed solutions, codebase health, and PR/issue validation
7
- tools: read, grep, find, ls, bash, edit, write, intercom
8
- systemPromptMode: replace
9
- inheritProjectContext: true
10
- inheritSkills: true
11
- defaultReads: plan.md, progress.md
12
- defaultContext: fork
13
- ---
14
-
15
- You are a disciplined commentator subagent. Your job is to inspect, evaluate, and report findings with evidence. You do not guess; you verify from the code, tests, docs, or requirements.
16
-
17
- ## Review types you handle
18
-
19
- ### 1. Code diffs (changed files)
20
- Inspect the actual diff or changed files. Verify:
21
- - Implementation matches intent and requirements.
22
- - Code is correct, coherent, and handles edge cases.
23
- - Tests cover the change and still pass.
24
- - No unintended side effects or regressions.
25
- - The change is minimal and readable.
26
-
27
- ### 2. Plans
28
- Validate a proposed plan for:
29
- - Feasibility and completeness.
30
- - Missing steps or hidden risks.
31
- - Alignment with existing architecture and constraints.
32
- - Whether the scope is appropriately bounded.
33
-
34
- ### 3. Proposed solutions
35
- Evaluate a suggested approach for:
36
- - Correctness and tradeoffs.
37
- - Fit with existing codebase patterns.
38
- - Whether simpler alternatives exist.
39
- - Edge cases the proposal may miss.
40
-
41
- ### 4. Current overall state of the codebase
42
- Assess codebase health by inspecting key files, tests, and structure. Look for:
43
- - Architecture drift or tech debt.
44
- - Inconsistent patterns or naming.
45
- - Areas lacking tests or documentation.
46
- - Obvious bugs or fragile code.
47
- - Opportunities to simplify or consolidate.
48
-
49
- ### 5. Specific PR or issue
50
- Review a PR or issue by understanding the context, then verifying:
51
- - The fix or feature addresses the root cause.
52
- - Changes are minimal and focused.
53
- - No regressions are introduced.
54
- - Tests and docs are updated as needed.
55
-
56
- ## Working rules
57
- - Read the plan, progress, and relevant files first when available.
58
- - Repo-local `progress.md` files are allowed scratch/memory files. Do not flag them as repo noise, delete them, or ask to remove them just because they are untracked. If they appear in a coding repo, they should remain untracked and be covered by `.gitignore`.
59
- - Use `bash` only for read-only inspection (e.g., `git diff`, `git log`, `git show`, test runs).
60
- - Do not invent issues. Only report problems you can justify from evidence.
61
- - Prefer small corrective edits over broad rewrites.
62
- - If everything looks good, say so plainly.
63
- - If you are asked to maintain progress, record what you checked and what you found.
64
- - If review-only or no-edit instructions conflict with progress-writing instructions, review-only/no-edit wins. Do not write `progress.md`; mention the conflict in your final review only if it matters.
65
-
66
- ## Supervisor coordination
67
- If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing; no-edit wins. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the review plan. Do not send routine completion handoffs; return the completed review normally.
68
-
69
- Fall back to generic `intercom` only if `contact_supervisor` is unavailable and the runtime bridge instructions identify a safe target. If no safe target is discoverable, do not guess.
70
-
71
- ## Review output format
72
- Structure your findings clearly:
73
-
74
- ```
75
- ## Review
76
- - Correct: what is already good (with evidence)
77
- - Fixed: issue, location, and resolution (if you applied a fix)
78
- - Blocker: critical issue that must be resolved before proceeding
79
- - Note: observation, risk, or follow-up item
80
- ```
81
-
82
- When reviewing code, cite file paths and line numbers. When reviewing plans, cite specific sections and assumptions.
83
-
84
- ## Ponytail review prompt
85
-
86
- Review diffs for unnecessary complexity. One line per finding: location, what
87
- to cut, what replaces it. The diff's best outcome is getting shorter.
88
-
89
- ### Format
90
-
91
- `L<line>: <tag> <what>. <replacement>.`, or `<file>:L<line>: ...` for
92
- multi-file diffs.
93
-
94
- Tags:
95
-
96
- - `delete:` dead code, unused flexibility, speculative feature. Replacement: nothing.
97
- - `stdlib:` hand-rolled thing the standard library ships. Name the function.
98
- - `native:` dependency or code doing what the platform already does. Name the feature.
99
- - `yagni:` abstraction with one implementation, config nobody sets, layer with one caller.
100
- - `shrink:` same logic, fewer lines. Show the shorter form.
101
-
102
- ### Examples
103
-
104
- ❌ "This EmailValidator class might be more complex than necessary, have you
105
- considered whether all these validation rules are needed at this stage?"
106
-
107
- ✅ `L12-38: stdlib: 27-line validator class. "@" in email, 1 line, real validation is the confirmation mail.`
108
-
109
- ✅ `L4: native: moment.js imported for one format call. Intl.DateTimeFormat, 0 deps.`
110
-
111
- ✅ `repo.py:L88: yagni: AbstractRepository with one implementation. Inline it until a second one exists.`
112
-
113
- ✅ `L52-71: delete: retry wrapper around an idempotent local call. Nothing replaces it.`
114
-
115
- ✅ `L30-44: shrink: manual loop builds dict. dict(zip(keys, values)), 1 line.`
116
-
117
- ### Scoring
118
-
119
- End with the only metric that matters: `net: -<N> lines possible.`
120
-
121
- If there is nothing to cut, say `Lean already. Ship.` and stop.
122
-
123
- ### Boundaries
124
-
125
- Scope: over-engineering and complexity only. Correctness bugs, security holes,
126
- and performance are explicitly out of scope. Route them to a normal review
127
- pass, not this one. A single smoke test or `assert`-based
128
- self-check is the ponytail minimum, not bloat, never flag it for deletion.
129
- Does not apply the fixes, only lists them.
130
- "stop ponytail-review" or "normal mode": revert to verbose review style.
@@ -1,51 +0,0 @@
1
- ---
2
- name: explorer
3
- model: tokenin/deepseek-v4-flash
4
- thinking: high
5
- description: Fast codebase recon that returns compressed context for handoff
6
- tools: read, grep, find, ls, bash, write, intercom
7
- systemPromptMode: replace
8
- inheritProjectContext: true
9
- inheritSkills: true
10
- output: context.md
11
- defaultProgress: true
12
- ---
13
-
14
- You are a explorer subagent running inside pi.
15
-
16
- Use the provided tools directly. Move fast, but do not guess. Prefer targeted search and selective reading over reading whole files unless the task clearly needs broader coverage.
17
-
18
- Focus on the minimum context another agent needs in order to act:
19
- - relevant entry points
20
- - key types, interfaces, and functions
21
- - data flow and dependencies
22
- - files that are likely to need changes
23
- - constraints, risks, and open questions
24
-
25
- Working rules:
26
- - Use `grep`, `find`, `ls`, and `read` to map the area before diving deeper.
27
- - Use `bash` only for non-interactive inspection commands.
28
- - When you cite code, use exact file paths and line ranges.
29
- - If you are told to write output, write it to the provided path and keep the final response short.
30
- - When running solo, summarize what you found after writing the output.
31
-
32
- Output format (`context.md`):
33
-
34
- # Code Context
35
-
36
- ## Files Retrieved
37
- List exact files and line ranges.
38
- 1. `path/to/file.ts` (lines 10-50) - why it matters
39
- 2. `path/to/other.ts` (lines 100-150) - why it matters
40
-
41
- ## Key Code
42
- Include the critical types, interfaces, functions, and small code snippets that matter.
43
-
44
- ## Architecture
45
- Explain how the pieces connect.
46
-
47
- ## Start Here
48
- Name the first file another agent should open and why.
49
-
50
- ## Supervisor coordination
51
- If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs; return the completed explorer findings normally.
@@ -1,26 +0,0 @@
1
- ---
2
- name: recapper
3
- model: tokenin/glm-5.2
4
- thinking: high
5
- skill: ponytail, handoff
6
- description: Summarize what the current conversation is about and prepare a handoff document.
7
- tools: read, grep, find, ls, bash, edit, write, intercom
8
- systemPromptMode: replace
9
- inheritProjectContext: true
10
- inheritSkills: true
11
- defaultReads: plan.md, progress.md
12
- defaultContext: fork
13
- output: handoff.md
14
- ---
15
-
16
- Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save to the temporary directory of the user's OS - not the current workspace.
17
-
18
- Include a "suggested skills" section in the document, which suggests skills that the agent should invoke.
19
-
20
- Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead.
21
-
22
- Redact any sensitive information, such as API keys, passwords, or personally identifiable information.
23
-
24
- If the user passed arguments, treat them as a description of what the next session will focus on and tailor the doc accordingly.
25
-
26
- write into handoff.md
@@ -1,132 +0,0 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { spawn } from "node:child_process";
3
- import { isAbsolute, relative, resolve, sep } from "node:path";
4
-
5
- const BLOCK_TOOLS = ["read", "write", "edit"];
6
- const SHELL_TOOLS = ["bash"];
7
- const SHELL_READERS = [
8
- "cat",
9
- "type",
10
- "less",
11
- "more",
12
- "head",
13
- "tail",
14
- "sed",
15
- "awk",
16
- "grep",
17
- "rg",
18
- "python",
19
- "python3",
20
- "py",
21
- "node",
22
- "ruby",
23
- "perl",
24
- "pwsh",
25
- "powershell",
26
- "Get-Content",
27
- ];
28
- const SCRIPT_EXTENSIONS = [".js", ".cjs", ".mjs", ".ts", ".py", ".rb", ".pl", ".sh", ".bash", ".ps1"];
29
- const ALLOW_PATTERNS = ["*.example", "*.local", "*.dev"];
30
-
31
- export default function (pi: ExtensionAPI) {
32
- const cache = new Map<string, boolean>();
33
-
34
- pi.on("tool_call", async (event, ctx) => {
35
- const cwd = ctx.cwd;
36
-
37
- if (BLOCK_TOOLS.includes(event.toolName)) {
38
- const rawPath = event.input.path as string | undefined;
39
- if (!rawPath) return;
40
-
41
- const rel = pathRelativeToCwd(rawPath, cwd);
42
- if (rel === undefined || isAllowed(rel)) return;
43
-
44
- if (await isIgnored(cwd, rel, cache)) {
45
- if (ctx.hasUI) {
46
- ctx.ui.notify(`Blocked ${event.toolName} to gitignored path: ${rel}`, "warning");
47
- }
48
- return blockedReason(event.toolName, rel);
49
- }
50
- return;
51
- }
52
-
53
- if (SHELL_TOOLS.includes(event.toolName)) {
54
- const command = event.input.command as string | undefined;
55
- if (!command) return;
56
-
57
- for (const rawPath of commandPathCandidates(command)) {
58
- const rel = pathRelativeToCwd(rawPath, cwd);
59
- if (rel === undefined || isAllowed(rel)) continue;
60
-
61
- if ((usesShellReader(command) || isScriptPath(rel)) && (await isIgnored(cwd, rel, cache))) {
62
- if (ctx.hasUI) {
63
- ctx.ui.notify(`Blocked ${event.toolName} access to gitignored path: ${rel}`, "warning");
64
- }
65
- return blockedReason(event.toolName, rel);
66
- }
67
- }
68
- }
69
- });
70
- }
71
-
72
- function isAllowed(rel: string): boolean {
73
- return ALLOW_PATTERNS.some((p) => rel === p || rel.endsWith(`/${p}`));
74
- }
75
-
76
- function blockedReason(toolName: string, rel: string) {
77
- return {
78
- block: true,
79
- reason: `You are not allowed to use ${toolName} to access gitignored path "${rel}". It may contain secrets. Stop trying to read it.`,
80
- };
81
- }
82
-
83
- function usesShellReader(command: string): boolean {
84
- return SHELL_READERS.some((reader) => new RegExp(`(^|[^\\w.-])${escapeRegExp(reader)}([^\\w.-]|$)`, "i").test(command));
85
- }
86
-
87
- function commandPathCandidates(command: string): string[] {
88
- return [...command.matchAll(/[A-Za-z0-9_./\\-]+/g)]
89
- .map((match) => match[0])
90
- .filter((token) => !token.startsWith("-") && (token.includes("/") || token.includes("\\") || token.startsWith(".") || isScriptPath(token)));
91
- }
92
-
93
- function isScriptPath(path: string): boolean {
94
- return SCRIPT_EXTENSIONS.some((extension) => path.toLowerCase().endsWith(extension));
95
- }
96
-
97
- function escapeRegExp(value: string): string {
98
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
99
- }
100
-
101
- function pathRelativeToCwd(rawPath: string, cwd: string): string | undefined {
102
- const abs = isAbsolute(rawPath) ? rawPath : resolve(cwd, rawPath);
103
- const rel = relative(cwd, abs);
104
- if (rel.startsWith(`..${sep}`) || rel === "..") return undefined;
105
- return rel.replace(/\\/g, "/");
106
- }
107
-
108
- async function isIgnored(cwd: string, relPath: string, cache: Map<string, boolean>): Promise<boolean> {
109
- const key = `${cwd}::${relPath}`;
110
- const cached = cache.get(key);
111
- if (cached !== undefined) return cached;
112
-
113
- const ignored = await gitCheckIgnore(cwd, relPath);
114
- cache.set(key, ignored);
115
- return ignored;
116
- }
117
-
118
- function gitCheckIgnore(cwd: string, relPath: string): Promise<boolean> {
119
- return new Promise((resolve) => {
120
- let resolved = false;
121
- const finish = (result: boolean) => {
122
- if (resolved) return;
123
- resolved = true;
124
- resolve(result);
125
- };
126
-
127
- const child = spawn("git", ["check-ignore", "--quiet", relPath], { cwd, shell: false });
128
- child.on("exit", (code) => finish(code === 0));
129
- child.on("error", () => finish(false));
130
- setTimeout(() => finish(false), 2000).unref();
131
- });
132
- }
@@ -1,44 +0,0 @@
1
- {
2
- "hooks": {
3
- "SessionStart": [
4
- {
5
- "matcher": "startup|resume|clear|compact",
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-activate.js\"; exit 0",
10
- "commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-activate.js\" }",
11
- "timeout": 5,
12
- "statusMessage": "Loading ponytail mode..."
13
- }
14
- ]
15
- }
16
- ],
17
- "SubagentStart": [
18
- {
19
- "hooks": [
20
- {
21
- "type": "command",
22
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-subagent.js\"; exit 0",
23
- "commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-subagent.js\" }",
24
- "timeout": 5,
25
- "statusMessage": "Loading ponytail mode..."
26
- }
27
- ]
28
- }
29
- ],
30
- "UserPromptSubmit": [
31
- {
32
- "hooks": [
33
- {
34
- "type": "command",
35
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-mode-tracker.js\"; exit 0",
36
- "commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-mode-tracker.js\" }",
37
- "timeout": 5,
38
- "statusMessage": "Tracking ponytail mode..."
39
- }
40
- ]
41
- }
42
- ]
43
- }
44
- }
@@ -1,21 +0,0 @@
1
- {
2
- "version": 1,
3
- "hooks": {
4
- "sessionStart": [
5
- {
6
- "type": "command",
7
- "bash": "node \"${PLUGIN_ROOT}/hooks/ponytail-activate.js\"",
8
- "powershell": "node \"${PLUGIN_ROOT}\\hooks\\ponytail-activate.js\"",
9
- "timeoutSec": 5
10
- }
11
- ],
12
- "userPromptSubmitted": [
13
- {
14
- "type": "command",
15
- "bash": "node \"${PLUGIN_ROOT}/hooks/ponytail-mode-tracker.js\"",
16
- "powershell": "node \"${PLUGIN_ROOT}\\hooks\\ponytail-mode-tracker.js\"",
17
- "timeoutSec": 5
18
- }
19
- ]
20
- }
21
- }
@@ -1,91 +0,0 @@
1
- #!/usr/bin/env node
2
- // ponytail — Claude Code SessionStart activation hook
3
- //
4
- // Runs on every session start:
5
- // 1. Writes flag file at $CLAUDE_CONFIG_DIR/.ponytail-active (defaults to ~/.claude; statusline reads this)
6
- // 2. Emits ponytail ruleset as hidden SessionStart context
7
- // 3. Detects missing statusline config and emits setup nudge
8
-
9
- const fs = require('fs');
10
- const path = require('path');
11
- const { getDefaultMode, getClaudeDir, isShellSafe } = require('./ponytail-config');
12
- const { getPonytailInstructions } = require('./ponytail-instructions');
13
- const {
14
- clearMode,
15
- isCodex,
16
- isCopilot,
17
- setMode,
18
- writeHookOutput,
19
- } = require('./ponytail-runtime');
20
-
21
- const claudeDir = getClaudeDir();
22
- const settingsPath = path.join(claudeDir, 'settings.json');
23
-
24
- const mode = getDefaultMode();
25
-
26
- // "off" mode — skip activation entirely, don't write flag or emit rules
27
- if (mode === 'off') {
28
- clearMode();
29
- const hookOutput = (isCodex || isCopilot) ? '' : 'OK';
30
- writeHookOutput('SessionStart', 'off', hookOutput);
31
- process.exit(0);
32
- }
33
-
34
- // 1. Write flag file
35
- try {
36
- setMode(mode);
37
- } catch (e) {
38
- // Silent fail -- flag is best-effort, don't block the hook
39
- }
40
-
41
- // 2. Emit the ponytail ruleset, filtered to the active intensity level.
42
- let output = getPonytailInstructions(mode);
43
-
44
- // 3. Detect missing statusline config — nudge Claude to help set it up
45
- if (!isCodex && !isCopilot) try {
46
- let hasStatusline = false;
47
- if (fs.existsSync(settingsPath)) {
48
- // Strip UTF-8 BOM some editors prepend on Windows (breaks JSON.parse)
49
- const raw = fs.readFileSync(settingsPath, 'utf8').replace(/^\uFEFF/, '');
50
- const settings = JSON.parse(raw);
51
- if (settings.statusLine) {
52
- hasStatusline = true;
53
- }
54
- }
55
-
56
- if (!hasStatusline) {
57
- const isWindows = process.platform === 'win32';
58
- const scriptName = isWindows ? 'ponytail-statusline.ps1' : 'ponytail-statusline.sh';
59
- const scriptPath = path.join(__dirname, scriptName);
60
- if (isShellSafe(scriptPath)) {
61
- const command = isWindows
62
- ? `powershell -ExecutionPolicy Bypass -File "${scriptPath}"`
63
- : `bash "${scriptPath}"`;
64
- const statusLineSnippet =
65
- '"statusLine": { "type": "command", "command": ' + JSON.stringify(command) + ' }';
66
- output += "\n\n" +
67
- "STATUSLINE SETUP NEEDED: The ponytail plugin includes a statusline badge showing active mode " +
68
- "(e.g. [PONYTAIL], [PONYTAIL:ULTRA]). It is not configured yet. " +
69
- "To enable, add this to ~/.claude/settings.json: " +
70
- statusLineSnippet + " " +
71
- "Proactively offer to set this up for the user on first interaction.";
72
- } else {
73
- // ponytail: install path has shell metacharacters — don't embed it in a
74
- // command snippet; have the agent wire it up by hand instead.
75
- output += "\n\n" +
76
- "STATUSLINE SETUP NEEDED: The ponytail plugin includes a statusline badge showing active mode. " +
77
- "Its install path contains characters unsafe to embed in a shell command, so configure it manually: " +
78
- "add a statusLine command of type \"command\" that runs " + scriptName +
79
- " from the plugin's hooks directory to ~/.claude/settings.json, quoting/escaping the path for your shell. " +
80
- "Proactively offer to set this up for the user on first interaction.";
81
- }
82
- }
83
- } catch (e) {
84
- // Silent fail — don't block session start over statusline detection
85
- }
86
-
87
- try {
88
- writeHookOutput('SessionStart', mode, output);
89
- } catch (e) {
90
- // Silent fail — stdout closed/EPIPE at hook exit must not surface as a hook failure
91
- }
@@ -1,122 +0,0 @@
1
- #!/usr/bin/env node
2
- // ponytail — shared configuration resolver
3
- //
4
- // Resolution order for default mode:
5
- // 1. PONYTAIL_DEFAULT_MODE environment variable
6
- // 2. Config file defaultMode field:
7
- // - $XDG_CONFIG_HOME/ponytail/config.json (any platform, if set)
8
- // - ~/.config/ponytail/config.json (macOS / Linux fallback)
9
- // - %APPDATA%\ponytail\config.json (Windows fallback)
10
- // 3. 'full'
11
-
12
- const fs = require('fs');
13
- const path = require('path');
14
- const os = require('os');
15
-
16
- const DEFAULT_MODE = 'full';
17
- const VALID_MODES = ['off', 'lite', 'full', 'ultra', 'review'];
18
- const RUNTIME_MODES = ['off', 'lite', 'full', 'ultra'];
19
-
20
- function normalizeMode(mode) {
21
- if (typeof mode !== 'string') return null;
22
- const normalized = mode.trim().toLowerCase();
23
- return RUNTIME_MODES.includes(normalized) ? normalized : null;
24
- }
25
-
26
- function normalizeConfigMode(mode) {
27
- if (typeof mode !== 'string') return null;
28
- const normalized = mode.trim().toLowerCase();
29
- return VALID_MODES.includes(normalized) ? normalized : null;
30
- }
31
-
32
- function normalizePersistedMode(mode) {
33
- return normalizeMode(mode) || normalizeConfigMode(mode);
34
- }
35
-
36
- // "stop ponytail" / "normal mode" turn ponytail off, but only as a standalone
37
- // command. Matching the phrase anywhere in the message turned it off mid-task
38
- // for ordinary requests like "add a normal mode toggle" — so require the whole
39
- // message to be the command, ignoring case and trailing punctuation.
40
- function isDeactivationCommand(text) {
41
- const t = String(text || '').trim().toLowerCase().replace(/[.!?\s]+$/, '');
42
- return t === 'stop ponytail' || t === 'normal mode';
43
- }
44
-
45
- // ponytail: only embed the plugin install path in a statusline shell command when
46
- // it's made of ordinary path characters. An allowlist beats escaping every shell's
47
- // metacharacters; a hostile clone path (quotes, &, $, backtick, ;, etc.) falls back
48
- // to manual setup instead. Allows : \ / for normal Windows and POSIX paths. Full
49
- // per-shell escaper only if a real need appears.
50
- function isShellSafe(p) {
51
- return typeof p === 'string' && /^[A-Za-z0-9 _.\-:/\\~]+$/.test(p);
52
- }
53
-
54
- function getConfigDir() {
55
- if (process.env.XDG_CONFIG_HOME) {
56
- return path.join(process.env.XDG_CONFIG_HOME, 'ponytail');
57
- }
58
- if (process.platform === 'win32') {
59
- return path.join(
60
- process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'),
61
- 'ponytail'
62
- );
63
- }
64
- return path.join(os.homedir(), '.config', 'ponytail');
65
- }
66
-
67
- function getConfigPath() {
68
- return path.join(getConfigDir(), 'config.json');
69
- }
70
-
71
- function getClaudeDir() {
72
- // ponytail: CLAUDE_CONFIG_DIR overrides ~/.claude, matching Claude Code.
73
- return process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
74
- }
75
-
76
- function getDefaultMode() {
77
- // 1. Environment variable (highest priority)
78
- const envMode = process.env.PONYTAIL_DEFAULT_MODE;
79
- if (envMode && VALID_MODES.includes(envMode.toLowerCase())) {
80
- return envMode.toLowerCase();
81
- }
82
-
83
- // 2. Config file
84
- try {
85
- const configPath = getConfigPath();
86
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
87
- if (config.defaultMode && VALID_MODES.includes(config.defaultMode.toLowerCase())) {
88
- return config.defaultMode.toLowerCase();
89
- }
90
- } catch (e) {
91
- // Config file doesn't exist or is invalid — fall through
92
- }
93
-
94
- // 3. Default
95
- return DEFAULT_MODE;
96
- }
97
-
98
- function writeDefaultMode(mode) {
99
- const normalized = normalizeConfigMode(mode);
100
- if (!normalized) return null;
101
-
102
- const configPath = getConfigPath();
103
- fs.mkdirSync(path.dirname(configPath), { recursive: true });
104
- fs.writeFileSync(configPath, JSON.stringify({ defaultMode: normalized }, null, 2), 'utf8');
105
- return normalized;
106
- }
107
-
108
- module.exports = {
109
- DEFAULT_MODE,
110
- VALID_MODES,
111
- RUNTIME_MODES,
112
- getDefaultMode,
113
- getConfigDir,
114
- getConfigPath,
115
- getClaudeDir,
116
- isShellSafe,
117
- normalizeMode,
118
- normalizeConfigMode,
119
- normalizePersistedMode,
120
- isDeactivationCommand,
121
- writeDefaultMode,
122
- };