compact-agent 1.1.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 (324) hide show
  1. package/README.md +394 -0
  2. package/bin/anycode.js +2 -0
  3. package/bin/crowcoder.js +19 -0
  4. package/bin/ecc-hooks.cjs +138 -0
  5. package/dist/agents.d.ts +17 -0
  6. package/dist/agents.js +1603 -0
  7. package/dist/agents.js.map +1 -0
  8. package/dist/api.d.ts +16 -0
  9. package/dist/api.js +115 -0
  10. package/dist/api.js.map +1 -0
  11. package/dist/autonomous-loops.d.ts +108 -0
  12. package/dist/autonomous-loops.js +526 -0
  13. package/dist/autonomous-loops.js.map +1 -0
  14. package/dist/codemaps.d.ts +53 -0
  15. package/dist/codemaps.js +325 -0
  16. package/dist/codemaps.js.map +1 -0
  17. package/dist/compaction.d.ts +30 -0
  18. package/dist/compaction.js +125 -0
  19. package/dist/compaction.js.map +1 -0
  20. package/dist/config.d.ts +5 -0
  21. package/dist/config.js +79 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/content-engine.d.ts +97 -0
  24. package/dist/content-engine.js +721 -0
  25. package/dist/content-engine.js.map +1 -0
  26. package/dist/cost-tracker.d.ts +49 -0
  27. package/dist/cost-tracker.js +150 -0
  28. package/dist/cost-tracker.js.map +1 -0
  29. package/dist/counter-button.d.ts +35 -0
  30. package/dist/counter-button.js +48 -0
  31. package/dist/counter-button.js.map +1 -0
  32. package/dist/counter.d.ts +21 -0
  33. package/dist/counter.js +31 -0
  34. package/dist/counter.js.map +1 -0
  35. package/dist/coverage.d.ts +23 -0
  36. package/dist/coverage.js +215 -0
  37. package/dist/coverage.js.map +1 -0
  38. package/dist/docs-sync.d.ts +23 -0
  39. package/dist/docs-sync.js +266 -0
  40. package/dist/docs-sync.js.map +1 -0
  41. package/dist/ecc.d.ts +41 -0
  42. package/dist/ecc.js +644 -0
  43. package/dist/ecc.js.map +1 -0
  44. package/dist/evaluation.d.ts +24 -0
  45. package/dist/evaluation.js +412 -0
  46. package/dist/evaluation.js.map +1 -0
  47. package/dist/export.d.ts +22 -0
  48. package/dist/export.js +109 -0
  49. package/dist/export.js.map +1 -0
  50. package/dist/git-workflow.d.ts +22 -0
  51. package/dist/git-workflow.js +197 -0
  52. package/dist/git-workflow.js.map +1 -0
  53. package/dist/hook-controls.d.ts +34 -0
  54. package/dist/hook-controls.js +90 -0
  55. package/dist/hook-controls.js.map +1 -0
  56. package/dist/hooks.d.ts +30 -0
  57. package/dist/hooks.js +130 -0
  58. package/dist/hooks.js.map +1 -0
  59. package/dist/html-parser.d.ts +18 -0
  60. package/dist/html-parser.js +101 -0
  61. package/dist/html-parser.js.map +1 -0
  62. package/dist/index.d.ts +12 -0
  63. package/dist/index.js +1230 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/learning.d.ts +35 -0
  66. package/dist/learning.js +238 -0
  67. package/dist/learning.js.map +1 -0
  68. package/dist/login.d.ts +37 -0
  69. package/dist/login.js +191 -0
  70. package/dist/login.js.map +1 -0
  71. package/dist/memory.d.ts +39 -0
  72. package/dist/memory.js +183 -0
  73. package/dist/memory.js.map +1 -0
  74. package/dist/model-router.d.ts +23 -0
  75. package/dist/model-router.js +145 -0
  76. package/dist/model-router.js.map +1 -0
  77. package/dist/modes.d.ts +17 -0
  78. package/dist/modes.js +217 -0
  79. package/dist/modes.js.map +1 -0
  80. package/dist/orchestration.d.ts +37 -0
  81. package/dist/orchestration.js +139 -0
  82. package/dist/orchestration.js.map +1 -0
  83. package/dist/package-detect.d.ts +36 -0
  84. package/dist/package-detect.js +529 -0
  85. package/dist/package-detect.js.map +1 -0
  86. package/dist/permissions.d.ts +25 -0
  87. package/dist/permissions.js +50 -0
  88. package/dist/permissions.js.map +1 -0
  89. package/dist/pm2-manager.d.ts +40 -0
  90. package/dist/pm2-manager.js +127 -0
  91. package/dist/pm2-manager.js.map +1 -0
  92. package/dist/query.d.ts +15 -0
  93. package/dist/query.js +278 -0
  94. package/dist/query.js.map +1 -0
  95. package/dist/refactor.d.ts +22 -0
  96. package/dist/refactor.js +226 -0
  97. package/dist/refactor.js.map +1 -0
  98. package/dist/retry.d.ts +20 -0
  99. package/dist/retry.js +88 -0
  100. package/dist/retry.js.map +1 -0
  101. package/dist/rules.d.ts +34 -0
  102. package/dist/rules.js +942 -0
  103. package/dist/rules.js.map +1 -0
  104. package/dist/schema.d.ts +23 -0
  105. package/dist/schema.js +12 -0
  106. package/dist/schema.js.map +1 -0
  107. package/dist/search-first.d.ts +17 -0
  108. package/dist/search-first.js +301 -0
  109. package/dist/search-first.js.map +1 -0
  110. package/dist/security.d.ts +10 -0
  111. package/dist/security.js +145 -0
  112. package/dist/security.js.map +1 -0
  113. package/dist/sessions.d.ts +21 -0
  114. package/dist/sessions.js +112 -0
  115. package/dist/sessions.js.map +1 -0
  116. package/dist/skill-create.d.ts +38 -0
  117. package/dist/skill-create.js +389 -0
  118. package/dist/skill-create.js.map +1 -0
  119. package/dist/skills.d.ts +34 -0
  120. package/dist/skills.js +161 -0
  121. package/dist/skills.js.map +1 -0
  122. package/dist/strategic-compaction.d.ts +24 -0
  123. package/dist/strategic-compaction.js +144 -0
  124. package/dist/strategic-compaction.js.map +1 -0
  125. package/dist/system-prompt.d.ts +3 -0
  126. package/dist/system-prompt.js +101 -0
  127. package/dist/system-prompt.js.map +1 -0
  128. package/dist/theme.d.ts +60 -0
  129. package/dist/theme.js +220 -0
  130. package/dist/theme.js.map +1 -0
  131. package/dist/tools/bash.d.ts +2 -0
  132. package/dist/tools/bash.js +49 -0
  133. package/dist/tools/bash.js.map +1 -0
  134. package/dist/tools/edit.d.ts +2 -0
  135. package/dist/tools/edit.js +76 -0
  136. package/dist/tools/edit.js.map +1 -0
  137. package/dist/tools/glob.d.ts +2 -0
  138. package/dist/tools/glob.js +54 -0
  139. package/dist/tools/glob.js.map +1 -0
  140. package/dist/tools/grep.d.ts +2 -0
  141. package/dist/tools/grep.js +64 -0
  142. package/dist/tools/grep.js.map +1 -0
  143. package/dist/tools/index.d.ts +5 -0
  144. package/dist/tools/index.js +27 -0
  145. package/dist/tools/index.js.map +1 -0
  146. package/dist/tools/list-dir.d.ts +2 -0
  147. package/dist/tools/list-dir.js +51 -0
  148. package/dist/tools/list-dir.js.map +1 -0
  149. package/dist/tools/read.d.ts +2 -0
  150. package/dist/tools/read.js +56 -0
  151. package/dist/tools/read.js.map +1 -0
  152. package/dist/tools/types.d.ts +45 -0
  153. package/dist/tools/types.js +2 -0
  154. package/dist/tools/types.js.map +1 -0
  155. package/dist/tools/web-fetch.d.ts +2 -0
  156. package/dist/tools/web-fetch.js +41 -0
  157. package/dist/tools/web-fetch.js.map +1 -0
  158. package/dist/tools/web-search.d.ts +27 -0
  159. package/dist/tools/web-search.js +139 -0
  160. package/dist/tools/web-search.js.map +1 -0
  161. package/dist/tools/write.d.ts +2 -0
  162. package/dist/tools/write.js +36 -0
  163. package/dist/tools/write.js.map +1 -0
  164. package/dist/types.d.ts +28 -0
  165. package/dist/types.js +57 -0
  166. package/dist/types.js.map +1 -0
  167. package/dist/users.d.ts +51 -0
  168. package/dist/users.js +193 -0
  169. package/dist/users.js.map +1 -0
  170. package/dist/verification.d.ts +73 -0
  171. package/dist/verification.js +269 -0
  172. package/dist/verification.js.map +1 -0
  173. package/dist/walkthrough.d.ts +10 -0
  174. package/dist/walkthrough.js +121 -0
  175. package/dist/walkthrough.js.map +1 -0
  176. package/package.json +58 -0
  177. package/resources/ecc/agents/architect.json +16 -0
  178. package/resources/ecc/agents/architect.md +212 -0
  179. package/resources/ecc/agents/build-error-resolver.json +17 -0
  180. package/resources/ecc/agents/build-error-resolver.md +116 -0
  181. package/resources/ecc/agents/chief-of-staff.json +17 -0
  182. package/resources/ecc/agents/chief-of-staff.md +153 -0
  183. package/resources/ecc/agents/code-reviewer.json +16 -0
  184. package/resources/ecc/agents/code-reviewer.md +238 -0
  185. package/resources/ecc/agents/database-reviewer.json +16 -0
  186. package/resources/ecc/agents/database-reviewer.md +92 -0
  187. package/resources/ecc/agents/doc-updater.json +16 -0
  188. package/resources/ecc/agents/doc-updater.md +108 -0
  189. package/resources/ecc/agents/e2e-runner.json +17 -0
  190. package/resources/ecc/agents/e2e-runner.md +109 -0
  191. package/resources/ecc/agents/go-build-resolver.json +17 -0
  192. package/resources/ecc/agents/go-build-resolver.md +96 -0
  193. package/resources/ecc/agents/go-reviewer.json +16 -0
  194. package/resources/ecc/agents/go-reviewer.md +77 -0
  195. package/resources/ecc/agents/harness-optimizer.json +15 -0
  196. package/resources/ecc/agents/harness-optimizer.md +34 -0
  197. package/resources/ecc/agents/loop-operator.json +16 -0
  198. package/resources/ecc/agents/loop-operator.md +36 -0
  199. package/resources/ecc/agents/planner.json +15 -0
  200. package/resources/ecc/agents/planner.md +212 -0
  201. package/resources/ecc/agents/python-reviewer.json +16 -0
  202. package/resources/ecc/agents/python-reviewer.md +99 -0
  203. package/resources/ecc/agents/refactor-cleaner.json +17 -0
  204. package/resources/ecc/agents/refactor-cleaner.md +87 -0
  205. package/resources/ecc/agents/security-reviewer.json +16 -0
  206. package/resources/ecc/agents/security-reviewer.md +109 -0
  207. package/resources/ecc/agents/tdd-guide.json +17 -0
  208. package/resources/ecc/agents/tdd-guide.md +93 -0
  209. package/resources/ecc/commands/add-language-rules.md +39 -0
  210. package/resources/ecc/commands/database-migration.md +36 -0
  211. package/resources/ecc/commands/feature-development.md +38 -0
  212. package/resources/ecc/prompts/build-fix.prompt.md +47 -0
  213. package/resources/ecc/prompts/code-review.prompt.md +56 -0
  214. package/resources/ecc/prompts/plan.prompt.md +52 -0
  215. package/resources/ecc/prompts/refactor.prompt.md +50 -0
  216. package/resources/ecc/prompts/security-review.prompt.md +70 -0
  217. package/resources/ecc/prompts/tdd.prompt.md +47 -0
  218. package/resources/ecc/rules/common-agents.md +53 -0
  219. package/resources/ecc/rules/common-coding-style.md +52 -0
  220. package/resources/ecc/rules/common-development-workflow.md +33 -0
  221. package/resources/ecc/rules/common-git-workflow.md +28 -0
  222. package/resources/ecc/rules/common-hooks.md +34 -0
  223. package/resources/ecc/rules/common-patterns.md +35 -0
  224. package/resources/ecc/rules/common-performance.md +59 -0
  225. package/resources/ecc/rules/common-security.md +33 -0
  226. package/resources/ecc/rules/common-testing.md +33 -0
  227. package/resources/ecc/rules/golang-coding-style.md +31 -0
  228. package/resources/ecc/rules/golang-hooks.md +16 -0
  229. package/resources/ecc/rules/golang-patterns.md +44 -0
  230. package/resources/ecc/rules/golang-security.md +33 -0
  231. package/resources/ecc/rules/golang-testing.md +30 -0
  232. package/resources/ecc/rules/kotlin-coding-style.md +39 -0
  233. package/resources/ecc/rules/kotlin-hooks.md +16 -0
  234. package/resources/ecc/rules/kotlin-patterns.md +50 -0
  235. package/resources/ecc/rules/kotlin-security.md +58 -0
  236. package/resources/ecc/rules/kotlin-testing.md +38 -0
  237. package/resources/ecc/rules/php-coding-style.md +25 -0
  238. package/resources/ecc/rules/php-hooks.md +21 -0
  239. package/resources/ecc/rules/php-patterns.md +23 -0
  240. package/resources/ecc/rules/php-security.md +24 -0
  241. package/resources/ecc/rules/php-testing.md +26 -0
  242. package/resources/ecc/rules/python-coding-style.md +42 -0
  243. package/resources/ecc/rules/python-hooks.md +19 -0
  244. package/resources/ecc/rules/python-patterns.md +39 -0
  245. package/resources/ecc/rules/python-security.md +30 -0
  246. package/resources/ecc/rules/python-testing.md +38 -0
  247. package/resources/ecc/rules/swift-coding-style.md +47 -0
  248. package/resources/ecc/rules/swift-hooks.md +20 -0
  249. package/resources/ecc/rules/swift-patterns.md +66 -0
  250. package/resources/ecc/rules/swift-security.md +33 -0
  251. package/resources/ecc/rules/swift-testing.md +45 -0
  252. package/resources/ecc/rules/typescript-coding-style.md +63 -0
  253. package/resources/ecc/rules/typescript-hooks.md +20 -0
  254. package/resources/ecc/rules/typescript-patterns.md +50 -0
  255. package/resources/ecc/rules/typescript-security.md +26 -0
  256. package/resources/ecc/rules/typescript-testing.md +16 -0
  257. package/resources/ecc/skills/agent-introspection-debugging/SKILL.md +152 -0
  258. package/resources/ecc/skills/agent-introspection-debugging/agents/openai.yaml +7 -0
  259. package/resources/ecc/skills/agent-sort/SKILL.md +214 -0
  260. package/resources/ecc/skills/agent-sort/agents/openai.yaml +7 -0
  261. package/resources/ecc/skills/api-design/SKILL.md +522 -0
  262. package/resources/ecc/skills/api-design/agents/openai.yaml +7 -0
  263. package/resources/ecc/skills/article-writing/SKILL.md +78 -0
  264. package/resources/ecc/skills/article-writing/agents/openai.yaml +7 -0
  265. package/resources/ecc/skills/backend-patterns/SKILL.md +597 -0
  266. package/resources/ecc/skills/backend-patterns/agents/openai.yaml +7 -0
  267. package/resources/ecc/skills/brand-voice/SKILL.md +96 -0
  268. package/resources/ecc/skills/brand-voice/agents/openai.yaml +7 -0
  269. package/resources/ecc/skills/brand-voice/references/voice-profile-schema.md +55 -0
  270. package/resources/ecc/skills/bun-runtime/SKILL.md +83 -0
  271. package/resources/ecc/skills/bun-runtime/agents/openai.yaml +7 -0
  272. package/resources/ecc/skills/coding-standards/SKILL.md +548 -0
  273. package/resources/ecc/skills/coding-standards/agents/openai.yaml +7 -0
  274. package/resources/ecc/skills/content-engine/SKILL.md +130 -0
  275. package/resources/ecc/skills/content-engine/agents/openai.yaml +7 -0
  276. package/resources/ecc/skills/crosspost/SKILL.md +110 -0
  277. package/resources/ecc/skills/crosspost/agents/openai.yaml +7 -0
  278. package/resources/ecc/skills/deep-research/SKILL.md +154 -0
  279. package/resources/ecc/skills/deep-research/agents/openai.yaml +7 -0
  280. package/resources/ecc/skills/dmux-workflows/SKILL.md +143 -0
  281. package/resources/ecc/skills/dmux-workflows/agents/openai.yaml +7 -0
  282. package/resources/ecc/skills/documentation-lookup/SKILL.md +89 -0
  283. package/resources/ecc/skills/documentation-lookup/agents/openai.yaml +7 -0
  284. package/resources/ecc/skills/e2e-testing/SKILL.md +325 -0
  285. package/resources/ecc/skills/e2e-testing/agents/openai.yaml +7 -0
  286. package/resources/ecc/skills/eval-harness/SKILL.md +235 -0
  287. package/resources/ecc/skills/eval-harness/agents/openai.yaml +7 -0
  288. package/resources/ecc/skills/everything-claude-code/SKILL.md +442 -0
  289. package/resources/ecc/skills/everything-claude-code/agents/openai.yaml +7 -0
  290. package/resources/ecc/skills/exa-search/SKILL.md +169 -0
  291. package/resources/ecc/skills/exa-search/agents/openai.yaml +7 -0
  292. package/resources/ecc/skills/fal-ai-media/SKILL.md +276 -0
  293. package/resources/ecc/skills/fal-ai-media/agents/openai.yaml +7 -0
  294. package/resources/ecc/skills/frontend-patterns/SKILL.md +647 -0
  295. package/resources/ecc/skills/frontend-patterns/agents/openai.yaml +7 -0
  296. package/resources/ecc/skills/frontend-slides/SKILL.md +183 -0
  297. package/resources/ecc/skills/frontend-slides/STYLE_PRESETS.md +330 -0
  298. package/resources/ecc/skills/frontend-slides/agents/openai.yaml +7 -0
  299. package/resources/ecc/skills/investor-materials/SKILL.md +95 -0
  300. package/resources/ecc/skills/investor-materials/agents/openai.yaml +7 -0
  301. package/resources/ecc/skills/investor-outreach/SKILL.md +90 -0
  302. package/resources/ecc/skills/investor-outreach/agents/openai.yaml +7 -0
  303. package/resources/ecc/skills/market-research/SKILL.md +74 -0
  304. package/resources/ecc/skills/market-research/agents/openai.yaml +7 -0
  305. package/resources/ecc/skills/mcp-server-patterns/SKILL.md +66 -0
  306. package/resources/ecc/skills/mcp-server-patterns/agents/openai.yaml +7 -0
  307. package/resources/ecc/skills/mle-workflow/SKILL.md +346 -0
  308. package/resources/ecc/skills/mle-workflow/agents/openai.yaml +7 -0
  309. package/resources/ecc/skills/nextjs-turbopack/SKILL.md +43 -0
  310. package/resources/ecc/skills/nextjs-turbopack/agents/openai.yaml +7 -0
  311. package/resources/ecc/skills/product-capability/SKILL.md +140 -0
  312. package/resources/ecc/skills/product-capability/agents/openai.yaml +7 -0
  313. package/resources/ecc/skills/security-review/SKILL.md +494 -0
  314. package/resources/ecc/skills/security-review/agents/openai.yaml +7 -0
  315. package/resources/ecc/skills/strategic-compact/SKILL.md +102 -0
  316. package/resources/ecc/skills/strategic-compact/agents/openai.yaml +7 -0
  317. package/resources/ecc/skills/tdd-workflow/SKILL.md +409 -0
  318. package/resources/ecc/skills/tdd-workflow/agents/openai.yaml +7 -0
  319. package/resources/ecc/skills/verification-loop/SKILL.md +125 -0
  320. package/resources/ecc/skills/verification-loop/agents/openai.yaml +7 -0
  321. package/resources/ecc/skills/video-editing/SKILL.md +307 -0
  322. package/resources/ecc/skills/video-editing/agents/openai.yaml +7 -0
  323. package/resources/ecc/skills/x-api/SKILL.md +229 -0
  324. package/resources/ecc/skills/x-api/agents/openai.yaml +7 -0
