hooks.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import { App } from "../app/app"
  2. import { Bus } from "../bus"
  3. import { File } from "../file"
  4. import { Session } from "../session"
  5. import { Log } from "../util/log"
  6. import { Config } from "./config"
  7. import path from "path"
  8. export namespace ConfigHooks {
  9. const log = Log.create({ service: "config.hooks" })
  10. export function init() {
  11. log.info("init")
  12. const app = App.info()
  13. Bus.subscribe(File.Event.Edited, async (payload) => {
  14. const cfg = await Config.get()
  15. const ext = path.extname(payload.properties.file)
  16. for (const item of cfg.experimental?.hook?.file_edited?.[ext] ?? []) {
  17. log.info("file_edited", {
  18. file: payload.properties.file,
  19. command: item.command,
  20. })
  21. Bun.spawn({
  22. cmd: item.command.map((x) => x.replace("$FILE", payload.properties.file)),
  23. env: item.environment,
  24. cwd: app.path.cwd,
  25. stdout: "ignore",
  26. stderr: "ignore",
  27. })
  28. }
  29. })
  30. Bus.subscribe(Session.Event.Idle, async (payload) => {
  31. const cfg = await Config.get()
  32. if (cfg.experimental?.hook?.session_completed) {
  33. const session = await Session.get(payload.properties.sessionID)
  34. // Only fire hook for top-level sessions (not subagent sessions)
  35. if (session.parentID) return
  36. for (const item of cfg.experimental.hook.session_completed) {
  37. log.info("session_completed", {
  38. command: item.command,
  39. })
  40. Bun.spawn({
  41. cmd: item.command,
  42. cwd: App.info().path.cwd,
  43. env: item.environment,
  44. stdout: "ignore",
  45. stderr: "ignore",
  46. })
  47. }
  48. }
  49. })
  50. }
  51. }