index.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import type { Plugin, Hooks } from "@kirincode-ai/plugin"
  2. import { MemoryStore } from "./memory"
  3. import { SkillRegistry } from "./skills"
  4. import { handleMemoryCommand, handleSkillCommand } from "./commands"
  5. export const KirinCodePlugin: Plugin = async ({ client, project, directory, worktree, $ }) => {
  6. const store = new MemoryStore(worktree)
  7. const registry = new SkillRegistry()
  8. // Load skills at startup
  9. registry.load(worktree)
  10. // Load memory summary for context injection
  11. const memorySummary = store.loadSummary()
  12. return {
  13. // Inject memory + skills into system context
  14. "experimental.chat.system.transform": async (_input, output) => {
  15. const extras: string[] = []
  16. if (memorySummary) {
  17. extras.push("## Your Memory (from past sessions)", memorySummary)
  18. }
  19. const skillCtx = registry.formatSystemContext()
  20. if (skillCtx) {
  21. extras.push(skillCtx)
  22. }
  23. if (extras.length) {
  24. output.system = [...output.system, ...extras]
  25. }
  26. },
  27. // Handle /memory and /skill commands
  28. "command.execute.before": async (input, output) => {
  29. if (input.command === "memory") {
  30. output.parts = await handleMemoryCommand(input.arguments, store)
  31. }
  32. if (input.command === "skill") {
  33. output.parts = await handleSkillCommand(input.arguments, registry, worktree)
  34. }
  35. },
  36. // Auto-memory on session idle
  37. event: async ({ event }) => {
  38. if (event.type === "session.idle") {
  39. const today = new Date().toISOString().slice(0, 10)
  40. store.updateIndex({
  41. date: today,
  42. category: "session",
  43. summary: `Session completed in ${directory}`,
  44. tags: ["auto"],
  45. })
  46. }
  47. },
  48. // Preserve memory context across compaction
  49. "experimental.session.compacting": async (_input, output) => {
  50. const summary = store.loadSummary()
  51. if (summary) {
  52. output.context.push("## Persisted Memory\n" + summary)
  53. }
  54. },
  55. // Shell env: expose KIRINCODE_ env vars
  56. "shell.env": async (_input, output) => {
  57. output.env.KIRINCODE_MEMORY_DIR = store["memoryDir"]
  58. },
  59. } satisfies Hooks
  60. }
  61. export { MemoryStore, SkillRegistry }