@asermax/tachikoma 2.0.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 (345) hide show
  1. package/README.md +64 -0
  2. package/dist/agent/adapter.d.ts +8 -0
  3. package/dist/agent/adapter.js +86 -0
  4. package/dist/agent/adapter.js.map +1 -0
  5. package/dist/agent/manager.d.ts +35 -0
  6. package/dist/agent/manager.js +76 -0
  7. package/dist/agent/manager.js.map +1 -0
  8. package/dist/agent/models.d.ts +46 -0
  9. package/dist/agent/models.js +96 -0
  10. package/dist/agent/models.js.map +1 -0
  11. package/dist/agent/side-run.d.ts +42 -0
  12. package/dist/agent/side-run.js +83 -0
  13. package/dist/agent/side-run.js.map +1 -0
  14. package/dist/app.d.ts +5 -0
  15. package/dist/app.js +79 -0
  16. package/dist/app.js.map +1 -0
  17. package/dist/channels/types.d.ts +37 -0
  18. package/dist/channels/types.js +5 -0
  19. package/dist/channels/types.js.map +1 -0
  20. package/dist/config/default-template.d.ts +1 -0
  21. package/dist/config/default-template.js +49 -0
  22. package/dist/config/default-template.js.map +1 -0
  23. package/dist/config/load.d.ts +8 -0
  24. package/dist/config/load.js +28 -0
  25. package/dist/config/load.js.map +1 -0
  26. package/dist/config/parse.d.ts +5 -0
  27. package/dist/config/parse.js +18 -0
  28. package/dist/config/parse.js.map +1 -0
  29. package/dist/config/schema.d.ts +29 -0
  30. package/dist/config/schema.js +35 -0
  31. package/dist/config/schema.js.map +1 -0
  32. package/dist/coordinator.d.ts +54 -0
  33. package/dist/coordinator.js +344 -0
  34. package/dist/coordinator.js.map +1 -0
  35. package/dist/db/core-schema.d.ts +250 -0
  36. package/dist/db/core-schema.js +19 -0
  37. package/dist/db/core-schema.js.map +1 -0
  38. package/dist/db/index.d.ts +8 -0
  39. package/dist/db/index.js +16 -0
  40. package/dist/db/index.js.map +1 -0
  41. package/dist/db/schema.d.ts +4 -0
  42. package/dist/db/schema.js +7 -0
  43. package/dist/db/schema.js.map +1 -0
  44. package/dist/db/state.d.ts +10 -0
  45. package/dist/db/state.js +36 -0
  46. package/dist/db/state.js.map +1 -0
  47. package/dist/domain/agent-events.d.ts +26 -0
  48. package/dist/domain/agent-events.js +2 -0
  49. package/dist/domain/agent-events.js.map +1 -0
  50. package/dist/domain/message.d.ts +25 -0
  51. package/dist/domain/message.js +17 -0
  52. package/dist/domain/message.js.map +1 -0
  53. package/dist/events.d.ts +9 -0
  54. package/dist/events.js +27 -0
  55. package/dist/events.js.map +1 -0
  56. package/dist/extensions/api.d.ts +118 -0
  57. package/dist/extensions/api.js +7 -0
  58. package/dist/extensions/api.js.map +1 -0
  59. package/dist/extensions/boundary/detector.d.ts +20 -0
  60. package/dist/extensions/boundary/detector.js +57 -0
  61. package/dist/extensions/boundary/detector.js.map +1 -0
  62. package/dist/extensions/boundary/idle.d.ts +10 -0
  63. package/dist/extensions/boundary/idle.js +28 -0
  64. package/dist/extensions/boundary/idle.js.map +1 -0
  65. package/dist/extensions/boundary/index.d.ts +12 -0
  66. package/dist/extensions/boundary/index.js +65 -0
  67. package/dist/extensions/boundary/index.js.map +1 -0
  68. package/dist/extensions/boundary/summary.d.ts +5 -0
  69. package/dist/extensions/boundary/summary.js +33 -0
  70. package/dist/extensions/boundary/summary.js.map +1 -0
  71. package/dist/extensions/commands/index.d.ts +7 -0
  72. package/dist/extensions/commands/index.js +21 -0
  73. package/dist/extensions/commands/index.js.map +1 -0
  74. package/dist/extensions/context/index.d.ts +7 -0
  75. package/dist/extensions/context/index.js +65 -0
  76. package/dist/extensions/context/index.js.map +1 -0
  77. package/dist/extensions/context/processor.d.ts +27 -0
  78. package/dist/extensions/context/processor.js +228 -0
  79. package/dist/extensions/context/processor.js.map +1 -0
  80. package/dist/extensions/detached-processes/index.d.ts +12 -0
  81. package/dist/extensions/detached-processes/index.js +51 -0
  82. package/dist/extensions/detached-processes/index.js.map +1 -0
  83. package/dist/extensions/detached-processes/limits.d.ts +27 -0
  84. package/dist/extensions/detached-processes/limits.js +55 -0
  85. package/dist/extensions/detached-processes/limits.js.map +1 -0
  86. package/dist/extensions/detached-processes/output.d.ts +2 -0
  87. package/dist/extensions/detached-processes/output.js +26 -0
  88. package/dist/extensions/detached-processes/output.js.map +1 -0
  89. package/dist/extensions/detached-processes/reconcile.d.ts +31 -0
  90. package/dist/extensions/detached-processes/reconcile.js +71 -0
  91. package/dist/extensions/detached-processes/reconcile.js.map +1 -0
  92. package/dist/extensions/detached-processes/repository.d.ts +33 -0
  93. package/dist/extensions/detached-processes/repository.js +62 -0
  94. package/dist/extensions/detached-processes/repository.js.map +1 -0
  95. package/dist/extensions/detached-processes/schema.d.ts +252 -0
  96. package/dist/extensions/detached-processes/schema.js +23 -0
  97. package/dist/extensions/detached-processes/schema.js.map +1 -0
  98. package/dist/extensions/detached-processes/spawn.d.ts +40 -0
  99. package/dist/extensions/detached-processes/spawn.js +137 -0
  100. package/dist/extensions/detached-processes/spawn.js.map +1 -0
  101. package/dist/extensions/detached-processes/tools.d.ts +41 -0
  102. package/dist/extensions/detached-processes/tools.js +243 -0
  103. package/dist/extensions/detached-processes/tools.js.map +1 -0
  104. package/dist/extensions/detached-processes/watcher.d.ts +7 -0
  105. package/dist/extensions/detached-processes/watcher.js +19 -0
  106. package/dist/extensions/detached-processes/watcher.js.map +1 -0
  107. package/dist/extensions/external/index.d.ts +11 -0
  108. package/dist/extensions/external/index.js +40 -0
  109. package/dist/extensions/external/index.js.map +1 -0
  110. package/dist/extensions/external/installs.d.ts +39 -0
  111. package/dist/extensions/external/installs.js +98 -0
  112. package/dist/extensions/external/installs.js.map +1 -0
  113. package/dist/extensions/external/loader.d.ts +19 -0
  114. package/dist/extensions/external/loader.js +70 -0
  115. package/dist/extensions/external/loader.js.map +1 -0
  116. package/dist/extensions/external/tools.d.ts +17 -0
  117. package/dist/extensions/external/tools.js +112 -0
  118. package/dist/extensions/external/tools.js.map +1 -0
  119. package/dist/extensions/git/commit.d.ts +19 -0
  120. package/dist/extensions/git/commit.js +44 -0
  121. package/dist/extensions/git/commit.js.map +1 -0
  122. package/dist/extensions/git/git.d.ts +11 -0
  123. package/dist/extensions/git/git.js +29 -0
  124. package/dist/extensions/git/git.js.map +1 -0
  125. package/dist/extensions/git/hooks.d.ts +10 -0
  126. package/dist/extensions/git/hooks.js +88 -0
  127. package/dist/extensions/git/hooks.js.map +1 -0
  128. package/dist/extensions/git/index.d.ts +11 -0
  129. package/dist/extensions/git/index.js +28 -0
  130. package/dist/extensions/git/index.js.map +1 -0
  131. package/dist/extensions/git/processor.d.ts +13 -0
  132. package/dist/extensions/git/processor.js +52 -0
  133. package/dist/extensions/git/processor.js.map +1 -0
  134. package/dist/extensions/git/sync.d.ts +44 -0
  135. package/dist/extensions/git/sync.js +189 -0
  136. package/dist/extensions/git/sync.js.map +1 -0
  137. package/dist/extensions/git/tools.d.ts +21 -0
  138. package/dist/extensions/git/tools.js +101 -0
  139. package/dist/extensions/git/tools.js.map +1 -0
  140. package/dist/extensions/host.d.ts +31 -0
  141. package/dist/extensions/host.js +75 -0
  142. package/dist/extensions/host.js.map +1 -0
  143. package/dist/extensions/index.d.ts +3 -0
  144. package/dist/extensions/index.js +32 -0
  145. package/dist/extensions/index.js.map +1 -0
  146. package/dist/extensions/memory/archive.d.ts +8 -0
  147. package/dist/extensions/memory/archive.js +46 -0
  148. package/dist/extensions/memory/archive.js.map +1 -0
  149. package/dist/extensions/memory/dates.d.ts +2 -0
  150. package/dist/extensions/memory/dates.js +7 -0
  151. package/dist/extensions/memory/dates.js.map +1 -0
  152. package/dist/extensions/memory/extraction.d.ts +17 -0
  153. package/dist/extensions/memory/extraction.js +218 -0
  154. package/dist/extensions/memory/extraction.js.map +1 -0
  155. package/dist/extensions/memory/index.d.ts +20 -0
  156. package/dist/extensions/memory/index.js +67 -0
  157. package/dist/extensions/memory/index.js.map +1 -0
  158. package/dist/extensions/memory/indexes.d.ts +14 -0
  159. package/dist/extensions/memory/indexes.js +64 -0
  160. package/dist/extensions/memory/indexes.js.map +1 -0
  161. package/dist/extensions/memory/layout.d.ts +20 -0
  162. package/dist/extensions/memory/layout.js +79 -0
  163. package/dist/extensions/memory/layout.js.map +1 -0
  164. package/dist/extensions/memory/maintenance.d.ts +21 -0
  165. package/dist/extensions/memory/maintenance.js +357 -0
  166. package/dist/extensions/memory/maintenance.js.map +1 -0
  167. package/dist/extensions/memory/prompts.d.ts +8 -0
  168. package/dist/extensions/memory/prompts.js +125 -0
  169. package/dist/extensions/memory/prompts.js.map +1 -0
  170. package/dist/extensions/memory/transcript.d.ts +18 -0
  171. package/dist/extensions/memory/transcript.js +79 -0
  172. package/dist/extensions/memory/transcript.js.map +1 -0
  173. package/dist/extensions/notifications/format.d.ts +5 -0
  174. package/dist/extensions/notifications/format.js +17 -0
  175. package/dist/extensions/notifications/format.js.map +1 -0
  176. package/dist/extensions/notifications/index.d.ts +13 -0
  177. package/dist/extensions/notifications/index.js +29 -0
  178. package/dist/extensions/notifications/index.js.map +1 -0
  179. package/dist/extensions/notifications/payload.d.ts +22 -0
  180. package/dist/extensions/notifications/payload.js +29 -0
  181. package/dist/extensions/notifications/payload.js.map +1 -0
  182. package/dist/extensions/notifications/router.d.ts +29 -0
  183. package/dist/extensions/notifications/router.js +55 -0
  184. package/dist/extensions/notifications/router.js.map +1 -0
  185. package/dist/extensions/notifications/tools.d.ts +12 -0
  186. package/dist/extensions/notifications/tools.js +41 -0
  187. package/dist/extensions/notifications/tools.js.map +1 -0
  188. package/dist/extensions/projects/context-provider.d.ts +9 -0
  189. package/dist/extensions/projects/context-provider.js +37 -0
  190. package/dist/extensions/projects/context-provider.js.map +1 -0
  191. package/dist/extensions/projects/git.d.ts +28 -0
  192. package/dist/extensions/projects/git.js +91 -0
  193. package/dist/extensions/projects/git.js.map +1 -0
  194. package/dist/extensions/projects/hooks.d.ts +7 -0
  195. package/dist/extensions/projects/hooks.js +42 -0
  196. package/dist/extensions/projects/hooks.js.map +1 -0
  197. package/dist/extensions/projects/index.d.ts +11 -0
  198. package/dist/extensions/projects/index.js +30 -0
  199. package/dist/extensions/projects/index.js.map +1 -0
  200. package/dist/extensions/projects/processor.d.ts +13 -0
  201. package/dist/extensions/projects/processor.js +63 -0
  202. package/dist/extensions/projects/processor.js.map +1 -0
  203. package/dist/extensions/projects/tools.d.ts +21 -0
  204. package/dist/extensions/projects/tools.js +118 -0
  205. package/dist/extensions/projects/tools.js.map +1 -0
  206. package/dist/extensions/registrations.d.ts +21 -0
  207. package/dist/extensions/registrations.js +12 -0
  208. package/dist/extensions/registrations.js.map +1 -0
  209. package/dist/extensions/repl/index.d.ts +2 -0
  210. package/dist/extensions/repl/index.js +85 -0
  211. package/dist/extensions/repl/index.js.map +1 -0
  212. package/dist/extensions/skills/agents.d.ts +17 -0
  213. package/dist/extensions/skills/agents.js +77 -0
  214. package/dist/extensions/skills/agents.js.map +1 -0
  215. package/dist/extensions/skills/delegate.d.ts +22 -0
  216. package/dist/extensions/skills/delegate.js +54 -0
  217. package/dist/extensions/skills/delegate.js.map +1 -0
  218. package/dist/extensions/skills/index.d.ts +11 -0
  219. package/dist/extensions/skills/index.js +43 -0
  220. package/dist/extensions/skills/index.js.map +1 -0
  221. package/dist/extensions/skills/reload.d.ts +8 -0
  222. package/dist/extensions/skills/reload.js +38 -0
  223. package/dist/extensions/skills/reload.js.map +1 -0
  224. package/dist/extensions/tasks/executor.d.ts +43 -0
  225. package/dist/extensions/tasks/executor.js +179 -0
  226. package/dist/extensions/tasks/executor.js.map +1 -0
  227. package/dist/extensions/tasks/expiration.d.ts +12 -0
  228. package/dist/extensions/tasks/expiration.js +17 -0
  229. package/dist/extensions/tasks/expiration.js.map +1 -0
  230. package/dist/extensions/tasks/generation.d.ts +14 -0
  231. package/dist/extensions/tasks/generation.js +70 -0
  232. package/dist/extensions/tasks/generation.js.map +1 -0
  233. package/dist/extensions/tasks/index.d.ts +14 -0
  234. package/dist/extensions/tasks/index.js +75 -0
  235. package/dist/extensions/tasks/index.js.map +1 -0
  236. package/dist/extensions/tasks/repository.d.ts +53 -0
  237. package/dist/extensions/tasks/repository.js +147 -0
  238. package/dist/extensions/tasks/repository.js.map +1 -0
  239. package/dist/extensions/tasks/schedule.d.ts +13 -0
  240. package/dist/extensions/tasks/schedule.js +32 -0
  241. package/dist/extensions/tasks/schedule.js.map +1 -0
  242. package/dist/extensions/tasks/schema.d.ts +423 -0
  243. package/dist/extensions/tasks/schema.js +45 -0
  244. package/dist/extensions/tasks/schema.js.map +1 -0
  245. package/dist/extensions/tasks/session-delivery.d.ts +18 -0
  246. package/dist/extensions/tasks/session-delivery.js +39 -0
  247. package/dist/extensions/tasks/session-delivery.js.map +1 -0
  248. package/dist/extensions/tasks/tools.d.ts +38 -0
  249. package/dist/extensions/tasks/tools.js +181 -0
  250. package/dist/extensions/tasks/tools.js.map +1 -0
  251. package/dist/extensions/telegram/buttons.d.ts +14 -0
  252. package/dist/extensions/telegram/buttons.js +49 -0
  253. package/dist/extensions/telegram/buttons.js.map +1 -0
  254. package/dist/extensions/telegram/channel.d.ts +39 -0
  255. package/dist/extensions/telegram/channel.js +201 -0
  256. package/dist/extensions/telegram/channel.js.map +1 -0
  257. package/dist/extensions/telegram/chunking.d.ts +7 -0
  258. package/dist/extensions/telegram/chunking.js +67 -0
  259. package/dist/extensions/telegram/chunking.js.map +1 -0
  260. package/dist/extensions/telegram/inbound.d.ts +7 -0
  261. package/dist/extensions/telegram/inbound.js +29 -0
  262. package/dist/extensions/telegram/inbound.js.map +1 -0
  263. package/dist/extensions/telegram/index.d.ts +13 -0
  264. package/dist/extensions/telegram/index.js +67 -0
  265. package/dist/extensions/telegram/index.js.map +1 -0
  266. package/dist/extensions/telegram/media.d.ts +39 -0
  267. package/dist/extensions/telegram/media.js +223 -0
  268. package/dist/extensions/telegram/media.js.map +1 -0
  269. package/dist/extensions/telegram/mutex.d.ts +9 -0
  270. package/dist/extensions/telegram/mutex.js +14 -0
  271. package/dist/extensions/telegram/mutex.js.map +1 -0
  272. package/dist/extensions/telegram/sending.d.ts +48 -0
  273. package/dist/extensions/telegram/sending.js +119 -0
  274. package/dist/extensions/telegram/sending.js.map +1 -0
  275. package/dist/extensions/telegram/streaming.d.ts +46 -0
  276. package/dist/extensions/telegram/streaming.js +140 -0
  277. package/dist/extensions/telegram/streaming.js.map +1 -0
  278. package/dist/extensions/telegram/tools.d.ts +80 -0
  279. package/dist/extensions/telegram/tools.js +232 -0
  280. package/dist/extensions/telegram/tools.js.map +1 -0
  281. package/dist/extensions/workflows/cleanup.d.ts +10 -0
  282. package/dist/extensions/workflows/cleanup.js +38 -0
  283. package/dist/extensions/workflows/cleanup.js.map +1 -0
  284. package/dist/extensions/workflows/index.d.ts +11 -0
  285. package/dist/extensions/workflows/index.js +42 -0
  286. package/dist/extensions/workflows/index.js.map +1 -0
  287. package/dist/extensions/workflows/loader.d.ts +27 -0
  288. package/dist/extensions/workflows/loader.js +90 -0
  289. package/dist/extensions/workflows/loader.js.map +1 -0
  290. package/dist/extensions/workflows/model.d.ts +19 -0
  291. package/dist/extensions/workflows/model.js +7 -0
  292. package/dist/extensions/workflows/model.js.map +1 -0
  293. package/dist/extensions/workflows/repository.d.ts +24 -0
  294. package/dist/extensions/workflows/repository.js +61 -0
  295. package/dist/extensions/workflows/repository.js.map +1 -0
  296. package/dist/extensions/workflows/schema.d.ts +193 -0
  297. package/dist/extensions/workflows/schema.js +20 -0
  298. package/dist/extensions/workflows/schema.js.map +1 -0
  299. package/dist/extensions/workflows/tools.d.ts +27 -0
  300. package/dist/extensions/workflows/tools.js +285 -0
  301. package/dist/extensions/workflows/tools.js.map +1 -0
  302. package/dist/log.d.ts +8 -0
  303. package/dist/log.js +15 -0
  304. package/dist/log.js.map +1 -0
  305. package/dist/main.d.ts +2 -0
  306. package/dist/main.js +27 -0
  307. package/dist/main.js.map +1 -0
  308. package/dist/migration/ask.d.ts +8 -0
  309. package/dist/migration/ask.js +24 -0
  310. package/dist/migration/ask.js.map +1 -0
  311. package/dist/migration/config.d.ts +10 -0
  312. package/dist/migration/config.js +122 -0
  313. package/dist/migration/config.js.map +1 -0
  314. package/dist/migration/context.d.ts +3 -0
  315. package/dist/migration/context.js +24 -0
  316. package/dist/migration/context.js.map +1 -0
  317. package/dist/migration/database.d.ts +8 -0
  318. package/dist/migration/database.js +51 -0
  319. package/dist/migration/database.js.map +1 -0
  320. package/dist/migration/fs.d.ts +1 -0
  321. package/dist/migration/fs.js +11 -0
  322. package/dist/migration/fs.js.map +1 -0
  323. package/dist/migration/index.d.ts +11 -0
  324. package/dist/migration/index.js +28 -0
  325. package/dist/migration/index.js.map +1 -0
  326. package/dist/migration/skills.d.ts +19 -0
  327. package/dist/migration/skills.js +77 -0
  328. package/dist/migration/skills.js.map +1 -0
  329. package/dist/scheduler.d.ts +17 -0
  330. package/dist/scheduler.js +53 -0
  331. package/dist/scheduler.js.map +1 -0
  332. package/dist/sessions/registry.d.ts +15 -0
  333. package/dist/sessions/registry.js +42 -0
  334. package/dist/sessions/registry.js.map +1 -0
  335. package/dist/workspace.d.ts +13 -0
  336. package/dist/workspace.js +32 -0
  337. package/dist/workspace.js.map +1 -0
  338. package/drizzle/0000_init.sql +19 -0
  339. package/drizzle/0001_extensions.sql +63 -0
  340. package/drizzle/meta/0000_snapshot.json +134 -0
  341. package/drizzle/meta/0001_snapshot.json +526 -0
  342. package/drizzle/meta/_journal.json +20 -0
  343. package/package.json +63 -0
  344. package/skills/skill-authoring/SKILL.md +168 -0
  345. package/skills/workflow-authoring/SKILL.md +251 -0
