siclaw 0.1.0 → 0.1.2

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 (270) hide show
  1. package/README.md +75 -114
  2. package/dist/agentbox/gateway-client.d.ts +2 -1
  3. package/dist/agentbox/gateway-client.js +6 -2
  4. package/dist/agentbox/gateway-client.js.map +1 -1
  5. package/dist/agentbox/http-server.js +184 -19
  6. package/dist/agentbox/http-server.js.map +1 -1
  7. package/dist/agentbox/resource-handlers.d.ts +1 -0
  8. package/dist/agentbox/resource-handlers.js +23 -23
  9. package/dist/agentbox/resource-handlers.js.map +1 -1
  10. package/dist/agentbox/session.js +85 -5
  11. package/dist/agentbox/session.js.map +1 -1
  12. package/dist/agentbox-main.d.ts +2 -1
  13. package/dist/agentbox-main.js +65 -18
  14. package/dist/agentbox-main.js.map +1 -1
  15. package/dist/cli-credentials.d.ts +1 -0
  16. package/dist/cli-credentials.js +109 -0
  17. package/dist/cli-credentials.js.map +1 -0
  18. package/dist/cli-first-run.d.ts +11 -0
  19. package/dist/cli-first-run.js +99 -0
  20. package/dist/cli-first-run.js.map +1 -0
  21. package/dist/cli-main.js +33 -11
  22. package/dist/cli-main.js.map +1 -1
  23. package/dist/cli-setup.d.ts +5 -11
  24. package/dist/cli-setup.js +12 -225
  25. package/dist/cli-setup.js.map +1 -1
  26. package/dist/core/agent-factory.d.ts +4 -0
  27. package/dist/core/agent-factory.js +102 -151
  28. package/dist/core/agent-factory.js.map +1 -1
  29. package/dist/core/config.d.ts +10 -3
  30. package/dist/core/config.js +11 -95
  31. package/dist/core/config.js.map +1 -1
  32. package/dist/core/extensions/deep-investigation.d.ts +2 -1
  33. package/dist/core/extensions/deep-investigation.js +144 -24
  34. package/dist/core/extensions/deep-investigation.js.map +1 -1
  35. package/dist/core/extensions/setup.d.ts +8 -0
  36. package/dist/core/extensions/setup.js +669 -0
  37. package/dist/core/extensions/setup.js.map +1 -0
  38. package/dist/core/llm-proxy.js +7 -3
  39. package/dist/core/llm-proxy.js.map +1 -1
  40. package/dist/core/mcp-client.d.ts +0 -10
  41. package/dist/core/mcp-client.js +0 -65
  42. package/dist/core/mcp-client.js.map +1 -1
  43. package/dist/core/prompt.d.ts +1 -1
  44. package/dist/core/prompt.js +42 -5
  45. package/dist/core/prompt.js.map +1 -1
  46. package/dist/core/provider-presets.d.ts +14 -0
  47. package/dist/core/provider-presets.js +81 -0
  48. package/dist/core/provider-presets.js.map +1 -0
  49. package/dist/cron/cron-coordinator.d.ts +2 -0
  50. package/dist/cron/cron-coordinator.js +46 -14
  51. package/dist/cron/cron-coordinator.js.map +1 -1
  52. package/dist/cron/cron-executor.js +33 -8
  53. package/dist/cron/cron-executor.js.map +1 -1
  54. package/dist/cron/cron-scheduler.d.ts +1 -1
  55. package/dist/cron/gateway-client.d.ts +5 -0
  56. package/dist/cron/gateway-client.js +43 -8
  57. package/dist/cron/gateway-client.js.map +1 -1
  58. package/dist/cron-main.js +39 -9
  59. package/dist/cron-main.js.map +1 -1
  60. package/dist/gateway/agentbox/client.d.ts +11 -0
  61. package/dist/gateway/agentbox/client.js +18 -0
  62. package/dist/gateway/agentbox/client.js.map +1 -1
  63. package/dist/gateway/agentbox/k8s-spawner.d.ts +11 -2
  64. package/dist/gateway/agentbox/k8s-spawner.js +95 -52
  65. package/dist/gateway/agentbox/k8s-spawner.js.map +1 -1
  66. package/dist/gateway/agentbox/local-spawner.d.ts +1 -1
  67. package/dist/gateway/agentbox/local-spawner.js +4 -2
  68. package/dist/gateway/agentbox/local-spawner.js.map +1 -1
  69. package/dist/gateway/agentbox/manager.d.ts +0 -10
  70. package/dist/gateway/agentbox/manager.js +11 -30
  71. package/dist/gateway/agentbox/manager.js.map +1 -1
  72. package/dist/gateway/agentbox/types.d.ts +6 -4
  73. package/dist/gateway/cron/cron-service.d.ts +49 -0
  74. package/dist/gateway/cron/cron-service.js +259 -0
  75. package/dist/gateway/cron/cron-service.js.map +1 -0
  76. package/dist/gateway/db/init-schema.js +44 -0
  77. package/dist/gateway/db/init-schema.js.map +1 -1
  78. package/dist/gateway/db/migrate-sqlite.js +73 -4
  79. package/dist/gateway/db/migrate-sqlite.js.map +1 -1
  80. package/dist/gateway/db/repositories/chat-repo.d.ts +56 -2
  81. package/dist/gateway/db/repositories/chat-repo.js +132 -2
  82. package/dist/gateway/db/repositories/chat-repo.js.map +1 -1
  83. package/dist/gateway/db/repositories/config-repo.d.ts +31 -2
  84. package/dist/gateway/db/repositories/config-repo.js +57 -7
  85. package/dist/gateway/db/repositories/config-repo.js.map +1 -1
  86. package/dist/gateway/db/repositories/env-repo.d.ts +14 -0
  87. package/dist/gateway/db/repositories/env-repo.js +15 -2
  88. package/dist/gateway/db/repositories/env-repo.js.map +1 -1
  89. package/dist/gateway/db/repositories/model-config-repo.d.ts +1 -1
  90. package/dist/gateway/db/repositories/model-config-repo.js +26 -12
  91. package/dist/gateway/db/repositories/model-config-repo.js.map +1 -1
  92. package/dist/gateway/db/repositories/skill-repo.d.ts +0 -5
  93. package/dist/gateway/db/repositories/skill-review-repo.d.ts +1 -0
  94. package/dist/gateway/db/repositories/skill-review-repo.js +4 -1
  95. package/dist/gateway/db/repositories/skill-review-repo.js.map +1 -1
  96. package/dist/gateway/db/repositories/skill-version-repo.js +0 -1
  97. package/dist/gateway/db/repositories/skill-version-repo.js.map +1 -1
  98. package/dist/gateway/db/repositories/system-config-repo.d.ts +1 -1
  99. package/dist/gateway/db/repositories/system-config-repo.js +2 -1
  100. package/dist/gateway/db/repositories/system-config-repo.js.map +1 -1
  101. package/dist/gateway/db/repositories/user-env-config-repo.d.ts +13 -0
  102. package/dist/gateway/db/repositories/user-env-config-repo.js +11 -0
  103. package/dist/gateway/db/repositories/user-env-config-repo.js.map +1 -1
  104. package/dist/gateway/db/repositories/workspace-repo.d.ts +3 -2
  105. package/dist/gateway/db/repositories/workspace-repo.js +6 -2
  106. package/dist/gateway/db/repositories/workspace-repo.js.map +1 -1
  107. package/dist/gateway/db/schema-mysql.d.ts +473 -51
  108. package/dist/gateway/db/schema-mysql.js +35 -4
  109. package/dist/gateway/db/schema-mysql.js.map +1 -1
  110. package/dist/gateway/db/schema-sqlite.d.ts +522 -57
  111. package/dist/gateway/db/schema-sqlite.js +38 -6
  112. package/dist/gateway/db/schema-sqlite.js.map +1 -1
  113. package/dist/gateway/db/schema.d.ts +471 -51
  114. package/dist/gateway/db/schema.js +1 -1
  115. package/dist/gateway/db/schema.js.map +1 -1
  116. package/dist/gateway/metrics-aggregator.d.ts +65 -0
  117. package/dist/gateway/metrics-aggregator.js +244 -0
  118. package/dist/gateway/metrics-aggregator.js.map +1 -0
  119. package/dist/gateway/plugins/channel-bridge.d.ts +4 -1
  120. package/dist/gateway/plugins/channel-bridge.js +78 -86
  121. package/dist/gateway/plugins/channel-bridge.js.map +1 -1
  122. package/dist/gateway/rpc-methods.d.ts +4 -2
  123. package/dist/gateway/rpc-methods.js +962 -163
  124. package/dist/gateway/rpc-methods.js.map +1 -1
  125. package/dist/gateway/security/cert-manager.d.ts +2 -2
  126. package/dist/gateway/security/cert-manager.js +4 -2
  127. package/dist/gateway/security/cert-manager.js.map +1 -1
  128. package/dist/gateway/server.d.ts +4 -8
  129. package/dist/gateway/server.js +297 -261
  130. package/dist/gateway/server.js.map +1 -1
  131. package/dist/gateway/skills/file-writer.js +17 -11
  132. package/dist/gateway/skills/file-writer.js.map +1 -1
  133. package/dist/gateway/skills/script-evaluator.js +12 -9
  134. package/dist/gateway/skills/script-evaluator.js.map +1 -1
  135. package/dist/gateway/web/dist/assets/index-0p17ZeTP.js +740 -0
  136. package/dist/gateway/web/dist/assets/index-9eP6nPUq.js +741 -0
  137. package/dist/gateway/web/dist/assets/index-9eP6nPUq.js.map +1 -0
  138. package/dist/gateway/web/dist/assets/index-CAmSY91d.js +675 -0
  139. package/dist/gateway/web/dist/assets/index-DMFEh8Pp.css +1 -0
  140. package/dist/gateway/web/dist/assets/index-DyowBCEj.css +1 -0
  141. package/dist/gateway/web/dist/assets/index-PDK5JJDO.css +1 -0
  142. package/dist/gateway/web/dist/index.html +2 -2
  143. package/dist/gateway-main.js +27 -10
  144. package/dist/gateway-main.js.map +1 -1
  145. package/dist/memory/embeddings.js +5 -4
  146. package/dist/memory/embeddings.js.map +1 -1
  147. package/dist/memory/indexer.d.ts +23 -3
  148. package/dist/memory/indexer.js +235 -23
  149. package/dist/memory/indexer.js.map +1 -1
  150. package/dist/memory/schema.js +15 -1
  151. package/dist/memory/schema.js.map +1 -1
  152. package/dist/memory/types.d.ts +18 -0
  153. package/dist/memory/types.js +6 -1
  154. package/dist/memory/types.js.map +1 -1
  155. package/dist/shared/detect-language.d.ts +12 -0
  156. package/dist/shared/detect-language.js +78 -0
  157. package/dist/shared/detect-language.js.map +1 -0
  158. package/dist/shared/diagnostic-events.d.ts +70 -0
  159. package/dist/shared/diagnostic-events.js +38 -0
  160. package/dist/shared/diagnostic-events.js.map +1 -0
  161. package/dist/shared/local-collector.d.ts +56 -0
  162. package/dist/shared/local-collector.js +284 -0
  163. package/dist/shared/local-collector.js.map +1 -0
  164. package/dist/shared/metrics-types.d.ts +64 -0
  165. package/dist/shared/metrics-types.js +25 -0
  166. package/dist/shared/metrics-types.js.map +1 -0
  167. package/dist/shared/metrics.d.ts +19 -0
  168. package/dist/shared/metrics.js +185 -0
  169. package/dist/shared/metrics.js.map +1 -0
  170. package/dist/shared/path-utils.d.ts +15 -0
  171. package/dist/shared/path-utils.js +23 -0
  172. package/dist/shared/path-utils.js.map +1 -0
  173. package/dist/shared/retry.d.ts +35 -0
  174. package/dist/shared/retry.js +61 -0
  175. package/dist/shared/retry.js.map +1 -0
  176. package/dist/tools/command-sets.d.ts +18 -2
  177. package/dist/tools/command-sets.js +207 -32
  178. package/dist/tools/command-sets.js.map +1 -1
  179. package/dist/tools/command-validator.d.ts +56 -0
  180. package/dist/tools/command-validator.js +357 -0
  181. package/dist/tools/command-validator.js.map +1 -0
  182. package/dist/tools/create-skill.js +26 -1
  183. package/dist/tools/create-skill.js.map +1 -1
  184. package/dist/tools/credential-list.js +1 -23
  185. package/dist/tools/credential-list.js.map +1 -1
  186. package/dist/tools/credential-manager.d.ts +98 -0
  187. package/dist/tools/credential-manager.js +313 -0
  188. package/dist/tools/credential-manager.js.map +1 -0
  189. package/dist/tools/deep-search/engine.js +184 -127
  190. package/dist/tools/deep-search/engine.js.map +1 -1
  191. package/dist/tools/deep-search/prompts.d.ts +10 -2
  192. package/dist/tools/deep-search/prompts.js +37 -36
  193. package/dist/tools/deep-search/prompts.js.map +1 -1
  194. package/dist/tools/deep-search/schemas.d.ts +87 -0
  195. package/dist/tools/deep-search/schemas.js +85 -0
  196. package/dist/tools/deep-search/schemas.js.map +1 -0
  197. package/dist/tools/deep-search/sub-agent.d.ts +21 -0
  198. package/dist/tools/deep-search/sub-agent.js +153 -4
  199. package/dist/tools/deep-search/sub-agent.js.map +1 -1
  200. package/dist/tools/deep-search/tool.js +1 -0
  201. package/dist/tools/deep-search/tool.js.map +1 -1
  202. package/dist/tools/deep-search/types.d.ts +2 -0
  203. package/dist/tools/deep-search/types.js.map +1 -1
  204. package/dist/tools/dp-tools.js +29 -5
  205. package/dist/tools/dp-tools.js.map +1 -1
  206. package/dist/tools/exec-utils.d.ts +85 -0
  207. package/dist/tools/exec-utils.js +294 -0
  208. package/dist/tools/exec-utils.js.map +1 -0
  209. package/dist/tools/fork-skill.js +14 -2
  210. package/dist/tools/fork-skill.js.map +1 -1
  211. package/dist/tools/investigation-feedback.d.ts +3 -0
  212. package/dist/tools/investigation-feedback.js +71 -0
  213. package/dist/tools/investigation-feedback.js.map +1 -0
  214. package/dist/tools/manage-schedule.js +16 -6
  215. package/dist/tools/manage-schedule.js.map +1 -1
  216. package/dist/tools/netns-script.js +27 -281
  217. package/dist/tools/netns-script.js.map +1 -1
  218. package/dist/tools/node-exec.d.ts +2 -14
  219. package/dist/tools/node-exec.js +18 -225
  220. package/dist/tools/node-exec.js.map +1 -1
  221. package/dist/tools/node-script.js +14 -168
  222. package/dist/tools/node-script.js.map +1 -1
  223. package/dist/tools/pod-exec.d.ts +1 -1
  224. package/dist/tools/pod-exec.js +10 -26
  225. package/dist/tools/pod-exec.js.map +1 -1
  226. package/dist/tools/pod-nsenter-exec.js +21 -225
  227. package/dist/tools/pod-nsenter-exec.js.map +1 -1
  228. package/dist/tools/pod-script.js +10 -19
  229. package/dist/tools/pod-script.js.map +1 -1
  230. package/dist/tools/restricted-bash.d.ts +1 -17
  231. package/dist/tools/restricted-bash.js +38 -252
  232. package/dist/tools/restricted-bash.js.map +1 -1
  233. package/dist/tools/run-skill.d.ts +3 -1
  234. package/dist/tools/run-skill.js +21 -1
  235. package/dist/tools/run-skill.js.map +1 -1
  236. package/dist/tools/script-resolver.d.ts +3 -1
  237. package/dist/tools/script-resolver.js +74 -30
  238. package/dist/tools/script-resolver.js.map +1 -1
  239. package/dist/tools/update-skill.js +17 -6
  240. package/dist/tools/update-skill.js.map +1 -1
  241. package/package.json +8 -6
  242. package/siclaw.mjs +10 -1
  243. package/skills/core/cluster-events/SKILL.md +1 -1
  244. package/skills/core/deep-investigation/SKILL.md +11 -0
  245. package/skills/core/deployment-rollout-debug/SKILL.md +1 -1
  246. package/skills/core/dns-debug/SKILL.md +1 -0
  247. package/skills/core/meta.json +12 -1
  248. package/skills/core/networkpolicy-debug/SKILL.md +332 -0
  249. package/skills/core/node-logs/scripts/get-node-logs.sh +19 -9
  250. package/skills/core/pod-pending-debug/SKILL.md +1 -0
  251. package/skills/core/quota-debug/SKILL.md +203 -0
  252. package/skills/core/service-debug/SKILL.md +1 -0
  253. package/skills/core/statefulset-debug/SKILL.md +280 -0
  254. package/skills/core/volcano-diagnose-pod/SKILL.md +196 -0
  255. package/skills/core/volcano-diagnose-pod/scripts/diagnose-pod.sh +175 -0
  256. package/skills/core/volcano-gang-scheduling/SKILL.md +299 -0
  257. package/skills/core/volcano-job-diagnose/SKILL.md +319 -0
  258. package/skills/core/volcano-job-diagnose/scripts/diagnose-job.sh +253 -0
  259. package/skills/core/volcano-node-resources/SKILL.md +334 -0
  260. package/skills/core/volcano-node-resources/scripts/get-node-resources.sh +281 -0
  261. package/skills/core/volcano-queue-diagnose/SKILL.md +294 -0
  262. package/skills/core/volcano-queue-diagnose/scripts/diagnose-queue.sh +283 -0
  263. package/skills/core/volcano-resource-insufficient/SKILL.md +315 -0
  264. package/skills/core/volcano-scheduler-config/SKILL.md +371 -0
  265. package/skills/core/volcano-scheduler-config/scripts/get-scheduler-config.sh +297 -0
  266. package/skills/core/volcano-scheduler-logs/SKILL.md +241 -0
  267. package/skills/core/volcano-scheduler-logs/scripts/get-scheduler-logs.sh +159 -0
  268. package/skills/platform/create-skill/SKILL.md +35 -3
  269. package/skills/platform/manage-skill/SKILL.md +9 -2
  270. package/skills/platform/update-skill/SKILL.md +17 -6