@@ -0,0 +1,22 @@
1
+ export declare function isGitRepo(cwd: string): boolean;
2
+ export declare function gitStatus(cwd: string): string;
3
+ export declare function gitDiff(cwd: string, staged?: boolean): string;
4
+ export declare function gitLog(cwd: string, count?: number): string;
5
+ export declare function gitBranch(cwd: string): string;
6
+ export declare function gitCurrentBranch(cwd: string): string;
7
+ /**
8
+ * Generate a commit message prompt for the AI based on staged changes.
9
+ */
10
+ export declare function buildCommitPrompt(cwd: string): string | null;
11
+ /**
12
+ * Generate a PR creation prompt based on branch diff.
13
+ */
14
+ export declare function buildPRPrompt(cwd: string): string | null;
15
+ /**
16
+ * Show formatted git info for /diff command.
17
+ */
18
+ export declare function printDiff(cwd: string): void;
19
+ /**
20
+ * Show formatted git log for /log command.
21
+ */
22
+ export declare function printLog(cwd: string, count?: number): void;
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Git workflow — smart commit, PR creation, diff, log.
3
+ * Injected as slash commands: /commit, /pr, /diff, /log
4
+ */
5
+ /**
6
+ * Git workflow — smart commit, PR creation, diff, log.
7
+ * Injected as slash commands: /commit, /pr, /diff, /log
8
+ */
9
+ import { execSync } from 'node:child_process';
10
+ import chalk from 'chalk';
11
+ /**
12
+ * Execute a git command safely, returning empty string on error.
13
+ * @param cmd - Git command arguments (without "git" prefix)
14
+ * @param cwd - Working directory
15
+ * @returns Command output or error message
16
+ */
17
+ function git(cmd, cwd) {
18
+ try {
19
+ return execSync(`git ${cmd}`, {
20
+ cwd,
21
+ encoding: 'utf-8',
22
+ timeout: 30_000,
23
+ stdio: ['pipe', 'pipe', 'pipe'],
24
+ }).trim();
25
+ }
26
+ catch (err) {
27
+ const msg = err instanceof Error ? err.stderr || err.message : String(err);
28
+ return `Error: ${msg}`;
29
+ }
30
+ }
31
+ export function isGitRepo(cwd) {
32
+ try {
33
+ execSync('git rev-parse --git-dir', { cwd, stdio: 'pipe' });
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ export function gitStatus(cwd) {
41
+ return git('status --short', cwd);
42
+ }
43
+ export function gitDiff(cwd, staged = false) {
44
+ const flag = staged ? '--cached' : '';
45
+ return git(`diff ${flag}`, cwd);
46
+ }
47
+ export function gitLog(cwd, count = 10) {
48
+ return git(`log --oneline -${count}`, cwd);
49
+ }
50
+ export function gitBranch(cwd) {
51
+ return git('branch -a', cwd);
52
+ }
53
+ export function gitCurrentBranch(cwd) {
54
+ return git('rev-parse --abbrev-ref HEAD', cwd);
55
+ }
56
+ /**
57
+ * Generate a commit message prompt for the AI based on staged changes.
58
+ */
59
+ export function buildCommitPrompt(cwd) {
60
+ if (!isGitRepo(cwd))
61
+ return null;
62
+ const status = gitStatus(cwd);
63
+ const stagedDiff = gitDiff(cwd, true);
64
+ const unstagedDiff = gitDiff(cwd, false);
65
+ const recentLog = gitLog(cwd, 5);
66
+ if (!status && !stagedDiff && !unstagedDiff)
67
+ return null;
68
+ return `Generate a git commit for the following changes.
69
+
70
+ ## Git Status
71
+ \`\`\`
72
+ ${status}
73
+ \`\`\`
74
+
75
+ ## Staged Changes
76
+ \`\`\`diff
77
+ ${stagedDiff || '(no staged changes)'}
78
+ \`\`\`
79
+
80
+ ## Unstaged Changes
81
+ \`\`\`diff
82
+ ${unstagedDiff.slice(0, 5000) || '(no unstaged changes)'}
83
+ \`\`\`
84
+
85
+ ## Recent Commits (for style reference)
86
+ \`\`\`
87
+ ${recentLog}
88
+ \`\`\`
89
+
90
+ Instructions:
91
+ 1. If there are unstaged changes, suggest which files to stage with \`git add\`
92
+ 2. Write a concise commit message (imperative mood, <72 chars title)
93
+ 3. Add a body if the changes are complex
94
+ 4. Run the git commands to stage and commit
95
+
96
+ Follow the existing commit message style from the recent log.`;
97
+ }
98
+ /**
99
+ * Generate a PR creation prompt based on branch diff.
100
+ */
101
+ export function buildPRPrompt(cwd) {
102
+ if (!isGitRepo(cwd))
103
+ return null;
104
+ const branch = gitCurrentBranch(cwd);
105
+ const baseBranch = detectBaseBranch(cwd);
106
+ const diffStat = git(`diff ${baseBranch}...HEAD --stat`, cwd);
107
+ const log = git(`log ${baseBranch}..HEAD --oneline`, cwd);
108
+ const diff = git(`diff ${baseBranch}...HEAD`, cwd);
109
+ return `Create a GitHub Pull Request for branch \`${branch}\` into \`${baseBranch}\`.
110
+
111
+ ## Commits
112
+ \`\`\`
113
+ ${log}
114
+ \`\`\`
115
+
116
+ ## Diff Summary
117
+ \`\`\`
118
+ ${diffStat}
119
+ \`\`\`
120
+
121
+ ## Full Diff (truncated)
122
+ \`\`\`diff
123
+ ${diff.slice(0, 10000)}
124
+ \`\`\`
125
+
126
+ Instructions:
127
+ 1. Write a PR title (<70 chars)
128
+ 2. Write a description with: Summary (bullet points), Test Plan
129
+ 3. Run: gh pr create --title "..." --body "..."
130
+ 4. Return the PR URL`;
131
+ }
132
+ function detectBaseBranch(cwd) {
133
+ // First, check git symbolic-ref for origin/HEAD
134
+ try {
135
+ const result = git('symbolic-ref refs/remotes/origin/HEAD', cwd);
136
+ if (result && !result.includes('Error')) {
137
+ // Output is like "refs/remotes/origin/main"
138
+ const parts = result.split('/');
139
+ const branch = parts[parts.length - 1];
140
+ if (branch)
141
+ return branch;
142
+ }
143
+ }
144
+ catch {
145
+ // Fall through to other methods
146
+ }
147
+ // Fall back to checking branch list for common names
148
+ const branches = git('branch -a', cwd);
149
+ if (branches.includes('main'))
150
+ return 'main';
151
+ if (branches.includes('master'))
152
+ return 'master';
153
+ if (branches.includes('develop'))
154
+ return 'develop';
155
+ if (branches.includes('trunk'))
156
+ return 'trunk';
157
+ // Final fallback
158
+ return 'main';
159
+ }
160
+ /**
161
+ * Show formatted git info for /diff command.
162
+ */
163
+ export function printDiff(cwd) {
164
+ if (!isGitRepo(cwd)) {
165
+ console.log(chalk.yellow(' Not a git repository'));
166
+ return;
167
+ }
168
+ const status = gitStatus(cwd);
169
+ const staged = gitDiff(cwd, true);
170
+ const unstaged = gitDiff(cwd, false);
171
+ console.log(chalk.cyan('\n Git Status:'));
172
+ console.log(chalk.dim(status || ' (clean)'));
173
+ if (staged) {
174
+ console.log(chalk.cyan('\n Staged Changes:'));
175
+ console.log(chalk.green(staged.slice(0, 3000)));
176
+ }
177
+ if (unstaged) {
178
+ console.log(chalk.cyan('\n Unstaged Changes:'));
179
+ console.log(chalk.yellow(unstaged.slice(0, 3000)));
180
+ }
181
+ console.log();
182
+ }
183
+ /**
184
+ * Show formatted git log for /log command.
185
+ */
186
+ export function printLog(cwd, count = 15) {
187
+ if (!isGitRepo(cwd)) {
188
+ console.log(chalk.yellow(' Not a git repository'));
189
+ return;
190
+ }
191
+ const branch = gitCurrentBranch(cwd);
192
+ const log = git(`log --oneline --graph --decorate -${count}`, cwd);
193
+ console.log(chalk.cyan(`\n Branch: ${branch}`));
194
+ console.log(chalk.dim(log));
195
+ console.log();
196
+ }
197
+ //# sourceMappingURL=git-workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-workflow.js","sourceRoot":"","sources":["../src/git-workflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Hook Runtime Controls — environment-based hook profile management.
3
+ * Control which hooks run and what severity of checks are enforced.
4
+ */
5
+ export type HookProfile = 'minimal' | 'standard' | 'strict';
6
+ export interface HookControlConfig {
7
+ profile: HookProfile;
8
+ disabledHooks: string[];
9
+ }
10
+ /**
11
+ * Get the current hook profile from environment variable.
12
+ * Defaults to 'standard' if not set or invalid.
13
+ */
14
+ export declare function getHookProfile(): HookProfile;
15
+ /**
16
+ * Get list of disabled hooks from environment variable.
17
+ * Format: comma-separated hook IDs (e.g., "hook1,hook2,hook3")
18
+ */
19
+ export declare function getDisabledHooks(): string[];
20
+ /**
21
+ * Determine if a hook should run based on profile and disabled list.
22
+ * @param hookId - The hook identifier
23
+ * @param event - The hook event type (PreToolUse, PostToolUse, SessionStart, SessionStop)
24
+ * @returns true if the hook should run, false otherwise
25
+ */
26
+ export declare function shouldRunHook(hookId: string, event: string): boolean;
27
+ /**
28
+ * Get a human-readable description of what a hook profile does.
29
+ */
30
+ export declare function getProfileDescription(profile: HookProfile): string;
31
+ /**
32
+ * Print the current hook control status to console.
33
+ */
34
+ export declare function printHookControlStatus(): void;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Hook Runtime Controls — environment-based hook profile management.
3
+ * Control which hooks run and what severity of checks are enforced.
4
+ */
5
+ /**
6
+ * Get the current hook profile from environment variable.
7
+ * Defaults to 'standard' if not set or invalid.
8
+ */
9
+ export function getHookProfile() {
10
+ const profile = process.env.CROWCODER_HOOK_PROFILE?.toLowerCase();
11
+ if (profile === 'minimal' || profile === 'strict') {
12
+ return profile;
13
+ }
14
+ return 'standard';
15
+ }
16
+ /**
17
+ * Get list of disabled hooks from environment variable.
18
+ * Format: comma-separated hook IDs (e.g., "hook1,hook2,hook3")
19
+ */
20
+ export function getDisabledHooks() {
21
+ const disabled = process.env.CROWCODER_DISABLED_HOOKS || '';
22
+ return disabled
23
+ .split(',')
24
+ .map((h) => h.trim())
25
+ .filter((h) => h.length > 0);
26
+ }
27
+ /**
28
+ * Determine if a hook should run based on profile and disabled list.
29
+ * @param hookId - The hook identifier
30
+ * @param event - The hook event type (PreToolUse, PostToolUse, SessionStart, SessionStop)
31
+ * @returns true if the hook should run, false otherwise
32
+ */
33
+ export function shouldRunHook(hookId, event) {
34
+ // Check if hook is explicitly disabled
35
+ const disabled = getDisabledHooks();
36
+ if (disabled.includes(hookId)) {
37
+ return false;
38
+ }
39
+ const profile = getHookProfile();
40
+ // minimal: only session start/stop hooks
41
+ if (profile === 'minimal') {
42
+ return event === 'SessionStart' || event === 'SessionStop';
43
+ }
44
+ // strict: all hooks run
45
+ if (profile === 'strict') {
46
+ return true;
47
+ }
48
+ // standard: all hooks except expensive ones
49
+ // (assume pre-commit validation and complex analysis hooks are "expensive")
50
+ if (profile === 'standard') {
51
+ // Filter out hooks that are marked as expensive/pre-commit hooks
52
+ const expensivePatterns = ['pre-commit', 'validation', 'analysis', 'lint'];
53
+ const isExpensive = expensivePatterns.some((pattern) => hookId.toLowerCase().includes(pattern));
54
+ return !isExpensive;
55
+ }
56
+ return true;
57
+ }
58
+ /**
59
+ * Get a human-readable description of what a hook profile does.
60
+ */
61
+ export function getProfileDescription(profile) {
62
+ switch (profile) {
63
+ case 'minimal':
64
+ return 'Only session start/stop hooks enabled (minimal overhead)';
65
+ case 'standard':
66
+ return 'All hooks except expensive validation (default, balanced)';
67
+ case 'strict':
68
+ return 'All hooks including pre-commit validation (comprehensive checks)';
69
+ default:
70
+ return 'Unknown profile';
71
+ }
72
+ }
73
+ /**
74
+ * Print the current hook control status to console.
75
+ */
76
+ export function printHookControlStatus() {
77
+ const profile = getHookProfile();
78
+ const disabled = getDisabledHooks();
79
+ console.log('\n=== Hook Control Status ===');
80
+ console.log(`Profile: ${profile}`);
81
+ console.log(`Description: ${getProfileDescription(profile)}`);
82
+ if (disabled.length > 0) {
83
+ console.log(`Disabled hooks: ${disabled.join(', ')}`);
84
+ }
85
+ else {
86
+ console.log('Disabled hooks: none');
87
+ }
88
+ console.log('');
89
+ }
90
+ //# sourceMappingURL=hook-controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-controls.js","sourceRoot":"","sources":["../src/hook-controls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export type HookEvent = 'PreToolUse' | 'PostToolUse' | 'SessionStart' | 'SessionStop';
2
+ export interface HookDef {
3
+ event: HookEvent;
4
+ match: string;
5
+ command: string;
6
+ timeout?: number;
7
+ blocking?: boolean;
8
+ enabled?: boolean;
9
+ }
10
+ export interface HooksConfig {
11
+ hooks: HookDef[];
12
+ }
13
+ export interface HookContext {
14
+ event: HookEvent;
15
+ toolName?: string;
16
+ toolInput?: Record<string, unknown>;
17
+ toolOutput?: string;
18
+ sessionId?: string;
19
+ cwd: string;
20
+ }
21
+ export interface HookResult {
22
+ allowed: boolean;
23
+ message?: string;
24
+ }
25
+ export declare function initHooksDir(): void;
26
+ export declare function runHooks(ctx: HookContext): Promise<HookResult>;
27
+ export declare function saveHooksConfig(config: HooksConfig): void;
28
+ export declare function listHooks(): HookDef[];
29
+ export declare function addHook(hook: HookDef): void;
30
+ export declare function removeHook(index: number): boolean;
package/dist/hooks.js ADDED
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Hook system — configurable pre/post tool execution hooks.
3
+ * Hooks are scripts in ~/.crowcoder/hooks/ that fire on events:
4
+ * - PreToolUse: before a tool runs (can block)
5
+ * - PostToolUse: after a tool runs (can log/alert)
6
+ * - SessionStart: when a session begins
7
+ * - SessionStop: when a session ends
8
+ *
9
+ * Hook config in ~/.crowcoder/hooks.json:
10
+ * {
11
+ * "hooks": [
12
+ * { "event": "PreToolUse", "match": "bash", "command": "node guard.js" },
13
+ * { "event": "PostToolUse", "match": "*", "command": "node logger.js" }
14
+ * ]
15
+ * }
16
+ */
17
+ import { execSync } from 'node:child_process';
18
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
19
+ import { join } from 'node:path';
20
+ import chalk from 'chalk';
21
+ import { getConfigDir } from './config.js';
22
+ import { shouldRunHook } from './hook-controls.js';
23
+ const HOOKS_DIR = join(getConfigDir(), 'hooks');
24
+ const HOOKS_CONFIG = join(getConfigDir(), 'hooks.json');
25
+ function loadHooksConfig() {
26
+ if (!existsSync(HOOKS_CONFIG)) {
27
+ return { hooks: [] };
28
+ }
29
+ try {
30
+ return JSON.parse(readFileSync(HOOKS_CONFIG, 'utf-8'));
31
+ }
32
+ catch {
33
+ return { hooks: [] };
34
+ }
35
+ }
36
+ export function initHooksDir() {
37
+ mkdirSync(HOOKS_DIR, { recursive: true });
38
+ if (!existsSync(HOOKS_CONFIG)) {
39
+ const defaultConfig = {
40
+ hooks: [
41
+ {
42
+ event: 'PostToolUse',
43
+ match: '*',
44
+ command: 'echo "Tool $CROWCODER_TOOL used"',
45
+ blocking: false,
46
+ enabled: false,
47
+ },
48
+ ],
49
+ };
50
+ writeFileSync(HOOKS_CONFIG, JSON.stringify(defaultConfig, null, 2), 'utf-8');
51
+ }
52
+ }
53
+ function matchesTool(pattern, toolName) {
54
+ if (pattern === '*')
55
+ return true;
56
+ if (pattern === toolName)
57
+ return true;
58
+ // Simple glob: "bash*" matches "bash", "bash_safe"
59
+ if (pattern.endsWith('*') && toolName.startsWith(pattern.slice(0, -1)))
60
+ return true;
61
+ return false;
62
+ }
63
+ export async function runHooks(ctx) {
64
+ const config = loadHooksConfig();
65
+ const matching = config.hooks.filter((h) => h.event === ctx.event &&
66
+ (h.enabled !== false) &&
67
+ (!ctx.toolName || matchesTool(h.match, ctx.toolName)));
68
+ for (const hook of matching) {
69
+ // Apply profile-based filtering before executing
70
+ const hookId = `${ctx.event}:${hook.match}`;
71
+ if (!shouldRunHook(hookId, ctx.event)) {
72
+ continue;
73
+ }
74
+ const env = {
75
+ ...process.env,
76
+ CROWCODER_EVENT: ctx.event,
77
+ CROWCODER_TOOL: ctx.toolName || '',
78
+ CROWCODER_TOOL_INPUT: ctx.toolInput ? JSON.stringify(ctx.toolInput) : '',
79
+ CROWCODER_TOOL_OUTPUT: ctx.toolOutput || '',
80
+ CROWCODER_SESSION_ID: ctx.sessionId || '',
81
+ CROWCODER_CWD: ctx.cwd,
82
+ };
83
+ const isBlocking = hook.blocking ?? (ctx.event === 'PreToolUse');
84
+ const timeout = hook.timeout ?? 10_000;
85
+ try {
86
+ const result = execSync(hook.command, {
87
+ cwd: ctx.cwd,
88
+ env,
89
+ timeout,
90
+ stdio: ['pipe', 'pipe', 'pipe'],
91
+ shell: process.platform === 'win32' ? 'bash' : '/bin/bash',
92
+ });
93
+ const output = result.toString().trim();
94
+ if (output) {
95
+ console.log(chalk.dim(` [hook:${ctx.event}] ${output}`));
96
+ }
97
+ }
98
+ catch (err) {
99
+ if (isBlocking) {
100
+ const msg = err instanceof Error ? err.message : String(err);
101
+ console.log(chalk.yellow(` [hook:${ctx.event}] BLOCKED: ${msg}`));
102
+ return { allowed: false, message: msg };
103
+ }
104
+ // Non-blocking hooks just log errors
105
+ console.log(chalk.dim(` [hook:${ctx.event}] error (non-blocking): ${err}`));
106
+ }
107
+ }
108
+ return { allowed: true };
109
+ }
110
+ export function saveHooksConfig(config) {
111
+ mkdirSync(HOOKS_DIR, { recursive: true });
112
+ writeFileSync(HOOKS_CONFIG, JSON.stringify(config, null, 2), 'utf-8');
113
+ }
114
+ export function listHooks() {
115
+ return loadHooksConfig().hooks;
116
+ }
117
+ export function addHook(hook) {
118
+ const config = loadHooksConfig();
119
+ config.hooks.push(hook);
120
+ saveHooksConfig(config);
121
+ }
122
+ export function removeHook(index) {
123
+ const config = loadHooksConfig();
124
+ if (index < 0 || index >= config.hooks.length)
125
+ return false;
126
+ config.hooks.splice(index, 1);
127
+ saveHooksConfig(config);
128
+ return true;
129
+ }
130
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * HTML to text parser — converts HTML to readable plain text without external dependencies.
3
+ * Used internally by the web_fetch tool to extract readable content from web pages.
4
+ */
5
+ /**
6
+ * Convert HTML to readable plain text.
7
+ * - Strips HTML tags
8
+ * - Converts HTML entities (&amp; &lt; &gt; &quot; &nbsp; &#NNN; &#xHHH;)
9
+ * - Preserves paragraph breaks
10
+ * - Removes script, style, nav, footer, header blocks entirely
11
+ * - Extracts title separately
12
+ * - Collapses multiple blank lines
13
+ * - Trims whitespace
14
+ *
15
+ * @param html - Raw HTML string
16
+ * @returns Plain text with preserved structure
17
+ */
18
+ export declare function htmlToText(html: string): string;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * HTML to text parser — converts HTML to readable plain text without external dependencies.
3
+ * Used internally by the web_fetch tool to extract readable content from web pages.
4
+ */
5
+ /**
6
+ * Convert HTML to readable plain text.
7
+ * - Strips HTML tags
8
+ * - Converts HTML entities (&amp; &lt; &gt; &quot; &nbsp; &#NNN; &#xHHH;)
9
+ * - Preserves paragraph breaks
10
+ * - Removes script, style, nav, footer, header blocks entirely
11
+ * - Extracts title separately
12
+ * - Collapses multiple blank lines
13
+ * - Trims whitespace
14
+ *
15
+ * @param html - Raw HTML string
16
+ * @returns Plain text with preserved structure
17
+ */
18
+ export function htmlToText(html) {
19
+ // Extract title before stripping tags
20
+ let title = '';
21
+ const titleMatch = html.match(/<title[^>]*>(.*?)<\/title>/is);
22
+ if (titleMatch && titleMatch[1]) {
23
+ title = titleMatch[1].trim();
24
+ }
25
+ let text = html;
26
+ // Remove entire blocks: script, style, nav, footer, header
27
+ text = text.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, '');
28
+ text = text.replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, '');
29
+ text = text.replace(/<nav\b[^>]*>[\s\S]*?<\/nav>/gi, '');
30
+ text = text.replace(/<footer\b[^>]*>[\s\S]*?<\/footer>/gi, '');
31
+ text = text.replace(/<header\b[^>]*>[\s\S]*?<\/header>/gi, '');
32
+ text = text.replace(/<title\b[^>]*>[\s\S]*?<\/title>/gi, '');
33
+ // Convert block-level tags to newlines (before stripping tags)
34
+ text = text.replace(/<\/?(?:p|div|section|article|main|aside|blockquote)\b[^>]*>/gi, '\n');
35
+ text = text.replace(/<(?:h[1-6])\b[^>]*>/gi, '\n');
36
+ text = text.replace(/<\/(?:h[1-6])\b[^>]*>/gi, '\n');
37
+ text = text.replace(/<br\s*\/?>/gi, '\n');
38
+ text = text.replace(/<hr\s*\/?>/gi, '\n');
39
+ text = text.replace(/<li\b[^>]*>/gi, '\n');
40
+ // Strip remaining HTML tags
41
+ text = text.replace(/<[^>]+>/g, '');
42
+ // Decode HTML entities
43
+ text = decodeHtmlEntities(text);
44
+ // Collapse multiple newlines to max 2 (max 1 blank line)
45
+ text = text.replace(/\n\n\n+/g, '\n\n');
46
+ // Trim each line
47
+ text = text
48
+ .split('\n')
49
+ .map((line) => line.trim())
50
+ .join('\n');
51
+ // Remove leading/trailing empty lines
52
+ text = text.replace(/^\n+|\n+$/g, '');
53
+ // Prepend title if found
54
+ if (title) {
55
+ text = title + '\n\n' + text;
56
+ }
57
+ return text;
58
+ }
59
+ /**
60
+ * Decode HTML entities in a string.
61
+ * Handles: &amp; &lt; &gt; &quot; &nbsp; &#NNN; &#xHHH;
62
+ */
63
+ function decodeHtmlEntities(str) {
64
+ // Common named entities
65
+ const namedEntities = {
66
+ amp: '&',
67
+ lt: '<',
68
+ gt: '>',
69
+ quot: '"',
70
+ apos: "'",
71
+ nbsp: ' ',
72
+ copy: '©',
73
+ reg: '®',
74
+ deg: '°',
75
+ };
76
+ // Replace named entities
77
+ let result = str.replace(/&([a-z]+);/gi, (match, entity) => {
78
+ const lower = entity.toLowerCase();
79
+ return namedEntities[lower] || match;
80
+ });
81
+ // Replace decimal numeric entities (&#123;)
82
+ result = result.replace(/&#(\d+);/g, (match, code) => {
83
+ try {
84
+ return String.fromCharCode(parseInt(code, 10));
85
+ }
86
+ catch {
87
+ return match;
88
+ }
89
+ });
90
+ // Replace hexadecimal numeric entities (&#x1F;)
91
+ result = result.replace(/&#x([0-9a-f]+);/gi, (match, code) => {
92
+ try {
93
+ return String.fromCharCode(parseInt(code, 16));
94
+ }
95
+ catch {
96
+ return match;
97
+ }
98
+ });
99
+ return result;
100
+ }
101
+ //# sourceMappingURL=html-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-parser.js","sourceRoot":"","sources":["../src/html-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import type { CrowcoderConfig, Message } from './types.js';
3
+ import { type Session } from './sessions.js';
4
+ import { type Mode } from './modes.js';
5
+ export declare function handleSlashCommand(input: string, config: CrowcoderConfig, messages: Message[], session: Session, mode: {
6
+ current: Mode;
7
+ }): {
8
+ handled: boolean;
9
+ shouldExit?: boolean;
10
+ newMessages?: Message[];
11
+ injectPrompt?: string;
12
+ };