@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,51 @@
1
+ import { rename } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import Database from "better-sqlite3";
4
+ import { pathExists } from "./fs.js";
5
+ export const LEGACY_BACKUP_DB = "tachikoma.legacy-backup.db";
6
+ // Early legacy installs carry an alembic_version table; later ones a hand-rolled
7
+ // schema_migrations table. Either marker means the file predates the drizzle-era schema.
8
+ const LEGACY_MARKER_PROBE = `
9
+ SELECT name FROM sqlite_master
10
+ WHERE type = 'table' AND name IN ('alembic_version', 'schema_migrations')
11
+ `;
12
+ const hasLegacyMarkers = (file) => {
13
+ const db = new Database(file, { readonly: true, fileMustExist: true });
14
+ try {
15
+ return db.prepare(LEGACY_MARKER_PROBE).all().length > 0;
16
+ }
17
+ finally {
18
+ db.close();
19
+ }
20
+ };
21
+ /**
22
+ * Detect a database written by a legacy install and rename it to a backup so
23
+ * drizzle starts from a fresh file. The backup is never deleted.
24
+ */
25
+ export const adaptLegacyDatabase = async (workspace, log) => {
26
+ const file = workspace.databaseFile;
27
+ if (!(await pathExists(file)))
28
+ return;
29
+ let legacyEra;
30
+ try {
31
+ legacyEra = hasLegacyMarkers(file);
32
+ }
33
+ catch (error) {
34
+ log.warn({ file, error }, "could not probe database for legacy markers — leaving it untouched");
35
+ return;
36
+ }
37
+ if (!legacyEra)
38
+ return;
39
+ const backup = join(workspace.dataDir, LEGACY_BACKUP_DB);
40
+ if (await pathExists(backup)) {
41
+ log.warn({ file, backup }, "legacy database detected but a backup already exists — leaving both untouched");
42
+ return;
43
+ }
44
+ // Sidecar journals move with the main file so the backup stays recoverable.
45
+ for (const suffix of ["", "-wal", "-shm"]) {
46
+ if (await pathExists(file + suffix))
47
+ await rename(file + suffix, backup + suffix);
48
+ }
49
+ log.warn({ file, backup }, "legacy database renamed — previous conversation history and tasks are preserved in the backup but are not migrated to the new database");
50
+ };
51
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/migration/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,CAAC,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AAE7D,iFAAiF;AACjF,yFAAyF;AACzF,MAAM,mBAAmB,GAAG;;;CAG3B,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAW,EAAE;IACjD,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvE,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1D,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,SAAoB,EAAE,GAAW,EAAiB,EAAE;IAC5F,MAAM,IAAI,GAAG,SAAS,CAAC,YAAY,CAAC;IAEpC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO;IAEtC,IAAI,SAAkB,CAAC;IAEvB,IAAI,CAAC;QACH,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,oEAAoE,CAAC,CAAC;QAChG,OAAO;IACT,CAAC;IAED,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAEzD,IAAI,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,IAAI,CACN,EAAE,IAAI,EAAE,MAAM,EAAE,EAChB,+EAA+E,CAChF,CAAC;QACF,OAAO;IACT,CAAC;IAED,4EAA4E;IAC5E,KAAK,MAAM,MAAM,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QAC1C,IAAI,MAAM,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC;YAAE,MAAM,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IACpF,CAAC;IAED,GAAG,CAAC,IAAI,CACN,EAAE,IAAI,EAAE,MAAM,EAAE,EAChB,wIAAwI,CACzI,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const pathExists: (path: string) => Promise<boolean>;
@@ -0,0 +1,11 @@
1
+ import { stat } from "node:fs/promises";
2
+ export const pathExists = async (path) => {
3
+ try {
4
+ await stat(path);
5
+ return true;
6
+ }
7
+ catch {
8
+ return false;
9
+ }
10
+ };
11
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/migration/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,IAAY,EAAoB,EAAE;IACjE,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Logger } from "../log.ts";
2
+ import type { Workspace } from "../workspace.ts";
3
+ import { type Ask } from "./ask.ts";
4
+ export { type Ask, createAsk } from "./ask.ts";
5
+ export { adaptConfig } from "./config.ts";
6
+ /**
7
+ * Adapt a workspace last used by a legacy install. Every step is
8
+ * self-detecting and idempotent; a pristine or already-adapted workspace is a
9
+ * fast no-op.
10
+ */
11
+ export declare const adaptWorkspace: (workspace: Workspace, log: Logger, ask?: Ask) => Promise<void>;
@@ -0,0 +1,28 @@
1
+ import { createAsk } from "./ask.js";
2
+ import { adaptContextFiles } from "./context.js";
3
+ import { adaptLegacyDatabase } from "./database.js";
4
+ import { adaptSkillsFrontmatter } from "./skills.js";
5
+ export { createAsk } from "./ask.js";
6
+ export { adaptConfig } from "./config.js";
7
+ /**
8
+ * Adapt a workspace last used by a legacy install. Every step is
9
+ * self-detecting and idempotent; a pristine or already-adapted workspace is a
10
+ * fast no-op.
11
+ */
12
+ export const adaptWorkspace = async (workspace, log, ask = createAsk(log)) => {
13
+ // Must complete before drizzle opens the database file, so failures propagate.
14
+ await adaptLegacyDatabase(workspace, log);
15
+ try {
16
+ await adaptContextFiles(workspace, log);
17
+ }
18
+ catch (error) {
19
+ log.warn({ error }, "context file adaptation failed — continuing startup");
20
+ }
21
+ try {
22
+ await adaptSkillsFrontmatter(workspace, log, ask);
23
+ }
24
+ catch (error) {
25
+ log.warn({ error }, "skills frontmatter adaptation failed — continuing startup");
26
+ }
27
+ };
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migration/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAY,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,SAAoB,EACpB,GAAW,EACX,MAAW,SAAS,CAAC,GAAG,CAAC,EACV,EAAE;IACjB,+EAA+E;IAC/E,MAAM,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAE1C,IAAI,CAAC;QACH,MAAM,iBAAiB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,qDAAqD,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,CAAC;QACH,MAAM,sBAAsB,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,2DAA2D,CAAC,CAAC;IACnF,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { Logger } from "../log.ts";
2
+ import type { Workspace } from "../workspace.ts";
3
+ import type { Ask } from "./ask.ts";
4
+ export interface FrontmatterScan {
5
+ keys: string[];
6
+ content: string;
7
+ }
8
+ /**
9
+ * Detect legacy-only frontmatter keys in a SKILL.md and produce a copy with
10
+ * those keys (and their indented/list continuation lines) removed.
11
+ * Returns null when the file has no frontmatter or no legacy-only keys.
12
+ */
13
+ export declare const stripLegacyFrontmatter: (source: string) => FrontmatterScan | null;
14
+ /**
15
+ * Scan workspace skills for legacy-only frontmatter keys and offer to strip
16
+ * them. Declining (or a non-interactive startup) keeps the files as-is with a
17
+ * warning — pi simply ignores the keys.
18
+ */
19
+ export declare const adaptSkillsFrontmatter: (workspace: Workspace, log: Logger, ask: Ask) => Promise<void>;
@@ -0,0 +1,77 @@
1
+ import { readdir, readFile, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ // Frontmatter keys only the legacy skill registry consumed; pi's Agent Skills
4
+ // loader only knows name/description/disable-model-invocation and ignores the rest.
5
+ const LEGACY_ONLY_KEYS = ["depends_on", "version"];
6
+ /**
7
+ * Detect legacy-only frontmatter keys in a SKILL.md and produce a copy with
8
+ * those keys (and their indented/list continuation lines) removed.
9
+ * Returns null when the file has no frontmatter or no legacy-only keys.
10
+ */
11
+ export const stripLegacyFrontmatter = (source) => {
12
+ const lines = source.split("\n");
13
+ if (lines[0]?.trim() !== "---")
14
+ return null;
15
+ const close = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
16
+ if (close === -1)
17
+ return null;
18
+ const kept = [];
19
+ const found = new Set();
20
+ let skipping = false;
21
+ for (const line of lines.slice(1, close)) {
22
+ const key = /^([\w-]+)\s*:/.exec(line)?.[1];
23
+ if (key != null) {
24
+ skipping = LEGACY_ONLY_KEYS.includes(key);
25
+ if (skipping) {
26
+ found.add(key);
27
+ continue;
28
+ }
29
+ }
30
+ if (skipping)
31
+ continue;
32
+ kept.push(line);
33
+ }
34
+ if (found.size === 0)
35
+ return null;
36
+ return {
37
+ keys: [...found],
38
+ content: [lines[0], ...kept, ...lines.slice(close)].join("\n"),
39
+ };
40
+ };
41
+ /**
42
+ * Scan workspace skills for legacy-only frontmatter keys and offer to strip
43
+ * them. Declining (or a non-interactive startup) keeps the files as-is with a
44
+ * warning — pi simply ignores the keys.
45
+ */
46
+ export const adaptSkillsFrontmatter = async (workspace, log, ask) => {
47
+ const skillsDir = workspace.resolve("skills");
48
+ const entries = await readdir(skillsDir, { withFileTypes: true }).catch(() => []);
49
+ const affected = [];
50
+ for (const entry of entries) {
51
+ if (!entry.isDirectory())
52
+ continue;
53
+ const skillFile = join(skillsDir, entry.name, "SKILL.md");
54
+ let source;
55
+ try {
56
+ source = await readFile(skillFile, "utf8");
57
+ }
58
+ catch {
59
+ continue;
60
+ }
61
+ const scan = stripLegacyFrontmatter(source);
62
+ if (scan != null)
63
+ affected.push({ path: skillFile, scan });
64
+ }
65
+ if (affected.length === 0)
66
+ return;
67
+ const keys = [...new Set(affected.flatMap(({ scan }) => scan.keys))].join(", ");
68
+ if (!(await ask(`Strip unsupported frontmatter keys (${keys}) from ${affected.length} skill(s)?`))) {
69
+ log.warn({ skills: affected.length, keys }, "keeping legacy-only frontmatter keys — pi ignores them (skill dependency chains are not supported)");
70
+ return;
71
+ }
72
+ for (const { path, scan } of affected) {
73
+ await writeFile(path, scan.content, "utf8");
74
+ log.info({ file: path, keys: scan.keys }, "stripped legacy-only frontmatter keys");
75
+ }
76
+ };
77
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/migration/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Logger } from "./log.ts";
2
+ export interface ScheduledJob {
3
+ name: string;
4
+ stop(): void;
5
+ trigger(): Promise<void>;
6
+ }
7
+ export declare class Scheduler {
8
+ private readonly jobs;
9
+ private readonly log;
10
+ private readonly timezone?;
11
+ constructor(log: Logger, timezone?: string);
12
+ cron(name: string, pattern: string, fn: () => void | Promise<void>): ScheduledJob;
13
+ every(name: string, seconds: number, fn: () => void | Promise<void>): ScheduledJob;
14
+ stopAll(): void;
15
+ private register;
16
+ private guarded;
17
+ }
@@ -0,0 +1,53 @@
1
+ import { Cron } from "croner";
2
+ export class Scheduler {
3
+ jobs = new Map();
4
+ log;
5
+ timezone;
6
+ constructor(log, timezone) {
7
+ this.log = log;
8
+ this.timezone = timezone;
9
+ }
10
+ cron(name, pattern, fn) {
11
+ const run = this.guarded(name, fn);
12
+ const job = new Cron(pattern, { timezone: this.timezone, protect: true, catch: true }, run);
13
+ const handle = {
14
+ name,
15
+ stop: () => job.stop(),
16
+ trigger: run,
17
+ };
18
+ this.register(handle);
19
+ return handle;
20
+ }
21
+ every(name, seconds, fn) {
22
+ const run = this.guarded(name, fn);
23
+ const interval = setInterval(run, seconds * 1000);
24
+ interval.unref();
25
+ const handle = {
26
+ name,
27
+ stop: () => clearInterval(interval),
28
+ trigger: run,
29
+ };
30
+ this.register(handle);
31
+ return handle;
32
+ }
33
+ stopAll() {
34
+ for (const job of this.jobs.values())
35
+ job.stop();
36
+ this.jobs.clear();
37
+ }
38
+ register(job) {
39
+ this.jobs.get(job.name)?.stop();
40
+ this.jobs.set(job.name, job);
41
+ }
42
+ guarded(name, fn) {
43
+ return async () => {
44
+ try {
45
+ await fn();
46
+ }
47
+ catch (error) {
48
+ this.log.error({ job: name, err: error }, "scheduled job failed");
49
+ }
50
+ };
51
+ }
52
+ }
53
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAU9B,MAAM,OAAO,SAAS;IACH,IAAI,GAAG,IAAI,GAAG,EAAwB,CAAC;IACvC,GAAG,CAAS;IACZ,QAAQ,CAAU;IAEnC,YAAY,GAAW,EAAE,QAAiB;QACxC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,OAAe,EAAE,EAA8B;QAChE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEnC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5F,MAAM,MAAM,GAAiB;YAC3B,IAAI;YACJ,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE;YACtB,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAY,EAAE,OAAe,EAAE,EAA8B;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEnC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;QAClD,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEjB,MAAM,MAAM,GAAiB;YAC3B,IAAI;YACJ,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC;YACnC,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO;QACL,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,GAAG,CAAC,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAEO,QAAQ,CAAC,GAAiB;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;IAEO,OAAO,CAAC,IAAY,EAAE,EAA8B;QAC1D,OAAO,KAAK,IAAI,EAAE;YAChB,IAAI,CAAC;gBACH,MAAM,EAAE,EAAE,CAAC;YACb,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,sBAAsB,CAAC,CAAC;YACpE,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import { type SessionRecord } from "../db/core-schema.ts";
2
+ import type { AppDatabase } from "../db/index.ts";
3
+ export declare class SessionRegistry {
4
+ private readonly db;
5
+ constructor(db: AppDatabase);
6
+ create(channel: string, piSessionFile: string | null): SessionRecord;
7
+ get(id: number): SessionRecord | null;
8
+ update(id: number, patch: Partial<Omit<SessionRecord, "id">>): SessionRecord;
9
+ close(id: number): SessionRecord;
10
+ reopen(id: number): SessionRecord;
11
+ /** Sessions left open by a previous run (crash or restart). */
12
+ findDangling(): SessionRecord[];
13
+ /** Closed sessions recent enough to be candidates for topic resumption. */
14
+ listResumable(windowSeconds: number): SessionRecord[];
15
+ }
@@ -0,0 +1,42 @@
1
+ import { and, desc, eq, gt, isNull } from "drizzle-orm";
2
+ import { sessions } from "../db/core-schema.js";
3
+ export class SessionRegistry {
4
+ db;
5
+ constructor(db) {
6
+ this.db = db;
7
+ }
8
+ create(channel, piSessionFile) {
9
+ return this.db
10
+ .insert(sessions)
11
+ .values({ channel, piSessionFile, createdAt: new Date() })
12
+ .returning()
13
+ .get();
14
+ }
15
+ get(id) {
16
+ return this.db.select().from(sessions).where(eq(sessions.id, id)).get() ?? null;
17
+ }
18
+ update(id, patch) {
19
+ return this.db.update(sessions).set(patch).where(eq(sessions.id, id)).returning().get();
20
+ }
21
+ close(id) {
22
+ return this.update(id, { closedAt: new Date() });
23
+ }
24
+ reopen(id) {
25
+ return this.update(id, { closedAt: null, lastResumedAt: new Date() });
26
+ }
27
+ /** Sessions left open by a previous run (crash or restart). */
28
+ findDangling() {
29
+ return this.db.select().from(sessions).where(isNull(sessions.closedAt)).all();
30
+ }
31
+ /** Closed sessions recent enough to be candidates for topic resumption. */
32
+ listResumable(windowSeconds) {
33
+ const cutoff = new Date(Date.now() - windowSeconds * 1000);
34
+ return this.db
35
+ .select()
36
+ .from(sessions)
37
+ .where(and(gt(sessions.closedAt, cutoff)))
38
+ .orderBy(desc(sessions.closedAt))
39
+ .all();
40
+ }
41
+ }
42
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/sessions/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAsB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGpE,MAAM,OAAO,eAAe;IACT,EAAE,CAAc;IAEjC,YAAY,EAAe;QACzB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,aAA4B;QAClD,OAAO,IAAI,CAAC,EAAE;aACX,MAAM,CAAC,QAAQ,CAAC;aAChB,MAAM,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;aACzD,SAAS,EAAE;aACX,GAAG,EAAE,CAAC;IACX,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;IAClF,CAAC;IAED,MAAM,CAAC,EAAU,EAAE,KAAyC;QAC1D,OAAO,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC;IAC1F,CAAC;IAED,KAAK,CAAC,EAAU;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,+DAA+D;IAC/D,YAAY;QACV,OAAO,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAChF,CAAC;IAED,2EAA2E;IAC3E,aAAa,CAAC,aAAqB;QACjC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,IAAI,CAAC,CAAC;QAE3D,OAAO,IAAI,CAAC,EAAE;aACX,MAAM,EAAE;aACR,IAAI,CAAC,QAAQ,CAAC;aACd,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;aACzC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;aAChC,GAAG,EAAE,CAAC;IACX,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ export declare const expandHome: (path: string) => string;
2
+ export declare class Workspace {
3
+ readonly root: string;
4
+ constructor(configuredPath: string);
5
+ resolve(...parts: string[]): string;
6
+ /** Internal data (database, pi state) — never committed to the workspace repo. */
7
+ get dataDir(): string;
8
+ /** Dedicated pi agent dir so Tachikoma never collides with a user's own pi install. */
9
+ get piDir(): string;
10
+ get sessionsDir(): string;
11
+ get databaseFile(): string;
12
+ ensure(): Promise<void>;
13
+ }
@@ -0,0 +1,32 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { isAbsolute, join, resolve } from "node:path";
4
+ export const expandHome = (path) => path === "~" || path.startsWith("~/") ? join(homedir(), path.slice(1)) : path;
5
+ export class Workspace {
6
+ root;
7
+ constructor(configuredPath) {
8
+ const expanded = expandHome(configuredPath);
9
+ this.root = isAbsolute(expanded) ? expanded : resolve(expanded);
10
+ }
11
+ resolve(...parts) {
12
+ return join(this.root, ...parts);
13
+ }
14
+ /** Internal data (database, pi state) — never committed to the workspace repo. */
15
+ get dataDir() {
16
+ return this.resolve(".tachikoma");
17
+ }
18
+ /** Dedicated pi agent dir so Tachikoma never collides with a user's own pi install. */
19
+ get piDir() {
20
+ return join(this.dataDir, "pi");
21
+ }
22
+ get sessionsDir() {
23
+ return join(this.piDir, "sessions");
24
+ }
25
+ get databaseFile() {
26
+ return join(this.dataDir, "tachikoma.db");
27
+ }
28
+ async ensure() {
29
+ await mkdir(this.sessionsDir, { recursive: true });
30
+ }
31
+ }
32
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE,CACjD,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAEhF,MAAM,OAAO,SAAS;IACX,IAAI,CAAS;IAEtB,YAAY,cAAsB;QAChC,MAAM,QAAQ,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,CAAC,GAAG,KAAe;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,kFAAkF;IAClF,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC;IAED,uFAAuF;IACvF,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ CREATE TABLE `app_state` (
2
+ `namespace` text NOT NULL,
3
+ `key` text NOT NULL,
4
+ `value` text,
5
+ `updated_at` integer NOT NULL,
6
+ PRIMARY KEY(`namespace`, `key`)
7
+ );
8
+ --> statement-breakpoint
9
+ CREATE TABLE `sessions` (
10
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
11
+ `channel` text NOT NULL,
12
+ `pi_session_file` text,
13
+ `summary` text,
14
+ `last_exchange` text,
15
+ `created_at` integer NOT NULL,
16
+ `closed_at` integer,
17
+ `last_resumed_at` integer,
18
+ `post_processing_state` text
19
+ );
@@ -0,0 +1,63 @@
1
+ CREATE TABLE `detached_processes` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `name` text NOT NULL,
4
+ `command` text NOT NULL,
5
+ `cwd` text NOT NULL,
6
+ `pid` integer NOT NULL,
7
+ `status` text NOT NULL,
8
+ `exit_code` integer,
9
+ `stop_reason` text,
10
+ `stdout_path` text NOT NULL,
11
+ `stderr_path` text NOT NULL,
12
+ `memory_limit_mb` integer,
13
+ `started_at` integer NOT NULL,
14
+ `exited_at` integer
15
+ );
16
+ --> statement-breakpoint
17
+ CREATE INDEX `ix_detached_processes_status` ON `detached_processes` (`status`);--> statement-breakpoint
18
+ CREATE TABLE `task_definitions` (
19
+ `id` text PRIMARY KEY NOT NULL,
20
+ `name` text NOT NULL,
21
+ `schedule` text NOT NULL,
22
+ `task_type` text NOT NULL,
23
+ `prompt` text NOT NULL,
24
+ `enabled` integer DEFAULT true NOT NULL,
25
+ `last_fired_at` integer,
26
+ `since` integer NOT NULL,
27
+ `created_at` integer NOT NULL
28
+ );
29
+ --> statement-breakpoint
30
+ CREATE TABLE `task_instances` (
31
+ `id` text PRIMARY KEY NOT NULL,
32
+ `definition_id` text,
33
+ `task_type` text NOT NULL,
34
+ `status` text NOT NULL,
35
+ `prompt` text NOT NULL,
36
+ `scheduled_for` integer NOT NULL,
37
+ `started_at` integer,
38
+ `completed_at` integer,
39
+ `result` text,
40
+ `user_response` text,
41
+ `updated_at` integer NOT NULL,
42
+ `created_at` integer NOT NULL,
43
+ FOREIGN KEY (`definition_id`) REFERENCES `task_definitions`(`id`) ON UPDATE no action ON DELETE no action
44
+ );
45
+ --> statement-breakpoint
46
+ CREATE INDEX `ix_task_instances_status` ON `task_instances` (`status`);--> statement-breakpoint
47
+ CREATE INDEX `ix_task_instances_task_type` ON `task_instances` (`task_type`);--> statement-breakpoint
48
+ CREATE TABLE `workflow_states` (
49
+ `id` text PRIMARY KEY NOT NULL,
50
+ `skill_name` text NOT NULL,
51
+ `workflow_name` text NOT NULL,
52
+ `current_step` text,
53
+ `step_states` text NOT NULL,
54
+ `definition_snapshot` text NOT NULL,
55
+ `scratchpad_path` text NOT NULL,
56
+ `deleted_at` integer,
57
+ `created_at` integer NOT NULL,
58
+ `updated_at` integer NOT NULL
59
+ );
60
+ --> statement-breakpoint
61
+ CREATE INDEX `ix_workflow_states_skill_name` ON `workflow_states` (`skill_name`);--> statement-breakpoint
62
+ CREATE INDEX `ix_workflow_states_workflow_name` ON `workflow_states` (`workflow_name`);--> statement-breakpoint
63
+ CREATE INDEX `ix_workflow_states_active_lookup` ON `workflow_states` (`skill_name`,`workflow_name`);
@@ -0,0 +1,134 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "0e7e2887-d267-4539-afb6-64b542a6d735",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "app_state": {
8
+ "name": "app_state",
9
+ "columns": {
10
+ "namespace": {
11
+ "name": "namespace",
12
+ "type": "text",
13
+ "primaryKey": false,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "key": {
18
+ "name": "key",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "value": {
25
+ "name": "value",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": false,
29
+ "autoincrement": false
30
+ },
31
+ "updated_at": {
32
+ "name": "updated_at",
33
+ "type": "integer",
34
+ "primaryKey": false,
35
+ "notNull": true,
36
+ "autoincrement": false
37
+ }
38
+ },
39
+ "indexes": {},
40
+ "foreignKeys": {},
41
+ "compositePrimaryKeys": {
42
+ "app_state_namespace_key_pk": {
43
+ "columns": ["namespace", "key"],
44
+ "name": "app_state_namespace_key_pk"
45
+ }
46
+ },
47
+ "uniqueConstraints": {},
48
+ "checkConstraints": {}
49
+ },
50
+ "sessions": {
51
+ "name": "sessions",
52
+ "columns": {
53
+ "id": {
54
+ "name": "id",
55
+ "type": "integer",
56
+ "primaryKey": true,
57
+ "notNull": true,
58
+ "autoincrement": true
59
+ },
60
+ "channel": {
61
+ "name": "channel",
62
+ "type": "text",
63
+ "primaryKey": false,
64
+ "notNull": true,
65
+ "autoincrement": false
66
+ },
67
+ "pi_session_file": {
68
+ "name": "pi_session_file",
69
+ "type": "text",
70
+ "primaryKey": false,
71
+ "notNull": false,
72
+ "autoincrement": false
73
+ },
74
+ "summary": {
75
+ "name": "summary",
76
+ "type": "text",
77
+ "primaryKey": false,
78
+ "notNull": false,
79
+ "autoincrement": false
80
+ },
81
+ "last_exchange": {
82
+ "name": "last_exchange",
83
+ "type": "text",
84
+ "primaryKey": false,
85
+ "notNull": false,
86
+ "autoincrement": false
87
+ },
88
+ "created_at": {
89
+ "name": "created_at",
90
+ "type": "integer",
91
+ "primaryKey": false,
92
+ "notNull": true,
93
+ "autoincrement": false
94
+ },
95
+ "closed_at": {
96
+ "name": "closed_at",
97
+ "type": "integer",
98
+ "primaryKey": false,
99
+ "notNull": false,
100
+ "autoincrement": false
101
+ },
102
+ "last_resumed_at": {
103
+ "name": "last_resumed_at",
104
+ "type": "integer",
105
+ "primaryKey": false,
106
+ "notNull": false,
107
+ "autoincrement": false
108
+ },
109
+ "post_processing_state": {
110
+ "name": "post_processing_state",
111
+ "type": "text",
112
+ "primaryKey": false,
113
+ "notNull": false,
114
+ "autoincrement": false
115
+ }
116
+ },
117
+ "indexes": {},
118
+ "foreignKeys": {},
119
+ "compositePrimaryKeys": {},
120
+ "uniqueConstraints": {},
121
+ "checkConstraints": {}
122
+ }
123
+ },
124
+ "views": {},
125
+ "enums": {},
126
+ "_meta": {
127
+ "schemas": {},
128
+ "tables": {},
129
+ "columns": {}
130
+ },
131
+ "internal": {
132
+ "indexes": {}
133
+ }
134
+ }