@@ -0,0 +1,49 @@
1
+ /**
2
+ * CronService — In-process cron scheduler for Gateway
3
+ *
4
+ * Replaces the standalone cron process. Runs timers directly in the
5
+ * Gateway process and calls configRepo for DB access (no HTTP proxy).
6
+ * Job execution delegates to /api/internal/agent-prompt on localhost.
7
+ */
8
+ import { CronScheduler, type CronJobRow } from "../../cron/cron-scheduler.js";
9
+ import type { ConfigRepository } from "../db/repositories/config-repo.js";
10
+ import type { NotificationRepository } from "../db/repositories/notification-repo.js";
11
+ export type SendToUserFn = (userId: string, event: string, payload: Record<string, unknown>) => void;
12
+ export declare class CronService {
13
+ readonly scheduler: CronScheduler;
14
+ /** Channel notification callback — set by gateway-main after construction */
15
+ onNotify?: (data: {
16
+ userId: string;
17
+ jobName: string;
18
+ result: string;
19
+ resultText: string;
20
+ error?: string;
21
+ }) => void;
22
+ private configRepo;
23
+ private notifRepo;
24
+ private sendToUser;
25
+ private gatewayPort;
26
+ private staleLockTimer;
27
+ private purgeTimer;
28
+ private sessionPurgeTimer;
29
+ constructor(opts: {
30
+ configRepo: ConfigRepository;
31
+ notifRepo: NotificationRepository;
32
+ sendToUser: SendToUserFn;
33
+ gatewayPort: number;
34
+ });
35
+ /** Load all active jobs and start background timers */
36
+ start(): Promise<void>;
37
+ /** Execute a single cron job */
38
+ private execute;
39
+ /** Record run history + push notification */
40
+ private recordResult;
41
+ /** Add or update a job in the scheduler */
42
+ addOrUpdate(job: CronJobRow): void;
43
+ /** Cancel a job from the scheduler */
44
+ cancel(jobId: string): void;
45
+ /** Stop all timers and clean up */
46
+ stop(): void;
47
+ private purgeNotifications;
48
+ private purgeSessions;
49
+ }
@@ -0,0 +1,259 @@
1
+ /**
2
+ * CronService — In-process cron scheduler for Gateway
3
+ *
4
+ * Replaces the standalone cron process. Runs timers directly in the
5
+ * Gateway process and calls configRepo for DB access (no HTTP proxy).
6
+ * Job execution delegates to /api/internal/agent-prompt on localhost.
7
+ */
8
+ import crypto from "node:crypto";
9
+ import { CronScheduler } from "../../cron/cron-scheduler.js";
10
+ const EXECUTION_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
11
+ const STALE_LOCK_CLEANUP_MS = 6 * 60 * 1000; // 6 min
12
+ const PURGE_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
13
+ const NOTIFICATION_RETENTION_DAYS = 30;
14
+ const SESSION_SOFT_DELETE_DAYS = 180;
15
+ const SESSION_HARD_DELETE_DAYS = 30;
16
+ const STATS_RETENTION_DAYS = 90;
17
+ export class CronService {
18
+ scheduler;
19
+ /** Channel notification callback — set by gateway-main after construction */
20
+ onNotify;
21
+ configRepo;
22
+ notifRepo;
23
+ sendToUser;
24
+ gatewayPort;
25
+ staleLockTimer = null;
26
+ purgeTimer = null;
27
+ sessionPurgeTimer = null;
28
+ constructor(opts) {
29
+ this.configRepo = opts.configRepo;
30
+ this.notifRepo = opts.notifRepo;
31
+ this.sendToUser = opts.sendToUser;
32
+ this.gatewayPort = opts.gatewayPort;
33
+ this.scheduler = new CronScheduler((job) => this.execute(job));
34
+ }
35
+ /** Load all active jobs and start background timers */
36
+ async start() {
37
+ // Load all active jobs
38
+ const jobs = await this.configRepo.listAllActiveCronJobs();
39
+ for (const job of jobs) {
40
+ this.scheduler.addOrUpdate(job);
41
+ }
42
+ console.log(`[cron-service] Loaded ${jobs.length} active jobs`);
43
+ // Stale lock cleanup every 6 minutes
44
+ this.staleLockTimer = setInterval(async () => {
45
+ try {
46
+ await this.configRepo.clearStaleLocks(STALE_LOCK_CLEANUP_MS);
47
+ }
48
+ catch (err) {
49
+ console.warn("[cron-service] clearStaleLocks failed:", err instanceof Error ? err.message : err);
50
+ }
51
+ }, STALE_LOCK_CLEANUP_MS);
52
+ this.staleLockTimer.unref();
53
+ // Daily notification purge
54
+ this.purgeNotifications();
55
+ this.purgeTimer = setInterval(() => this.purgeNotifications(), PURGE_INTERVAL_MS);
56
+ this.purgeTimer.unref();
57
+ // Daily session purge
58
+ this.purgeSessions();
59
+ this.sessionPurgeTimer = setInterval(() => this.purgeSessions(), PURGE_INTERVAL_MS);
60
+ this.sessionPurgeTimer.unref();
61
+ console.log("[cron-service] Started");
62
+ }
63
+ /** Execute a single cron job */
64
+ async execute(job) {
65
+ // Re-validate from DB
66
+ const current = await this.configRepo.getCronJobById(job.id);
67
+ if (!current || current.status !== "active") {
68
+ console.log(`[cron-service] Job ${job.id} no longer active, skipping`);
69
+ return;
70
+ }
71
+ // Acquire execution lock
72
+ const executionId = crypto.randomUUID();
73
+ const locked = await this.configRepo.lockJobForExecution(job.id, executionId);
74
+ if (!locked) {
75
+ console.log(`[cron-service] Job ${job.id} already locked, skipping`);
76
+ return;
77
+ }
78
+ const workspaceId = current.workspaceId ?? undefined;
79
+ console.log(`[cron-service] Executing job ${job.id} (${job.name}) for user ${job.userId}${workspaceId ? ` ws=${workspaceId}` : ""}`);
80
+ try {
81
+ const sessionId = `cron-${job.id}-${Date.now()}`;
82
+ const prompt = buildCronPrompt(current);
83
+ const resp = await fetch(`http://localhost:${this.gatewayPort}/api/internal/agent-prompt`, {
84
+ method: "POST",
85
+ headers: { "Content-Type": "application/json" },
86
+ body: JSON.stringify({
87
+ userId: current.userId,
88
+ sessionId,
89
+ text: prompt,
90
+ timeoutMs: EXECUTION_TIMEOUT_MS,
91
+ caller: "cron",
92
+ workspaceId,
93
+ }),
94
+ signal: AbortSignal.timeout(EXECUTION_TIMEOUT_MS + 10_000),
95
+ });
96
+ const data = await resp.json();
97
+ if (!resp.ok || data.status !== "success") {
98
+ throw new Error(data.error || `agent-prompt returned status=${data.status} http=${resp.status}`);
99
+ }
100
+ const resultText = data.resultText || "";
101
+ // Record success
102
+ try {
103
+ await this.configRepo.updateCronJobRun(job.id, "success");
104
+ }
105
+ catch (e) {
106
+ console.warn(`[cron-service] updateCronJobRun failed for ${job.id}:`, e instanceof Error ? e.message : e);
107
+ }
108
+ console.log(`[cron-service] Job ${job.id} completed in ${data.durationMs}ms, resultText length=${resultText.length}`);
109
+ // Write run record + notification
110
+ await this.recordResult(job, "success", resultText, undefined, data.durationMs);
111
+ }
112
+ catch (err) {
113
+ console.error(`[cron-service] Job ${job.id} failed:`, err);
114
+ try {
115
+ await this.configRepo.updateCronJobRun(job.id, "failure");
116
+ }
117
+ catch (e) {
118
+ console.warn(`[cron-service] updateCronJobRun failed for ${job.id}:`, e instanceof Error ? e.message : e);
119
+ }
120
+ await this.recordResult(job, "failure", "", err instanceof Error ? err.message : String(err));
121
+ }
122
+ finally {
123
+ try {
124
+ await this.configRepo.unlockJob(job.id, executionId);
125
+ }
126
+ catch (err) {
127
+ console.warn(`[cron-service] Failed to unlock job ${job.id}:`, err instanceof Error ? err.message : err);
128
+ }
129
+ }
130
+ }
131
+ /** Record run history + push notification */
132
+ async recordResult(job, result, resultText, error, durationMs) {
133
+ // Persist run record
134
+ try {
135
+ await this.configRepo.insertCronJobRun({
136
+ jobId: job.id,
137
+ status: result,
138
+ resultText: resultText || undefined,
139
+ error,
140
+ durationMs,
141
+ });
142
+ }
143
+ catch (runErr) {
144
+ console.warn("[cron-service] Failed to insert cron run:", runErr instanceof Error ? runErr.message : runErr);
145
+ }
146
+ // Create notification
147
+ const notifType = result === "success" ? "cron_success" : "cron_failure";
148
+ const notifMessage = result === "success" ? resultText : (error || "Unknown error");
149
+ const notifId = await this.notifRepo.create({
150
+ userId: job.userId,
151
+ type: notifType,
152
+ title: job.name,
153
+ message: notifMessage,
154
+ relatedId: job.id,
155
+ });
156
+ // Push via WebSocket
157
+ this.sendToUser(job.userId, "notification", {
158
+ id: notifId,
159
+ type: notifType,
160
+ title: job.name,
161
+ message: notifMessage,
162
+ relatedId: job.id,
163
+ isRead: false,
164
+ createdAt: new Date().toISOString(),
165
+ });
166
+ // Channel notification callback
167
+ if (this.onNotify) {
168
+ this.onNotify({
169
+ userId: job.userId,
170
+ jobName: job.name,
171
+ result,
172
+ resultText,
173
+ error,
174
+ });
175
+ }
176
+ }
177
+ /** Add or update a job in the scheduler */
178
+ addOrUpdate(job) {
179
+ this.scheduler.addOrUpdate(job);
180
+ }
181
+ /** Cancel a job from the scheduler */
182
+ cancel(jobId) {
183
+ this.scheduler.cancel(jobId);
184
+ }
185
+ /** Stop all timers and clean up */
186
+ stop() {
187
+ this.scheduler.stop();
188
+ if (this.staleLockTimer) {
189
+ clearInterval(this.staleLockTimer);
190
+ this.staleLockTimer = null;
191
+ }
192
+ if (this.purgeTimer) {
193
+ clearInterval(this.purgeTimer);
194
+ this.purgeTimer = null;
195
+ }
196
+ if (this.sessionPurgeTimer) {
197
+ clearInterval(this.sessionPurgeTimer);
198
+ this.sessionPurgeTimer = null;
199
+ }
200
+ console.log("[cron-service] Stopped");
201
+ }
202
+ async purgeNotifications() {
203
+ try {
204
+ const resp = await fetch(`http://localhost:${this.gatewayPort}/api/internal/notifications/purge`, {
205
+ method: "POST",
206
+ headers: { "Content-Type": "application/json" },
207
+ body: JSON.stringify({ retentionDays: NOTIFICATION_RETENTION_DAYS }),
208
+ signal: AbortSignal.timeout(10_000),
209
+ });
210
+ const data = await resp.json();
211
+ console.log(`[cron-service] Notification purge: deleted=${data.deleted ?? 0}`);
212
+ }
213
+ catch (err) {
214
+ console.warn("[cron-service] Notification purge failed:", err instanceof Error ? err.message : err);
215
+ }
216
+ }
217
+ async purgeSessions() {
218
+ try {
219
+ const resp = await fetch(`http://localhost:${this.gatewayPort}/api/internal/sessions/purge`, {
220
+ method: "POST",
221
+ headers: { "Content-Type": "application/json" },
222
+ body: JSON.stringify({
223
+ statsRetentionDays: STATS_RETENTION_DAYS,
224
+ softDeleteInactiveDays: SESSION_SOFT_DELETE_DAYS,
225
+ hardDeleteAfterDays: SESSION_HARD_DELETE_DAYS,
226
+ }),
227
+ signal: AbortSignal.timeout(30_000),
228
+ });
229
+ const data = (await resp.json());
230
+ console.log(`[cron-service] Session purge: softDeleted=${data.softDeleted}, ` +
231
+ `statsPurged=${data.statsPurged}, sessionsPurged=${data.sessionsPurged}`);
232
+ }
233
+ catch (err) {
234
+ console.warn("[cron-service] Session purge failed:", err instanceof Error ? err.message : err);
235
+ }
236
+ }
237
+ }
238
+ function buildCronPrompt(job) {
239
+ const parts = [
240
+ `[System: You are executing an automated scheduled task in NON-INTERACTIVE mode.
241
+
242
+ Rules:
243
+ - Perform the task described below directly and report the result.
244
+ - Do NOT ask the user any questions or request confirmations — there is no user to respond.
245
+ - If multiple environments, hosts, or credentials are available, operate on ALL of them unless the task description specifies a particular target.
246
+ - Do NOT create, modify, delete, pause, or manage any schedules.
247
+ - Keep the output concise and structured.
248
+ - Respond in the same language as the task name and description below.]`,
249
+ `Task: ${job.name}`,
250
+ ];
251
+ if (job.description) {
252
+ parts.push(`Instructions: ${job.description}`);
253
+ }
254
+ if (job.skillId) {
255
+ parts.push(`Execute skill: ${job.skillId}`);
256
+ }
257
+ return parts.join("\n\n");
258
+ }
259
+ //# sourceMappingURL=cron-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-service.js","sourceRoot":"","sources":["../../../src/gateway/cron/cron-service.ts"],"names":[],"mappings":"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"}
@@ -48,6 +48,9 @@ const DDL_STATEMENTS = [
48
48
  tool_input TEXT,
49
49
  metadata JSON DEFAULT NULL,
50
50
  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
51
+ user_id VARCHAR(64),
52
+ outcome VARCHAR(16),
53
+ duration_ms INT,
51
54
  FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
52
55
  )`,
53
56
  `CREATE TABLE IF NOT EXISTS skills (
@@ -95,7 +98,18 @@ const DDL_STATEMENTS = [
95
98
  locked_by VARCHAR(64),
96
99
  locked_at TIMESTAMP NULL,
97
100
  env_id VARCHAR(64),
101
+ workspace_id VARCHAR(64),
98
102
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
103
+ )`,
104
+ `CREATE TABLE IF NOT EXISTS cron_job_runs (
105
+ id VARCHAR(64) PRIMARY KEY,
106
+ job_id VARCHAR(64) NOT NULL,
107
+ status VARCHAR(20) NOT NULL,
108
+ result_text TEXT,
109
+ error TEXT,
110
+ duration_ms INT,
111
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
112
+ FOREIGN KEY (job_id) REFERENCES cron_jobs(id) ON DELETE CASCADE
99
113
  )`,
100
114
  `CREATE TABLE IF NOT EXISTS cron_instances (
101
115
  instance_id VARCHAR(64) PRIMARY KEY,
@@ -128,6 +142,7 @@ const DDL_STATEMENTS = [
128
142
  id VARCHAR(64) PRIMARY KEY,
129
143
  name VARCHAR(255) NOT NULL,
130
144
  is_test BOOLEAN NOT NULL DEFAULT FALSE,
145
+ api_server VARCHAR(512) NOT NULL DEFAULT '',
131
146
  created_by VARCHAR(32),
132
147
  allowed_servers TEXT,
133
148
  default_kubeconfig LONGTEXT,
@@ -244,6 +259,7 @@ const DDL_STATEMENTS = [
244
259
  user_id VARCHAR(32) NOT NULL,
245
260
  name VARCHAR(100) NOT NULL,
246
261
  is_default BOOLEAN NOT NULL DEFAULT FALSE,
262
+ env_type VARCHAR(10) NOT NULL DEFAULT 'prod',
247
263
  config_json JSON,
248
264
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
249
265
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
@@ -316,6 +332,22 @@ const DDL_STATEMENTS = [
316
332
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
317
333
  FOREIGN KEY (created_by) REFERENCES users(id)
318
334
  )`,
335
+ `CREATE TABLE IF NOT EXISTS session_stats (
336
+ id VARCHAR(64) PRIMARY KEY,
337
+ session_id VARCHAR(64) NOT NULL,
338
+ user_id VARCHAR(32) NOT NULL,
339
+ provider VARCHAR(64),
340
+ model VARCHAR(128),
341
+ input_tokens INT DEFAULT 0,
342
+ output_tokens INT DEFAULT 0,
343
+ cache_read_tokens INT DEFAULT 0,
344
+ cache_write_tokens INT DEFAULT 0,
345
+ duration_ms INT DEFAULT 0,
346
+ prompt_count INT DEFAULT 0,
347
+ tool_call_count INT DEFAULT 0,
348
+ skill_call_count INT DEFAULT 0,
349
+ created_at BIGINT NOT NULL
350
+ )`,
319
351
  ];
320
352
  // Indexes — handled separately since MySQL lacks CREATE INDEX IF NOT EXISTS
321
353
  const INDEX_STATEMENTS = [
@@ -333,6 +365,13 @@ const INDEX_STATEMENTS = [
333
365
  `ALTER TABLE skill_versions ADD INDEX idx_skill_versions_skill (skill_id, version)`,
334
366
  `ALTER TABLE skill_contents ADD INDEX idx_skill_contents_skill (skill_id)`,
335
367
  `ALTER TABLE credentials ADD INDEX idx_credentials_user (user_id, type)`,
368
+ `ALTER TABLE session_stats ADD INDEX idx_session_stats_created (created_at)`,
369
+ `ALTER TABLE session_stats ADD INDEX idx_session_stats_user (user_id, created_at)`,
370
+ `ALTER TABLE messages ADD INDEX idx_messages_audit (role, user_id, timestamp, id)`,
371
+ `ALTER TABLE messages ADD INDEX idx_messages_tool_name (tool_name)`,
372
+ `ALTER TABLE cron_job_runs ADD INDEX idx_cron_job_runs_job (job_id, created_at)`,
373
+ `ALTER TABLE cron_jobs ADD INDEX idx_cron_jobs_status_assigned (status, assigned_to)`,
374
+ `ALTER TABLE cron_instances ADD INDEX idx_cron_instances_heartbeat (heartbeat_at)`,
336
375
  ];
337
376
  export async function initSchema(db) {
338
377
  if (isSqlite())
@@ -351,6 +390,11 @@ export async function initSchema(db) {
351
390
  `ALTER TABLE skills MODIFY COLUMN scope ENUM('builtin','team','personal') NOT NULL DEFAULT 'personal'`,
352
391
  `ALTER TABLE skills MODIFY COLUMN review_status ENUM('draft','pending','approved') NOT NULL DEFAULT 'draft'`,
353
392
  `ALTER TABLE skills ADD COLUMN labels_json JSON NULL`,
393
+ // ADR-011: environment isolation
394
+ `ALTER TABLE workspaces ADD COLUMN env_type VARCHAR(10) NOT NULL DEFAULT 'prod' AFTER is_default`,
395
+ `ALTER TABLE environments ADD COLUMN api_server VARCHAR(512) NOT NULL DEFAULT '' AFTER is_test`,
396
+ `ALTER TABLE cron_jobs ADD COLUMN workspace_id VARCHAR(64)`,
397
+ `ALTER TABLE cron_jobs ADD CONSTRAINT fk_cron_jobs_workspace FOREIGN KEY (workspace_id) REFERENCES workspaces(id)`,
354
398
  ];
355
399
  for (const stmt of MIGRATIONS) {
356
400
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"init-schema.js","sourceRoot":"","sources":["../../../src/gateway/db/init-schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init-schema.js","sourceRoot":"","sources":["../../../src/gateway/db/init-schema.ts"],"names":[],"mappings":"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"}
@@ -44,7 +44,10 @@ const DDL_STATEMENTS = [
44
44
  tool_name TEXT,
45
45
  tool_input TEXT,
46
46
  metadata TEXT,
47
- timestamp INTEGER NOT NULL DEFAULT (unixepoch())
47
+ timestamp INTEGER NOT NULL DEFAULT (unixepoch()),
48
+ user_id TEXT,
49
+ outcome TEXT,
50
+ duration_ms INTEGER
48
51
  )`,
49
52
  `CREATE TABLE IF NOT EXISTS skills (
50
53
  id TEXT PRIMARY KEY,
@@ -88,7 +91,17 @@ const DDL_STATEMENTS = [
88
91
  assigned_to TEXT,
89
92
  locked_by TEXT,
90
93
  locked_at INTEGER,
91
- env_id TEXT
94
+ env_id TEXT,
95
+ workspace_id TEXT
96
+ )`,
97
+ `CREATE TABLE IF NOT EXISTS cron_job_runs (
98
+ id TEXT PRIMARY KEY,
99
+ job_id TEXT NOT NULL REFERENCES cron_jobs(id) ON DELETE CASCADE,
100
+ status TEXT NOT NULL,
101
+ result_text TEXT,
102
+ error TEXT,
103
+ duration_ms INTEGER,
104
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
92
105
  )`,
93
106
  `CREATE TABLE IF NOT EXISTS cron_instances (
94
107
  instance_id TEXT PRIMARY KEY,
@@ -118,6 +131,7 @@ const DDL_STATEMENTS = [
118
131
  id TEXT PRIMARY KEY,
119
132
  name TEXT NOT NULL,
120
133
  is_test INTEGER NOT NULL DEFAULT 0,
134
+ api_server TEXT NOT NULL DEFAULT '',
121
135
  created_by TEXT,
122
136
  allowed_servers TEXT,
123
137
  default_kubeconfig TEXT,
@@ -225,6 +239,7 @@ const DDL_STATEMENTS = [
225
239
  user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
226
240
  name TEXT NOT NULL,
227
241
  is_default INTEGER NOT NULL DEFAULT 0,
242
+ env_type TEXT NOT NULL DEFAULT 'prod',
228
243
  config_json TEXT,
229
244
  created_at INTEGER NOT NULL DEFAULT (unixepoch()),
230
245
  updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
@@ -271,6 +286,22 @@ const DDL_STATEMENTS = [
271
286
  sort_order INTEGER NOT NULL DEFAULT 0,
272
287
  created_at INTEGER NOT NULL DEFAULT (unixepoch()),
273
288
  UNIQUE (provider_id, model_id)
289
+ )`,
290
+ `CREATE TABLE IF NOT EXISTS session_stats (
291
+ id TEXT PRIMARY KEY,
292
+ session_id TEXT NOT NULL,
293
+ user_id TEXT NOT NULL,
294
+ provider TEXT,
295
+ model TEXT,
296
+ input_tokens INTEGER DEFAULT 0,
297
+ output_tokens INTEGER DEFAULT 0,
298
+ cache_read_tokens INTEGER DEFAULT 0,
299
+ cache_write_tokens INTEGER DEFAULT 0,
300
+ duration_ms INTEGER DEFAULT 0,
301
+ prompt_count INTEGER DEFAULT 0,
302
+ tool_call_count INTEGER DEFAULT 0,
303
+ skill_call_count INTEGER DEFAULT 0,
304
+ created_at INTEGER NOT NULL
274
305
  )`,
275
306
  `CREATE TABLE IF NOT EXISTS mcp_servers (
276
307
  id TEXT PRIMARY KEY,
@@ -304,6 +335,13 @@ const INDEX_STATEMENTS = [
304
335
  `CREATE INDEX IF NOT EXISTS idx_skill_versions_skill ON skill_versions(skill_id, version)`,
305
336
  `CREATE INDEX IF NOT EXISTS idx_skill_contents_skill ON skill_contents(skill_id)`,
306
337
  `CREATE INDEX IF NOT EXISTS idx_credentials_user ON credentials(user_id, type)`,
338
+ `CREATE INDEX IF NOT EXISTS idx_session_stats_created ON session_stats(created_at)`,
339
+ `CREATE INDEX IF NOT EXISTS idx_session_stats_user ON session_stats(user_id, created_at)`,
340
+ `CREATE INDEX IF NOT EXISTS idx_messages_audit ON messages(role, user_id, timestamp, id)`,
341
+ `CREATE INDEX IF NOT EXISTS idx_messages_tool_name ON messages(tool_name)`,
342
+ `CREATE INDEX IF NOT EXISTS idx_cron_job_runs_job ON cron_job_runs(job_id, created_at)`,
343
+ `CREATE INDEX IF NOT EXISTS idx_cron_jobs_status_assigned ON cron_jobs(status, assigned_to)`,
344
+ `CREATE INDEX IF NOT EXISTS idx_cron_instances_heartbeat ON cron_instances(heartbeat_at)`,
307
345
  ];
308
346
  export async function runSqliteMigrations(db) {
309
347
  console.log("[db] Running SQLite migrations...");
@@ -313,6 +351,34 @@ export async function runSqliteMigrations(db) {
313
351
  for (const ddl of DDL_STATEMENTS) {
314
352
  sdb.run(sql.raw(ddl));
315
353
  }
354
+ // Schema migrations — handle existing databases missing new columns.
355
+ // Must run BEFORE index creation, since some indexes reference new columns.
356
+ const MIGRATIONS = [
357
+ // ADR-011: environment isolation
358
+ `ALTER TABLE workspaces ADD COLUMN env_type TEXT NOT NULL DEFAULT 'prod'`,
359
+ `ALTER TABLE environments ADD COLUMN api_server TEXT NOT NULL DEFAULT ''`,
360
+ `ALTER TABLE cron_jobs ADD COLUMN workspace_id TEXT`,
361
+ ];
362
+ // Backfill: copy allowedServers[0] → apiServer for rows that haven't been set
363
+ const BACKFILLS = [
364
+ `UPDATE environments SET api_server = TRIM(SUBSTR(allowed_servers, 1, CASE WHEN INSTR(allowed_servers, ',') > 0 THEN INSTR(allowed_servers, ',') - 1 ELSE LENGTH(allowed_servers) END)) WHERE api_server = '' AND allowed_servers != ''`,
365
+ ];
366
+ for (const stmt of MIGRATIONS) {
367
+ try {
368
+ sdb.run(sql.raw(stmt));
369
+ }
370
+ catch (_err) {
371
+ // Ignore "duplicate column name" errors (column already exists)
372
+ }
373
+ }
374
+ for (const stmt of BACKFILLS) {
375
+ try {
376
+ sdb.run(sql.raw(stmt));
377
+ }
378
+ catch (_err) {
379
+ // Backfill may fail on empty tables — safe to ignore
380
+ }
381
+ }
316
382
  for (const ddl of INDEX_STATEMENTS) {
317
383
  sdb.run(sql.raw(ddl));
318
384
  }
@@ -325,9 +391,12 @@ export async function runSqliteMigrations(db) {
325
391
  UPDATE mcp_servers SET updated_at = unixepoch() WHERE id = NEW.id;
326
392
  END
327
393
  `));
328
- // Seed default embedding config if not present
394
+ // Seed default embedding config if not present (empty = unconfigured)
329
395
  sdb.run(sql.raw(`INSERT OR IGNORE INTO embedding_config (id, provider_name, model, dimensions, updated_at)
330
- VALUES ('default', 'default', 'BAAI/bge-m3', 1024, ${Math.floor(Date.now() / 1000)})`));
396
+ VALUES ('default', '', '', 1024, ${Math.floor(Date.now() / 1000)})`));
397
+ // Clean up old seed that hardcoded BAAI/bge-m3 as default
398
+ sdb.run(sql.raw(`UPDATE embedding_config SET provider_name = '', model = ''
399
+ WHERE id = 'default' AND provider_name = 'default' AND model = 'BAAI/bge-m3'`));
331
400
  // Persist schema changes to disk immediately (sql.js is in-memory)
332
401
  flushSqliteDb();
333
402
  console.log("[db] SQLite migrations complete");
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-sqlite.js","sourceRoot":"","sources":["../../../src/gateway/db/migrate-sqlite.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,MAAM,cAAc,GAAG;IACrB;;;;;;;;IAQE;IAEF;;;;;;;IAOE;IAEF;;;;;;;;;;;IAWE;IAEF;;;;;;;;;IASE;IAEF;;;;;;;;;;;;;;;;;;;;;IAqBE;IAEF;;;;;;IAME;IAEF;;;;;;;;;;;;;;IAcE;IAEF;;;;;;IAME;IAEF;;;;;;;;;IASE;IAEF;;;;;;IAME;IAEF;;;;;;;;;IASE;IAEF;;;;;;;;IAQE;IAEF;;;;IAIE;IAEF;;;;;;;;;;IAUE;IAEF;;;;;;;IAOE;IAEF;;;;;;;;;IASE;IAEF;;;;;;;;;;;;IAYE;IAEF;;;;;;;;;IASE;IAEF;;;;;;;;;;;IAWE;IAEF;;;;;;;;;;IAUE;IAEF;;;;;;IAME;IAEF;;;;;;;;;IASE;IAEF;;;;IAIE;IAEF;;;;IAIE;IAEF;;;;IAIE;IAEF;;;;IAIE;IAEF;;;;IAIE;IAEF;;;;;;;;;;;;;;;;IAgBE;IAEF;;;;;;;;;;;;;;;IAeE;CACH,CAAC;AAEF,MAAM,gBAAgB,GAAG;IACvB,mFAAmF;IACnF,oFAAoF;IACpF,8DAA8D;IAC9D,mEAAmE;IACnE,4FAA4F;IAC5F,2EAA2E;IAC3E,kGAAkG;IAClG,2FAA2F;IAC3F,sFAAsF;IACtF,mFAAmF;IACnF,iFAAiF;IACjF,0FAA0F;IAC1F,iFAAiF;IACjF,+EAA+E;CAChF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAY;IACpD,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IAEjD,gEAAgE;IAChE,8EAA8E;IAC9E,MAAM,GAAG,GAAG,EAAS,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,oGAAoG;IACpG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;;;;;;;GAOf,CAAC,CAAC,CAAC;IAEJ,+CAA+C;IAC/C,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CACb;0DACsD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CACvF,CAAC,CAAC;IAEH,mEAAmE;IACnE,aAAa,EAAE,CAAC;IAEhB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"migrate-sqlite.js","sourceRoot":"","sources":["../../../src/gateway/db/migrate-sqlite.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,6 @@ export declare class ChatRepository {
15
15
  lastActiveAt: Date;
16
16
  messageCount: number;
17
17
  deletedAt: Date | null;
18
- s3Key: string | null;
19
18
  }[]>;
20
19
  getSession(sessionId: string): Promise<{
21
20
  id: string;
@@ -27,7 +26,6 @@ export declare class ChatRepository {
27
26
  lastActiveAt: Date;
28
27
  messageCount: number;
29
28
  deletedAt: Date | null;
30
- s3Key: string | null;
31
29
  }>;
32
30
  createSession(userId: string, title?: string, workspaceId?: string): Promise<{
33
31
  id: `${string}-${string}-${string}-${string}-${string}`;
@@ -51,6 +49,9 @@ export declare class ChatRepository {
51
49
  toolInput: string | null;
52
50
  metadata: Record<string, unknown> | null;
53
51
  timestamp: Date;
52
+ userId: string | null;
53
+ outcome: string | null;
54
+ durationMs: number | null;
54
55
  }[]>;
55
56
  appendMessage(msg: {
56
57
  sessionId: string;
@@ -59,6 +60,59 @@ export declare class ChatRepository {
59
60
  toolName?: string;
60
61
  toolInput?: string;
61
62
  metadata?: Record<string, unknown>;
63
+ userId?: string;
64
+ outcome?: "success" | "error" | "blocked";
65
+ durationMs?: number;
62
66
  }): Promise<`${string}-${string}-${string}-${string}-${string}`>;
67
+ getMessageById(messageId: string): Promise<{
68
+ id: string;
69
+ sessionId: string;
70
+ role: "user" | "assistant" | "tool";
71
+ content: string;
72
+ toolName: string | null;
73
+ toolInput: string | null;
74
+ metadata: Record<string, unknown> | null;
75
+ timestamp: Date;
76
+ userId: string | null;
77
+ outcome: string | null;
78
+ durationMs: number | null;
79
+ }>;
80
+ queryAuditLogs(opts: {
81
+ userId?: string;
82
+ userName?: string;
83
+ toolName?: string;
84
+ outcome?: string;
85
+ startDate?: number;
86
+ endDate?: number;
87
+ cursorTs?: number;
88
+ cursorId?: string;
89
+ limit: number;
90
+ }): Promise<{
91
+ id: string;
92
+ userId: string | null;
93
+ userName: string | null;
94
+ toolName: string | null;
95
+ toolInput: string | null;
96
+ outcome: string | null;
97
+ durationMs: number | null;
98
+ timestamp: Date;
99
+ }[]>;
100
+ private static readonly BATCH_SIZE;
101
+ /**
102
+ * Soft-delete inactive sessions (no activity for `inactiveDays`).
103
+ * Only targets sessions that haven't been deleted yet.
104
+ */
105
+ softDeleteInactiveSessions(inactiveDays: number): Promise<number>;
106
+ /**
107
+ * Hard-delete sessions that were soft-deleted more than `deletedDays` ago.
108
+ * Messages are cleaned up automatically via FK CASCADE.
109
+ */
110
+ purgeDeletedSessions(deletedDays: number): Promise<number>;
111
+ /**
112
+ * Hard-delete session_stats older than `retentionDays`.
113
+ * Note: sessionStats.createdAt is a raw epoch number in milliseconds
114
+ * (no mode:"timestamp"), so we compare with numeric ms, not Date.
115
+ */
116
+ purgeOldSessionStats(retentionDays: number): Promise<number>;
63
117
  updateMetadata(userId: string, messageId: string, metadata: Record<string, unknown>): Promise<void>;
64
118
  }