@@ -0,0 +1,189 @@
1
+ import { access, readFile, stat } from "node:fs/promises";
2
+ import { isAbsolute, join, resolve } from "node:path";
3
+ import { hasUncommittedChanges, runGit, runGitCapture } from "./git.js";
4
+ export const DIVERGENCE_STATUS = {
5
+ upToDate: "UP_TO_DATE",
6
+ ahead: "AHEAD",
7
+ behind: "BEHIND",
8
+ diverged: "DIVERGED",
9
+ };
10
+ export const PUSH_RESULT = {
11
+ pushed: "PUSHED",
12
+ nothingToPush: "NOTHING_TO_PUSH",
13
+ rebaseSucceeded: "REBASE_SUCCEEDED",
14
+ pushFailed: "PUSH_FAILED",
15
+ rebaseFailed: "REBASE_FAILED",
16
+ };
17
+ export const SYNC_RESULT = {
18
+ upToDate: "UP_TO_DATE",
19
+ fastForwarded: "FAST_FORWARDED",
20
+ rebaseSucceeded: "REBASE_SUCCEEDED",
21
+ syncFailed: "SYNC_FAILED",
22
+ dirtySkipped: "DIRTY_SKIPPED",
23
+ };
24
+ export const PUSH_SUCCESS = new Set([
25
+ PUSH_RESULT.pushed,
26
+ PUSH_RESULT.rebaseSucceeded,
27
+ ]);
28
+ const exists = async (path) => access(path).then(() => true, () => false);
29
+ /**
30
+ * Resolve the real .git directory, following a gitlink file if present.
31
+ * Submodules and worktrees store `.git` as a file containing `gitdir: <path>`
32
+ * rather than a directory — reading it keeps rebase-state checks working there.
33
+ */
34
+ const resolveGitDir = async (cwd) => {
35
+ const gitPath = join(cwd, ".git");
36
+ try {
37
+ const stats = await stat(gitPath);
38
+ if (stats.isFile()) {
39
+ const content = (await readFile(gitPath, "utf8")).trim();
40
+ const prefix = "gitdir:";
41
+ if (content.startsWith(prefix)) {
42
+ const target = content.slice(prefix.length).trim();
43
+ return isAbsolute(target) ? target : resolve(cwd, target);
44
+ }
45
+ }
46
+ }
47
+ catch {
48
+ return gitPath;
49
+ }
50
+ return gitPath;
51
+ };
52
+ const rebaseInProgress = async (cwd) => {
53
+ const gitDir = await resolveGitDir(cwd);
54
+ return ((await exists(join(gitDir, "rebase-merge"))) || (await exists(join(gitDir, "rebase-apply"))));
55
+ };
56
+ const abortStaleRebase = async (cwd, log) => {
57
+ if (!(await rebaseInProgress(cwd)))
58
+ return;
59
+ log.warn({ path: cwd }, "stale rebase detected — aborting");
60
+ try {
61
+ await runGit(cwd, ["rebase", "--abort"]);
62
+ }
63
+ catch (error) {
64
+ log.warn({ path: cwd, err: error }, "failed to abort stale rebase");
65
+ }
66
+ };
67
+ /**
68
+ * Resolve "HEAD" to the actual local branch name. Remotes don't always have a
69
+ * `refs/remotes/<remote>/HEAD` symbolic ref — repos created via `git init`
70
+ * (rather than cloned) never get one — so passing "HEAD" through to
71
+ * `<remote>/HEAD` breaks the rebase ref and false-positives the
72
+ * `merge-base --is-ancestor` checks into DIVERGED.
73
+ */
74
+ const resolveBranch = async (cwd, branch) => {
75
+ if (branch !== "HEAD")
76
+ return branch;
77
+ const result = await runGitCapture(cwd, ["symbolic-ref", "--short", "HEAD"]);
78
+ if (result.code === 0 && result.stdout !== "")
79
+ return result.stdout;
80
+ return branch;
81
+ };
82
+ /**
83
+ * Classify the relationship between local HEAD and `<remote>/<branch>`.
84
+ * Precondition: `git fetch <remote>` has already run.
85
+ */
86
+ export const detectDivergence = async (cwd, remote = "origin", branch = "HEAD") => {
87
+ const remoteRef = `${remote}/${branch}`;
88
+ const remoteIsAncestor = (await runGitCapture(cwd, ["merge-base", "--is-ancestor", remoteRef, "HEAD"])).code === 0;
89
+ const headIsAncestor = (await runGitCapture(cwd, ["merge-base", "--is-ancestor", "HEAD", remoteRef])).code === 0;
90
+ if (remoteIsAncestor && headIsAncestor)
91
+ return DIVERGENCE_STATUS.upToDate;
92
+ if (remoteIsAncestor)
93
+ return DIVERGENCE_STATUS.ahead;
94
+ if (headIsAncestor)
95
+ return DIVERGENCE_STATUS.behind;
96
+ return DIVERGENCE_STATUS.diverged;
97
+ };
98
+ /**
99
+ * Attempt a naive rebase with --autostash. On conflict, aborts the rebase to
100
+ * restore a clean state and returns false.
101
+ */
102
+ const tryNaiveRebase = async (cwd, remoteBranch, log) => {
103
+ const result = await runGitCapture(cwd, ["rebase", "--autostash", remoteBranch]);
104
+ if (result.code === 0)
105
+ return true;
106
+ if (await rebaseInProgress(cwd)) {
107
+ try {
108
+ await runGit(cwd, ["rebase", "--abort"]);
109
+ }
110
+ catch (error) {
111
+ log.warn({ path: cwd, err: error }, "failed to abort rebase after conflict");
112
+ }
113
+ }
114
+ else {
115
+ log.warn({ path: cwd }, "rebase failed without starting (no conflicts)");
116
+ }
117
+ return false;
118
+ };
119
+ /**
120
+ * Push local commits with divergence recovery: abort stale rebase → fetch →
121
+ * detect divergence → push directly when ahead, or rebase-then-push when
122
+ * diverged. Conflicting rebases are aborted (local commits preserved) and
123
+ * surface as REBASE_FAILED.
124
+ */
125
+ export const smartPush = async (cwd, remote, branch, log) => {
126
+ try {
127
+ await abortStaleRebase(cwd, log);
128
+ await runGit(cwd, ["fetch", remote]);
129
+ const resolved = await resolveBranch(cwd, branch);
130
+ const divergence = await detectDivergence(cwd, remote, resolved);
131
+ if (divergence === DIVERGENCE_STATUS.upToDate || divergence === DIVERGENCE_STATUS.behind) {
132
+ return PUSH_RESULT.nothingToPush;
133
+ }
134
+ if (divergence === DIVERGENCE_STATUS.ahead) {
135
+ await runGit(cwd, ["push", remote, "HEAD"]);
136
+ return PUSH_RESULT.pushed;
137
+ }
138
+ const remoteBranch = `${remote}/${resolved}`;
139
+ if (!(await tryNaiveRebase(cwd, remoteBranch, log)))
140
+ return PUSH_RESULT.rebaseFailed;
141
+ try {
142
+ await runGit(cwd, ["push", remote, "HEAD"]);
143
+ return PUSH_RESULT.rebaseSucceeded;
144
+ }
145
+ catch (error) {
146
+ log.warn({ path: cwd, err: error }, "push failed after successful rebase");
147
+ return PUSH_RESULT.pushFailed;
148
+ }
149
+ }
150
+ catch (error) {
151
+ log.warn({ path: cwd, err: error }, "smart push failed");
152
+ return PUSH_RESULT.rebaseFailed;
153
+ }
154
+ };
155
+ /**
156
+ * Pull remote changes with divergence recovery: skip when dirty, abort stale
157
+ * rebase → fetch → detect divergence → fast-forward when behind, or naive
158
+ * rebase when diverged. Conflicting rebases are aborted and surface as
159
+ * SYNC_FAILED.
160
+ */
161
+ export const smartPull = async (cwd, remote, branch, log) => {
162
+ try {
163
+ if (await hasUncommittedChanges(cwd)) {
164
+ log.warn({ path: cwd }, "working tree has uncommitted changes — skipping sync");
165
+ return SYNC_RESULT.dirtySkipped;
166
+ }
167
+ await abortStaleRebase(cwd, log);
168
+ await runGit(cwd, ["fetch", remote]);
169
+ const resolved = await resolveBranch(cwd, branch);
170
+ const divergence = await detectDivergence(cwd, remote, resolved);
171
+ if (divergence === DIVERGENCE_STATUS.upToDate)
172
+ return SYNC_RESULT.upToDate;
173
+ if (divergence === DIVERGENCE_STATUS.ahead)
174
+ return SYNC_RESULT.upToDate;
175
+ const remoteBranch = `${remote}/${resolved}`;
176
+ if (divergence === DIVERGENCE_STATUS.behind) {
177
+ await runGit(cwd, ["rebase", remoteBranch]);
178
+ return SYNC_RESULT.fastForwarded;
179
+ }
180
+ if (await tryNaiveRebase(cwd, remoteBranch, log))
181
+ return SYNC_RESULT.rebaseSucceeded;
182
+ return SYNC_RESULT.syncFailed;
183
+ }
184
+ catch (error) {
185
+ log.warn({ path: cwd, err: error }, "smart pull failed");
186
+ return SYNC_RESULT.syncFailed;
187
+ }
188
+ };
189
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/extensions/git/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type ExtensionFactory } from "@earendil-works/pi-coding-agent";
2
+ import { type Static, Type } from "typebox";
3
+ import type { Logger } from "../../log.ts";
4
+ import { type Completer } from "./commit.ts";
5
+ export interface GitToolDeps {
6
+ workspaceRoot: string;
7
+ side: Completer;
8
+ log: Logger;
9
+ }
10
+ export declare const QueryGitStatusParams: Type.TObject<{}>;
11
+ export declare const ListRecentCommitsParams: Type.TObject<{
12
+ limit: Type.TOptional<Type.TNumber>;
13
+ }>;
14
+ export declare const CommitWorkspaceParams: Type.TObject<{
15
+ message: Type.TOptional<Type.TString>;
16
+ }>;
17
+ export declare const handleQueryGitStatus: ({ workspaceRoot }: GitToolDeps) => Promise<string>;
18
+ export declare const handleListRecentCommits: ({ workspaceRoot }: GitToolDeps, args: Static<typeof ListRecentCommitsParams>) => Promise<string>;
19
+ export declare const handleCommitWorkspace: ({ workspaceRoot, side, log }: GitToolDeps, args: Static<typeof CommitWorkspaceParams>) => Promise<string>;
20
+ /** pi extension factory exposing the workspace git tools to the agent. */
21
+ export declare const createGitToolsFactory: (deps: GitToolDeps) => ExtensionFactory;
@@ -0,0 +1,101 @@
1
+ import { truncateTail } from "@earendil-works/pi-coding-agent";
2
+ import { Type } from "typebox";
3
+ import { commitAll } from "./commit.js";
4
+ import { runGitCapture } from "./git.js";
5
+ import { workspaceFallbackMessage } from "./processor.js";
6
+ export const QueryGitStatusParams = Type.Object({});
7
+ export const ListRecentCommitsParams = Type.Object({
8
+ limit: Type.Optional(Type.Number({ description: "Maximum number of commits to return (default 10)" })),
9
+ });
10
+ export const CommitWorkspaceParams = Type.Object({
11
+ message: Type.Optional(Type.String({
12
+ description: "Commit message to use; when omitted, a message is generated from the changes",
13
+ })),
14
+ });
15
+ export const handleQueryGitStatus = async ({ workspaceRoot }) => {
16
+ const branch = await runGitCapture(workspaceRoot, ["symbolic-ref", "--short", "HEAD"]);
17
+ const header = branch.code === 0 && branch.stdout !== ""
18
+ ? `On branch ${branch.stdout}`
19
+ : "Detached HEAD or unborn branch";
20
+ const status = await runGitCapture(workspaceRoot, ["status", "--porcelain"]);
21
+ if (status.code !== 0) {
22
+ throw new Error(`git status failed: ${status.stderr || `exit code ${status.code}`}`);
23
+ }
24
+ if (status.stdout === "")
25
+ return `${header}\n\nWorking tree is clean.`;
26
+ const { content } = truncateTail(status.stdout);
27
+ return `${header}\n\nUncommitted changes:\n${content}`;
28
+ };
29
+ export const handleListRecentCommits = async ({ workspaceRoot }, args) => {
30
+ const limit = args.limit ?? 10;
31
+ const result = await runGitCapture(workspaceRoot, [
32
+ "log",
33
+ "-n",
34
+ String(limit),
35
+ "--date=short",
36
+ "--format=%h %ad %s",
37
+ ]);
38
+ if (result.code !== 0 || result.stdout === "")
39
+ return "No commits found.";
40
+ const { content } = truncateTail(result.stdout);
41
+ return `Recent commits:\n${content}`;
42
+ };
43
+ export const handleCommitWorkspace = async ({ workspaceRoot, side, log }, args) => {
44
+ const message = await commitAll({
45
+ cwd: workspaceRoot,
46
+ side,
47
+ fallbackMessage: workspaceFallbackMessage(),
48
+ ...(args.message != null ? { message: args.message } : {}),
49
+ log,
50
+ });
51
+ if (message == null)
52
+ return "Nothing to commit — the working tree is clean.";
53
+ return `Committed workspace changes: ${message}`;
54
+ };
55
+ const textResult = (text) => ({
56
+ content: [{ type: "text", text }],
57
+ details: undefined,
58
+ });
59
+ /** pi extension factory exposing the workspace git tools to the agent. */
60
+ export const createGitToolsFactory = (deps) => (pi) => {
61
+ pi.registerTool({
62
+ name: "query_git_status",
63
+ label: "Query Git Status",
64
+ description: "Show the workspace git status: current branch and any uncommitted changes (modified, added, deleted, untracked files).",
65
+ promptSnippet: "Inspect uncommitted changes in the workspace git repo",
66
+ promptGuidelines: [
67
+ "Use query_git_status to check for pending workspace changes before committing.",
68
+ ],
69
+ parameters: QueryGitStatusParams,
70
+ async execute() {
71
+ return textResult(await handleQueryGitStatus(deps));
72
+ },
73
+ });
74
+ pi.registerTool({
75
+ name: "list_recent_commits",
76
+ label: "List Recent Commits",
77
+ description: "List the most recent commits in the workspace git repo (hash, date, and subject), newest first.",
78
+ promptSnippet: "Review recent workspace commit history",
79
+ promptGuidelines: [
80
+ "Use list_recent_commits when the user asks what changed in the workspace recently.",
81
+ ],
82
+ parameters: ListRecentCommitsParams,
83
+ async execute(_toolCallId, params) {
84
+ return textResult(await handleListRecentCommits(deps, params));
85
+ },
86
+ });
87
+ pi.registerTool({
88
+ name: "commit_workspace",
89
+ label: "Commit Workspace",
90
+ description: "Stage and commit all pending workspace changes in a single commit. A descriptive message is generated from the changes unless one is provided. Changes are also committed automatically at session end — use this only when an immediate commit matters.",
91
+ promptSnippet: "Commit pending workspace changes on demand",
92
+ promptGuidelines: [
93
+ "Use commit_workspace when the user explicitly asks to save or commit workspace changes now.",
94
+ ],
95
+ parameters: CommitWorkspaceParams,
96
+ async execute(_toolCallId, params) {
97
+ return textResult(await handleCommitWorkspace(deps, params));
98
+ },
99
+ });
100
+ };
101
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/extensions/git/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { AgentManager } from "../agent/manager.ts";
2
+ import type { Config } from "../config/schema.ts";
3
+ import type { Coordinator } from "../coordinator.ts";
4
+ import type { AppDatabase } from "../db/index.ts";
5
+ import type { EventBus } from "../events.ts";
6
+ import { type Logger } from "../log.ts";
7
+ import type { Scheduler } from "../scheduler.ts";
8
+ import type { SessionRegistry } from "../sessions/registry.ts";
9
+ import type { Workspace } from "../workspace.ts";
10
+ import type { TachikomaExtension } from "./api.ts";
11
+ import type { Registrations } from "./registrations.ts";
12
+ export interface HostServices {
13
+ config: Config;
14
+ workspace: Workspace;
15
+ log: Logger;
16
+ db: AppDatabase;
17
+ events: EventBus;
18
+ scheduler: Scheduler;
19
+ agent: AgentManager;
20
+ registry: SessionRegistry;
21
+ coordinator: Coordinator;
22
+ regs: Registrations;
23
+ }
24
+ export declare class ExtensionHost {
25
+ private readonly services;
26
+ constructor(services: HostServices);
27
+ private readonly queue;
28
+ load(extensions: TachikomaExtension<never>[]): Promise<void>;
29
+ bootstrap(): Promise<void>;
30
+ private buildContext;
31
+ }
@@ -0,0 +1,75 @@
1
+ import { SideRunner } from "../agent/side-run.js";
2
+ import { parseWithSchema } from "../config/parse.js";
3
+ import { KeyValueState } from "../db/state.js";
4
+ import { componentLogger } from "../log.js";
5
+ export class ExtensionHost {
6
+ services;
7
+ constructor(services) {
8
+ this.services = services;
9
+ }
10
+ queue = [];
11
+ async load(extensions) {
12
+ this.queue.push(...extensions);
13
+ // Extensions may enqueue further extensions (plugins) while loading.
14
+ for (let index = 0; index < this.queue.length; index += 1) {
15
+ const extension = this.queue[index];
16
+ const app = this.buildContext(extension);
17
+ await extension.setup(app);
18
+ this.services.log.debug({ extension: extension.name }, "extension loaded");
19
+ }
20
+ }
21
+ async bootstrap() {
22
+ for (const { name, hook } of this.services.regs.bootstrapHooks) {
23
+ this.services.log.debug({ hook: name }, "bootstrap hook");
24
+ await hook();
25
+ }
26
+ }
27
+ buildContext(extension) {
28
+ const { services } = this;
29
+ const log = componentLogger(services.log, extension.name);
30
+ const rawSection = services.config.extensions[extension.name] ?? {};
31
+ const extensionConfig = extension.configSchema != null
32
+ ? parseWithSchema(extension.configSchema, rawSection, `extensions.${extension.name}`)
33
+ : rawSection;
34
+ return {
35
+ config: services.config,
36
+ extensionConfig,
37
+ workspace: services.workspace,
38
+ log,
39
+ db: services.db,
40
+ state: new KeyValueState(services.db, extension.name),
41
+ events: services.events,
42
+ scheduler: services.scheduler,
43
+ sessions: {
44
+ current: () => services.coordinator.current(),
45
+ get: (id) => services.registry.get(id),
46
+ update: (id, patch) => services.registry.update(id, patch),
47
+ listResumable: () => services.registry.listResumable(services.config.sessions.resumeWindowSeconds),
48
+ close: () => services.coordinator.closeActiveSession(),
49
+ closeIfIdle: () => services.coordinator.closeActiveSessionIfIdle(),
50
+ abortExchange: () => services.coordinator.abortExchange(),
51
+ onOpen: (hook) => services.regs.sessionOpenHooks.push(hook),
52
+ onExchange: (processor) => services.regs.exchangeProcessors.push(processor),
53
+ registerProcessor: (processor) => services.regs.postProcessors.push(processor),
54
+ },
55
+ channels: {
56
+ register: (channel) => services.regs.channels.set(channel.name, channel),
57
+ deliver: (delivery) => services.coordinator.deliver(delivery),
58
+ },
59
+ agent: {
60
+ use: (factory) => services.regs.piFactories.push(factory),
61
+ systemPrompt: (builder) => services.regs.systemPromptBuilders.push(builder),
62
+ provideContext: (provider) => services.regs.contextProviders.push(provider),
63
+ models: services.agent.tiers,
64
+ side: new SideRunner(services.agent, log),
65
+ },
66
+ inbound: {
67
+ use: (middleware) => services.regs.inboundMiddleware.push(middleware),
68
+ },
69
+ bootstrap: (name, hook) => services.regs.bootstrapHooks.push({ name: `${extension.name}:${name}`, hook }),
70
+ status: (text) => services.coordinator.status(text),
71
+ registerExtension: (nested) => this.queue.push(nested),
72
+ };
73
+ }
74
+ }
75
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/extensions/host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { TachikomaExtension } from "./api.ts";
2
+ /** First-party extensions, in load order. */
3
+ export declare const firstPartyExtensions: TachikomaExtension<never>[];
@@ -0,0 +1,32 @@
1
+ import boundary from "./boundary/index.js";
2
+ import commands from "./commands/index.js";
3
+ import context from "./context/index.js";
4
+ import detachedProcesses from "./detached-processes/index.js";
5
+ import external from "./external/index.js";
6
+ import git from "./git/index.js";
7
+ import memory from "./memory/index.js";
8
+ import notifications from "./notifications/index.js";
9
+ import projects from "./projects/index.js";
10
+ import repl from "./repl/index.js";
11
+ import skills from "./skills/index.js";
12
+ import tasks from "./tasks/index.js";
13
+ import telegram from "./telegram/index.js";
14
+ import workflows from "./workflows/index.js";
15
+ /** First-party extensions, in load order. */
16
+ export const firstPartyExtensions = [
17
+ commands,
18
+ context,
19
+ memory,
20
+ projects,
21
+ git,
22
+ boundary,
23
+ skills,
24
+ workflows,
25
+ tasks,
26
+ detachedProcesses,
27
+ notifications,
28
+ repl,
29
+ telegram,
30
+ external,
31
+ ];
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,OAAO,MAAM,oBAAoB,CAAC;AACzC,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAC9D,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,GAAG,MAAM,gBAAgB,CAAC;AACjC,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,aAAa,MAAM,0BAA0B,CAAC;AACrD,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,IAAI,MAAM,iBAAiB,CAAC;AACnC,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,KAAK,MAAM,kBAAkB,CAAC;AACrC,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,SAAS,MAAM,sBAAsB,CAAC;AAE7C,6CAA6C;AAC7C,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ;IACR,OAAO;IACP,MAAM;IACN,QAAQ;IACR,GAAG;IACH,QAAQ;IACR,MAAM;IACN,SAAS;IACT,KAAK;IACL,iBAAiB;IACjB,aAAa;IACb,IAAI;IACJ,QAAQ;IACR,QAAQ;CACsB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { PostProcessor } from "../api.ts";
2
+ /**
3
+ * Copies the pi session JSONL into the workspace so transcripts are
4
+ * git-versioned alongside the memories extracted from them. Named after the
5
+ * pi session id from the JSONL header, falling back to the source filename.
6
+ * Never throws — a failed archive must not block the rest of finalization.
7
+ */
8
+ export declare const createTranscriptArchiveProcessor: (workspaceRoot: string) => PostProcessor;
@@ -0,0 +1,46 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { basename, join } from "node:path";
3
+ import { transcriptsDir } from "./layout.js";
4
+ const headerSessionId = (raw) => {
5
+ const newline = raw.indexOf("\n");
6
+ const firstLine = newline === -1 ? raw : raw.slice(0, newline);
7
+ try {
8
+ const header = JSON.parse(firstLine);
9
+ if (header.type === "session" && typeof header.id === "string" && header.id !== "") {
10
+ return header.id;
11
+ }
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ return null;
17
+ };
18
+ /**
19
+ * Copies the pi session JSONL into the workspace so transcripts are
20
+ * git-versioned alongside the memories extracted from them. Named after the
21
+ * pi session id from the JSONL header, falling back to the source filename.
22
+ * Never throws — a failed archive must not block the rest of finalization.
23
+ */
24
+ export const createTranscriptArchiveProcessor = (workspaceRoot) => ({
25
+ name: "transcript-archive",
26
+ phase: "finalize",
27
+ async process({ transcriptPath, log }) {
28
+ if (transcriptPath == null) {
29
+ log.debug("no transcript — skipping archive");
30
+ return;
31
+ }
32
+ try {
33
+ const raw = await readFile(transcriptPath, "utf8");
34
+ const sessionId = headerSessionId(raw);
35
+ const name = sessionId != null ? `${sessionId}.jsonl` : basename(transcriptPath);
36
+ const dest = join(transcriptsDir(workspaceRoot), name);
37
+ await mkdir(transcriptsDir(workspaceRoot), { recursive: true });
38
+ await writeFile(dest, raw, "utf8");
39
+ log.info({ dest }, "archived transcript");
40
+ }
41
+ catch (error) {
42
+ log.warn({ err: error, src: transcriptPath }, "transcript archive failed");
43
+ }
44
+ },
45
+ });
46
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/extensions/memory/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,eAAe,GAAG,CAAC,GAAW,EAAiB,EAAE;IACrD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAE/D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAoC,CAAC;QAExE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,IAAI,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACnF,OAAO,MAAM,CAAC,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,aAAqB,EAAiB,EAAE,CAAC,CAAC;IACzF,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,UAAU;IAEjB,KAAK,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,GAAG,EAAE;QACnC,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,GAAG,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YACjF,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC;YAEvD,MAAM,KAAK,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAEnC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,qBAAqB,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,2BAA2B,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Local-timezone YYYY-MM-DD — memory filenames follow the user's day, not UTC. */
2
+ export declare const localIsoDate: (date?: Date) => string;
@@ -0,0 +1,7 @@
1
+ /** Local-timezone YYYY-MM-DD — memory filenames follow the user's day, not UTC. */
2
+ export const localIsoDate = (date = new Date()) => {
3
+ const month = String(date.getMonth() + 1).padStart(2, "0");
4
+ const day = String(date.getDate()).padStart(2, "0");
5
+ return `${date.getFullYear()}-${month}-${day}`;
6
+ };
7
+ //# sourceMappingURL=dates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dates.js","sourceRoot":"","sources":["../../../src/extensions/memory/dates.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAa,IAAI,IAAI,EAAE,EAAU,EAAE;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEpD,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;AACjD,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { SideRunner } from "../../agent/side-run.ts";
2
+ import type { PostProcessor } from "../api.ts";
3
+ import { type MemoryStore } from "./layout.ts";
4
+ export declare const MEMORY_FILE_TOOLS: string[];
5
+ export type Runner = Pick<SideRunner, "run">;
6
+ export interface ExtractionDeps {
7
+ side: Runner;
8
+ workspaceRoot: string;
9
+ maxTranscriptChars: number;
10
+ }
11
+ export declare const extractionSystemPrompt: (store: MemoryStore, workspaceRoot: string) => string;
12
+ export declare const conversationPrompt: (conversation: string) => string;
13
+ /**
14
+ * Session-close extraction: re-reads the session transcript and runs a headless
15
+ * agent with file tools to fold the conversation into one memory store.
16
+ */
17
+ export declare const createExtractionProcessor: (store: MemoryStore, { side, workspaceRoot, maxTranscriptChars }: ExtractionDeps) => PostProcessor;