@progmruansilva/omp-web 1.202608.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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +181 -0
  3. package/dist/cli.js +1015 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/client/assets/CodeViewer-Da66baHj.js +4 -0
  6. package/dist/client/assets/TerminalPanel-Bj9an79F.js +126 -0
  7. package/dist/client/assets/UnifiedDiffViewer-eK_kynTO.js +34 -0
  8. package/dist/client/assets/index-DytaeWNd.js +3070 -0
  9. package/dist/client/assets/vendor-editor-core-CL2gOCIg.js +12 -0
  10. package/dist/client/assets/vendor-editor-languages-zOM9I4iZ.js +26 -0
  11. package/dist/client/assets/vendor-editor-legacy-B4QLsWF8.js +1 -0
  12. package/dist/client/assets/vendor-terminal-DDGTF8rc.css +1 -0
  13. package/dist/client/assets/vendor-terminal-DjQ08hXu.js +16 -0
  14. package/dist/client/favicon-16x16.png +0 -0
  15. package/dist/client/favicon-180x180.png +0 -0
  16. package/dist/client/favicon-192x192.png +0 -0
  17. package/dist/client/favicon-32x32.png +0 -0
  18. package/dist/client/favicon-512x512.png +0 -0
  19. package/dist/client/favicon.ico +0 -0
  20. package/dist/client/favicon.png +0 -0
  21. package/dist/client/favicon.svg +11 -0
  22. package/dist/client/index.html +67 -0
  23. package/dist/client/manifest.webmanifest +36 -0
  24. package/dist/config.js +272 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/docker/ompWebDockerCommandPlan.js +211 -0
  27. package/dist/docker/ompWebDockerCommandPlan.js.map +1 -0
  28. package/dist/omp-web-plugins/info/omp-web-plugin.js +51 -0
  29. package/dist/omp-web-plugins/info/package.json +9 -0
  30. package/dist/omp-web-plugins/schedule-prompts/omp-web-plugin.js +43 -0
  31. package/dist/omp-web-plugins/schedule-prompts/package.json +9 -0
  32. package/dist/omp-web-plugins/schedule-prompts/schedulePromptsPanelElement.js +242 -0
  33. package/dist/omp-web-plugins/schedule-prompts/types.js +2 -0
  34. package/dist/omp-web-plugins/updates/omp-web-plugin.js +173 -0
  35. package/dist/omp-web-plugins/updates/package.json +9 -0
  36. package/dist/omp-web-plugins/updates/updatesLogic.js +97 -0
  37. package/dist/ompWebVersionReport.js +217 -0
  38. package/dist/ompWebVersionReport.js.map +1 -0
  39. package/dist/plugin-api/unstable.d.ts +22 -0
  40. package/dist/plugin-api.d.ts +197 -0
  41. package/dist/server/activity/workspaceActivityRoutes.js +4 -0
  42. package/dist/server/activity/workspaceActivityRoutes.js.map +1 -0
  43. package/dist/server/activity/workspaceActivityService.js +98 -0
  44. package/dist/server/activity/workspaceActivityService.js.map +1 -0
  45. package/dist/server/app.js +162 -0
  46. package/dist/server/app.js.map +1 -0
  47. package/dist/server/configRoutes.js +270 -0
  48. package/dist/server/configRoutes.js.map +1 -0
  49. package/dist/server/diagnostics/nodePtySpawnHelper.js +130 -0
  50. package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -0
  51. package/dist/server/git/gitEnv.js +15 -0
  52. package/dist/server/git/gitEnv.js.map +1 -0
  53. package/dist/server/git/gitService.js +119 -0
  54. package/dist/server/git/gitService.js.map +1 -0
  55. package/dist/server/gitRoutes.js +23 -0
  56. package/dist/server/gitRoutes.js.map +1 -0
  57. package/dist/server/index.js +7 -0
  58. package/dist/server/index.js.map +1 -0
  59. package/dist/server/machines/machineClient.js +162 -0
  60. package/dist/server/machines/machineClient.js.map +1 -0
  61. package/dist/server/machines/machinePluginProxyRoutes.js +157 -0
  62. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -0
  63. package/dist/server/machines/machineProxyRoutes.js +127 -0
  64. package/dist/server/machines/machineProxyRoutes.js.map +1 -0
  65. package/dist/server/machines/machineRoutes.js +54 -0
  66. package/dist/server/machines/machineRoutes.js.map +1 -0
  67. package/dist/server/machines/machineService.js +230 -0
  68. package/dist/server/machines/machineService.js.map +1 -0
  69. package/dist/server/machines/machineStore.js +123 -0
  70. package/dist/server/machines/machineStore.js.map +1 -0
  71. package/dist/server/machines/proxyUtils.js +30 -0
  72. package/dist/server/machines/proxyUtils.js.map +1 -0
  73. package/dist/server/ompWebPluginService.js +279 -0
  74. package/dist/server/ompWebPluginService.js.map +1 -0
  75. package/dist/server/ompWebStatus.js +601 -0
  76. package/dist/server/ompWebStatus.js.map +1 -0
  77. package/dist/server/ompWebStatusCache.js +31 -0
  78. package/dist/server/ompWebStatusCache.js.map +1 -0
  79. package/dist/server/piPackageRoutes.js +82 -0
  80. package/dist/server/piPackageRoutes.js.map +1 -0
  81. package/dist/server/piPackageService.js +65 -0
  82. package/dist/server/piPackageService.js.map +1 -0
  83. package/dist/server/projects/directorySuggestions.js +37 -0
  84. package/dist/server/projects/directorySuggestions.js.map +1 -0
  85. package/dist/server/projects/projectService.js +31 -0
  86. package/dist/server/projects/projectService.js.map +1 -0
  87. package/dist/server/push/PushNotificationService.js +137 -0
  88. package/dist/server/push/PushNotificationService.js.map +1 -0
  89. package/dist/server/push/pushRoutes.js +55 -0
  90. package/dist/server/push/pushRoutes.js.map +1 -0
  91. package/dist/server/realtime/sessionEventHub.js +39 -0
  92. package/dist/server/realtime/sessionEventHub.js.map +1 -0
  93. package/dist/server/sessiond/sessionProxyRoutes.js +61 -0
  94. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -0
  95. package/dist/server/sessiond.js +92 -0
  96. package/dist/server/sessiond.js.map +1 -0
  97. package/dist/server/sessions/attachmentService.js +112 -0
  98. package/dist/server/sessions/attachmentService.js.map +1 -0
  99. package/dist/server/sessions/authProviderOptions.js +52 -0
  100. package/dist/server/sessions/authProviderOptions.js.map +1 -0
  101. package/dist/server/sessions/authRoutes.js +59 -0
  102. package/dist/server/sessions/authRoutes.js.map +1 -0
  103. package/dist/server/sessions/authService.js +105 -0
  104. package/dist/server/sessions/authService.js.map +1 -0
  105. package/dist/server/sessions/builtinCommands.js +29 -0
  106. package/dist/server/sessions/builtinCommands.js.map +1 -0
  107. package/dist/server/sessions/editPreview.js +196 -0
  108. package/dist/server/sessions/editPreview.js.map +1 -0
  109. package/dist/server/sessions/messagePaging.js +41 -0
  110. package/dist/server/sessions/messagePaging.js.map +1 -0
  111. package/dist/server/sessions/oauthLoginFlowService.js +136 -0
  112. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -0
  113. package/dist/server/sessions/piSessionManagerGateway.js +97 -0
  114. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -0
  115. package/dist/server/sessions/piSessionService.js +2401 -0
  116. package/dist/server/sessions/piSessionService.js.map +1 -0
  117. package/dist/server/sessions/schedulePrompt/schedulePromptService.js +46 -0
  118. package/dist/server/sessions/schedulePrompt/schedulePromptService.js.map +1 -0
  119. package/dist/server/sessions/schedulePrompt/scheduler.js +315 -0
  120. package/dist/server/sessions/schedulePrompt/scheduler.js.map +1 -0
  121. package/dist/server/sessions/schedulePrompt/storage.js +118 -0
  122. package/dist/server/sessions/schedulePrompt/storage.js.map +1 -0
  123. package/dist/server/sessions/schedulePrompt/tool.js +252 -0
  124. package/dist/server/sessions/schedulePrompt/tool.js.map +1 -0
  125. package/dist/server/sessions/schedulePrompt/types.js +2 -0
  126. package/dist/server/sessions/schedulePrompt/types.js.map +1 -0
  127. package/dist/server/sessions/sessionArchiveStore.js +254 -0
  128. package/dist/server/sessions/sessionArchiveStore.js.map +1 -0
  129. package/dist/server/sessions/sessionArchiveTree.js +35 -0
  130. package/dist/server/sessions/sessionArchiveTree.js.map +1 -0
  131. package/dist/server/sessions/sessionCleanup.js +157 -0
  132. package/dist/server/sessions/sessionCleanup.js.map +1 -0
  133. package/dist/server/sessions/sessionCommandService.js +260 -0
  134. package/dist/server/sessions/sessionCommandService.js.map +1 -0
  135. package/dist/server/sessions/sessionNameGenerator.js +61 -0
  136. package/dist/server/sessions/sessionNameGenerator.js.map +1 -0
  137. package/dist/server/sessions/sessionRoutes.js +344 -0
  138. package/dist/server/sessions/sessionRoutes.js.map +1 -0
  139. package/dist/server/sessions/sessionRuntimeStore.js +2 -0
  140. package/dist/server/sessions/sessionRuntimeStore.js.map +1 -0
  141. package/dist/server/sessions/spawnSessionTool.js +41 -0
  142. package/dist/server/sessions/spawnSessionTool.js.map +1 -0
  143. package/dist/server/sessions/spawnSubsessionTool.js +203 -0
  144. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -0
  145. package/dist/server/sessions/spawnTargetResolver.js +36 -0
  146. package/dist/server/sessions/spawnTargetResolver.js.map +1 -0
  147. package/dist/server/sessions/subsessionTranscript.js +233 -0
  148. package/dist/server/sessions/subsessionTranscript.js.map +1 -0
  149. package/dist/server/storage/projectStore.js +83 -0
  150. package/dist/server/storage/projectStore.js.map +1 -0
  151. package/dist/server/terminalProxyRoutes.js +140 -0
  152. package/dist/server/terminalProxyRoutes.js.map +1 -0
  153. package/dist/server/terminals/terminalRoutes.js +153 -0
  154. package/dist/server/terminals/terminalRoutes.js.map +1 -0
  155. package/dist/server/terminals/terminalService.js +320 -0
  156. package/dist/server/terminals/terminalService.js.map +1 -0
  157. package/dist/server/terminals/terminalSize.js +17 -0
  158. package/dist/server/terminals/terminalSize.js.map +1 -0
  159. package/dist/server/types.js +2 -0
  160. package/dist/server/types.js.map +1 -0
  161. package/dist/server/utils.js +8 -0
  162. package/dist/server/utils.js.map +1 -0
  163. package/dist/server/webSocketBridge.js +32 -0
  164. package/dist/server/webSocketBridge.js.map +1 -0
  165. package/dist/server/workingDirectory.js +44 -0
  166. package/dist/server/workingDirectory.js.map +1 -0
  167. package/dist/server/workspaceExplorerRoutes.js +109 -0
  168. package/dist/server/workspaceExplorerRoutes.js.map +1 -0
  169. package/dist/server/workspaces/effectivePathAccess.js +27 -0
  170. package/dist/server/workspaces/effectivePathAccess.js.map +1 -0
  171. package/dist/server/workspaces/fileContentService.js +181 -0
  172. package/dist/server/workspaces/fileContentService.js.map +1 -0
  173. package/dist/server/workspaces/fileSuggestions.js +512 -0
  174. package/dist/server/workspaces/fileSuggestions.js.map +1 -0
  175. package/dist/server/workspaces/fileTreeService.js +27 -0
  176. package/dist/server/workspaces/fileTreeService.js.map +1 -0
  177. package/dist/server/workspaces/gitWorktreeDiscovery.js +34 -0
  178. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +1 -0
  179. package/dist/server/workspaces/imagePreviewService.js +40 -0
  180. package/dist/server/workspaces/imagePreviewService.js.map +1 -0
  181. package/dist/server/workspaces/pathAccessPolicy.js +87 -0
  182. package/dist/server/workspaces/pathAccessPolicy.js.map +1 -0
  183. package/dist/server/workspaces/pathSafety.js +54 -0
  184. package/dist/server/workspaces/pathSafety.js.map +1 -0
  185. package/dist/server/workspaces/projectOmpWebConfig.js +56 -0
  186. package/dist/server/workspaces/projectOmpWebConfig.js.map +1 -0
  187. package/dist/server/workspaces/workspaceContext.js +8 -0
  188. package/dist/server/workspaces/workspaceContext.js.map +1 -0
  189. package/dist/server/workspaces/workspaceDeletionRoutes.js +111 -0
  190. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -0
  191. package/dist/server/workspaces/workspaceService.js +39 -0
  192. package/dist/server/workspaces/workspaceService.js.map +1 -0
  193. package/dist/sessiond/config.js +9 -0
  194. package/dist/sessiond/config.js.map +1 -0
  195. package/dist/sessiond/sessionDaemonClient.js +65 -0
  196. package/dist/sessiond/sessionDaemonClient.js.map +1 -0
  197. package/dist/shared/activity.js +26 -0
  198. package/dist/shared/activity.js.map +1 -0
  199. package/dist/shared/apiTypes.d.ts +688 -0
  200. package/dist/shared/apiTypes.js +11 -0
  201. package/dist/shared/apiTypes.js.map +1 -0
  202. package/dist/shared/capabilities.js +52 -0
  203. package/dist/shared/capabilities.js.map +1 -0
  204. package/dist/shared/federatedRoutes.js +79 -0
  205. package/dist/shared/federatedRoutes.js.map +1 -0
  206. package/dist/shared/machinePluginIds.js +41 -0
  207. package/dist/shared/machinePluginIds.js.map +1 -0
  208. package/dist/shared/ompWebStatusParsing.js +100 -0
  209. package/dist/shared/ompWebStatusParsing.js.map +1 -0
  210. package/dist/shared/pluginIds.js +5 -0
  211. package/dist/shared/pluginIds.js.map +1 -0
  212. package/dist/shared/promptAttachments.js +90 -0
  213. package/dist/shared/promptAttachments.js.map +1 -0
  214. package/dist/shared/thinkingLevels.d.ts +19 -0
  215. package/dist/shared/thinkingLevels.js +24 -0
  216. package/dist/shared/thinkingLevels.js.map +1 -0
  217. package/dist/shared/utils.js +4 -0
  218. package/dist/shared/utils.js.map +1 -0
  219. package/dist/shared/workspaceDeletion.js +12 -0
  220. package/dist/shared/workspaceDeletion.js.map +1 -0
  221. package/dist/shared/workspaceFiles.js +3 -0
  222. package/dist/shared/workspaceFiles.js.map +1 -0
  223. package/docs/assets/favicon.svg +11 -0
  224. package/docs/assets/omp-web-banner.png +0 -0
  225. package/docs/assets/omp-web-desktop.png +0 -0
  226. package/docs/assets/omp-web-mobile.png +0 -0
  227. package/docs/assets/omp-web-tablet.png +0 -0
  228. package/docs/config.md +208 -0
  229. package/docs/plugins.md +916 -0
  230. package/extensions/omp-web.ts +133 -0
  231. package/install.sh +5 -0
  232. package/package.json +141 -0
  233. package/plugin-api/unstable.d.ts +1 -0
  234. package/plugin-api.d.ts +1 -0
@@ -0,0 +1,118 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ /**
4
+ * Handles persistence of scheduled prompts to .omp-web/schedule-prompts.json
5
+ */
6
+ export class CronStorage {
7
+ constructor(workspaceCwd) {
8
+ this.storeDir = path.join(workspaceCwd, ".omp-web");
9
+ this.storePath = path.join(this.storeDir, "schedule-prompts.json");
10
+ }
11
+ /**
12
+ * Load scheduled prompts from disk
13
+ */
14
+ load() {
15
+ try {
16
+ if (fs.existsSync(this.storePath)) {
17
+ const data = fs.readFileSync(this.storePath, "utf-8");
18
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- JSON.parse returns unknown
19
+ const store = JSON.parse(data);
20
+ return store;
21
+ }
22
+ }
23
+ catch (error) {
24
+ console.error("Failed to load scheduled prompts:", error);
25
+ }
26
+ // Return empty store if file doesn't exist or is corrupted
27
+ return { jobs: [], version: 1 };
28
+ }
29
+ /**
30
+ * Save scheduled prompts to disk
31
+ */
32
+ save(store) {
33
+ try {
34
+ // Ensure store directory exists
35
+ if (!fs.existsSync(this.storeDir)) {
36
+ fs.mkdirSync(this.storeDir, { recursive: true });
37
+ }
38
+ // Write atomically using temp file
39
+ const tempPath = `${this.storePath}.tmp`;
40
+ fs.writeFileSync(tempPath, JSON.stringify(store, null, 2), "utf-8");
41
+ fs.renameSync(tempPath, this.storePath);
42
+ }
43
+ catch (error) {
44
+ console.error("Failed to save scheduled prompts:", error);
45
+ throw error;
46
+ }
47
+ }
48
+ /**
49
+ * Check if a job name already exists
50
+ */
51
+ hasJobWithName(name) {
52
+ const store = this.load();
53
+ return store.jobs.some((j) => j.name === name);
54
+ }
55
+ /**
56
+ * Add a new job
57
+ */
58
+ addJob(job) {
59
+ const store = this.load();
60
+ store.jobs.push(job);
61
+ this.save(store);
62
+ }
63
+ /**
64
+ * Remove a job by ID
65
+ */
66
+ removeJob(id) {
67
+ const store = this.load();
68
+ const initialLength = store.jobs.length;
69
+ store.jobs = store.jobs.filter((j) => j.id !== id);
70
+ if (store.jobs.length < initialLength) {
71
+ this.save(store);
72
+ return true;
73
+ }
74
+ return false;
75
+ }
76
+ /**
77
+ * Update a job by ID
78
+ */
79
+ updateJob(id, partial) {
80
+ const store = this.load();
81
+ const job = store.jobs.find((j) => j.id === id);
82
+ if (job) {
83
+ for (const [key, value] of Object.entries(partial)) {
84
+ if (value === undefined) {
85
+ Reflect.deleteProperty(job, key);
86
+ }
87
+ else {
88
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- dynamic key value assignment on CronJob
89
+ job[key] = value;
90
+ }
91
+ }
92
+ this.save(store);
93
+ return true;
94
+ }
95
+ return false;
96
+ }
97
+ /**
98
+ * Get a single job by ID
99
+ */
100
+ getJob(id) {
101
+ const store = this.load();
102
+ return store.jobs.find((j) => j.id === id);
103
+ }
104
+ /**
105
+ * Get all jobs
106
+ */
107
+ getAllJobs() {
108
+ const store = this.load();
109
+ return store.jobs;
110
+ }
111
+ /**
112
+ * Get storage file path
113
+ */
114
+ getStorePath() {
115
+ return this.storePath;
116
+ }
117
+ }
118
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../../src/server/sessions/schedulePrompt/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,252 @@
1
+ import { isRecord } from "../../utils.js";
2
+ import { Type } from "@oh-my-pi/pi-coding-agent/extensibility/typebox";
3
+ import { nanoid } from "nanoid";
4
+ import { CronScheduler } from "./scheduler.js";
5
+ const SchedulePromptParams = Type.Object({
6
+ action: Type.Union([
7
+ Type.Literal("add"), Type.Literal("remove"), Type.Literal("list"),
8
+ Type.Literal("enable"), Type.Literal("disable"), Type.Literal("update"),
9
+ Type.Literal("cleanup"),
10
+ ]),
11
+ name: Type.Optional(Type.String({
12
+ description: "Job name, auto-generated if omitted",
13
+ })),
14
+ schedule: Type.Optional(Type.String({
15
+ description: "Required for add. Cron expression (6-field with seconds e.g. '0 * * * * *'), ISO timestamp, relative time (+10s, +5m, +1h), or interval (5m, 1h)",
16
+ })),
17
+ prompt: Type.Optional(Type.String({
18
+ description: "Required for add. The prompt text to execute",
19
+ })),
20
+ jobId: Type.Optional(Type.String({
21
+ description: "Job ID for remove, enable, disable, or update actions",
22
+ })),
23
+ type: Type.Optional(Type.Union([
24
+ Type.Literal("cron"), Type.Literal("once"), Type.Literal("interval"),
25
+ ], {
26
+ description: "Job type. Use 'once' for relative times like '+10s'. Default is cron",
27
+ })),
28
+ description: Type.Optional(Type.String({
29
+ description: "Optional job description",
30
+ })),
31
+ scope: Type.Optional(Type.Union([
32
+ Type.Literal("session"), Type.Literal("workspace"),
33
+ ], {
34
+ description: "Scope: 'session' (default) = only fires in this session; 'workspace' = fires in any session of this workspace",
35
+ })),
36
+ });
37
+ export function createSchedulePromptToolDefinition(sessionId, getStorage, getScheduler) {
38
+ const def = {
39
+ name: "schedule_prompt",
40
+ label: "Schedule Prompt",
41
+ description: "IMPORTANT: For action='add', you MUST provide both 'schedule' parameter AND 'prompt' parameter. Schedule prompts at times/intervals. Schedule formats: 6-field cron (with seconds: '0 * * * * *' = every minute), ISO timestamp, relative time (+10s, +5m, +1h), or interval (5m, 1h). Type defaults to 'cron', use 'once' for relative/ISO times. Actions: add (needs schedule+prompt), list, remove/enable/disable/update (need jobId), cleanup.",
42
+ parameters: SchedulePromptParams,
43
+ async execute(_toolCallId, params) {
44
+ await Promise.resolve();
45
+ const storage = getStorage();
46
+ const scheduler = getScheduler();
47
+ const p = parseParams(params);
48
+ const action = p.action;
49
+ const details = { action, jobs: [] };
50
+ try {
51
+ switch (action) {
52
+ case "add": {
53
+ if (p.schedule === undefined || p.schedule === "" || p.prompt === undefined || p.prompt === "") {
54
+ const missing = [];
55
+ if (p.schedule === undefined || p.schedule === "")
56
+ missing.push("'schedule'");
57
+ if (p.prompt === undefined || p.prompt === "")
58
+ missing.push("'prompt'");
59
+ throw new Error(`Missing required parameters for add action: ${missing.join(" and ")}. You must provide both schedule (e.g., '+10s', '*/5 * * * * *') and prompt (the text to execute).`);
60
+ }
61
+ const jobName = p.name !== undefined && p.name !== "" ? p.name : `job-${nanoid(6)}`;
62
+ if (storage.hasJobWithName(jobName)) {
63
+ throw new Error(`A job named "${jobName}" already exists. Please use a different name or remove the existing job first.`);
64
+ }
65
+ const type = p.type ?? "cron";
66
+ const validated = CronScheduler.validateSchedule(type, p.schedule);
67
+ if (!validated.ok)
68
+ throw new Error(validated.error);
69
+ const schedule = validated.schedule;
70
+ const intervalMs = validated.intervalMs;
71
+ const scope = p.scope ?? "session";
72
+ const now = new Date().toISOString();
73
+ const job = {
74
+ id: nanoid(10),
75
+ name: jobName,
76
+ schedule,
77
+ prompt: p.prompt,
78
+ enabled: true,
79
+ type,
80
+ ...(intervalMs !== undefined ? { intervalMs } : {}),
81
+ createdAt: now,
82
+ runCount: 0,
83
+ scope,
84
+ ...(scope === "session" ? { sessionId } : {}),
85
+ ...(p.description !== undefined ? { description: p.description } : {}),
86
+ };
87
+ storage.addJob(job);
88
+ scheduler.addJob(job);
89
+ details.jobs = [job];
90
+ details.jobId = job.id;
91
+ details.jobName = job.name;
92
+ return {
93
+ content: [{
94
+ type: "text",
95
+ text: `✓ Created cron job "${job.name}" (${job.id})\nType: ${job.type}\nSchedule: ${job.schedule}\nPrompt: ${job.prompt}\nScope: ${job.scope}`,
96
+ }],
97
+ details,
98
+ };
99
+ }
100
+ case "remove": {
101
+ if (p.jobId === undefined || p.jobId === "")
102
+ throw new Error("jobId is required for remove action");
103
+ const job = storage.getJob(p.jobId);
104
+ if (!job)
105
+ throw new Error(`Job not found: ${p.jobId}`);
106
+ const removed = storage.removeJob(p.jobId);
107
+ if (removed) {
108
+ scheduler.removeJob(p.jobId);
109
+ details.jobId = p.jobId;
110
+ details.jobName = job.name;
111
+ return {
112
+ content: [{ type: "text", text: `✓ Removed cron job "${job.name}" (${p.jobId})` }],
113
+ details,
114
+ };
115
+ }
116
+ throw new Error(`Failed to remove job: ${p.jobId}`);
117
+ }
118
+ case "enable":
119
+ case "disable": {
120
+ if (p.jobId === undefined || p.jobId === "")
121
+ throw new Error(`jobId is required for ${action} action`);
122
+ const job = storage.getJob(p.jobId);
123
+ if (!job)
124
+ throw new Error(`Job not found: ${p.jobId}`);
125
+ const enabled = action === "enable";
126
+ storage.updateJob(p.jobId, { enabled });
127
+ const updated = { ...job, enabled };
128
+ scheduler.updateJob(p.jobId, updated);
129
+ details.jobs = [updated];
130
+ details.jobId = p.jobId;
131
+ details.jobName = job.name;
132
+ return {
133
+ content: [{ type: "text", text: `✓ ${enabled ? "Enabled" : "Disabled"} cron job "${job.name}" (${p.jobId})` }],
134
+ details,
135
+ };
136
+ }
137
+ case "cleanup": {
138
+ const disabledJobs = storage
139
+ .getAllJobs()
140
+ .filter((j) => !j.enabled && CronScheduler.isLoadedFor(j, sessionId));
141
+ if (disabledJobs.length === 0) {
142
+ details.jobs = [];
143
+ return {
144
+ content: [{ type: "text", text: "No disabled jobs to clean up" }],
145
+ details,
146
+ };
147
+ }
148
+ for (const job of disabledJobs) {
149
+ storage.removeJob(job.id);
150
+ scheduler.removeJob(job.id);
151
+ }
152
+ details.jobs = disabledJobs;
153
+ return {
154
+ content: [{
155
+ type: "text",
156
+ text: `✓ Removed ${String(disabledJobs.length)} disabled job(s):\n${disabledJobs.map((j) => ` - ${j.name} (${j.id})`).join("\n")}`,
157
+ }],
158
+ details,
159
+ };
160
+ }
161
+ case "update": {
162
+ if (p.jobId === undefined || p.jobId === "")
163
+ throw new Error("jobId is required for update action");
164
+ const job = storage.getJob(p.jobId);
165
+ if (!job)
166
+ throw new Error(`Job not found: ${p.jobId}`);
167
+ const updates = {};
168
+ if (p.name !== undefined && p.name !== "")
169
+ updates.name = p.name;
170
+ if (p.prompt !== undefined && p.prompt !== "")
171
+ updates.prompt = p.prompt;
172
+ if (p.description !== undefined)
173
+ updates.description = p.description;
174
+ if (p.schedule !== undefined && p.schedule !== "") {
175
+ const validated = CronScheduler.validateSchedule(job.type, p.schedule);
176
+ if (!validated.ok)
177
+ throw new Error(validated.error);
178
+ updates.schedule = validated.schedule;
179
+ if (validated.intervalMs !== undefined)
180
+ updates.intervalMs = validated.intervalMs;
181
+ }
182
+ storage.updateJob(p.jobId, updates);
183
+ const updated = { ...job, ...updates };
184
+ scheduler.updateJob(p.jobId, updated);
185
+ details.jobs = [updated];
186
+ details.jobId = p.jobId;
187
+ details.jobName = updated.name;
188
+ return {
189
+ content: [{ type: "text", text: `✓ Updated cron job "${updated.name}" (${p.jobId})` }],
190
+ details,
191
+ };
192
+ }
193
+ case "list": {
194
+ const jobs = storage
195
+ .getAllJobs()
196
+ .filter((j) => CronScheduler.isLoadedFor(j, sessionId));
197
+ details.jobs = jobs;
198
+ if (jobs.length === 0) {
199
+ return {
200
+ content: [{ type: "text", text: "No cron jobs configured." }],
201
+ details,
202
+ };
203
+ }
204
+ const lines = ["Configured cron jobs:", ""];
205
+ for (const job of jobs) {
206
+ const status = job.enabled ? "✓" : "✗";
207
+ const nextRun = scheduler.getNextRun(job.id);
208
+ const nextStr = nextRun !== null ? `Next: ${nextRun.toISOString()}` : "";
209
+ const lastStr = job.lastRun !== undefined && job.lastRun !== "" ? `Last: ${job.lastRun}` : "Never run";
210
+ lines.push(`${status} ${job.name} (${job.id})`);
211
+ lines.push(` Type: ${job.type} | Schedule: ${job.schedule} | Scope: ${job.scope}`);
212
+ lines.push(` Prompt: ${job.prompt}`);
213
+ lines.push(` ${lastStr} ${nextStr !== "" ? `| ${nextStr}` : ""}`);
214
+ lines.push(` Runs: ${String(job.runCount)} | Status: ${job.lastStatus ?? "pending"}`);
215
+ if (job.description !== undefined && job.description !== "")
216
+ lines.push(` Description: ${job.description}`);
217
+ lines.push("");
218
+ }
219
+ return {
220
+ content: [{ type: "text", text: lines.join("\n") }],
221
+ details,
222
+ };
223
+ }
224
+ default:
225
+ throw new Error(`Unknown action: ${action}`);
226
+ }
227
+ }
228
+ catch (error) {
229
+ details.error = error instanceof Error ? error.message : String(error);
230
+ return {
231
+ content: [{ type: "text", text: `✗ Error: ${details.error}` }],
232
+ details,
233
+ };
234
+ }
235
+ },
236
+ };
237
+ return def;
238
+ }
239
+ function parseParams(params) {
240
+ const p = isRecord(params) ? params : {};
241
+ return {
242
+ action: typeof p["action"] === "string" ? p["action"] : "",
243
+ ...(typeof p["name"] === "string" ? { name: p["name"] } : {}),
244
+ ...(typeof p["schedule"] === "string" ? { schedule: p["schedule"] } : {}),
245
+ ...(typeof p["prompt"] === "string" ? { prompt: p["prompt"] } : {}),
246
+ ...(typeof p["jobId"] === "string" ? { jobId: p["jobId"] } : {}),
247
+ ...(p["type"] === "cron" || p["type"] === "once" || p["type"] === "interval" ? { type: p["type"] } : {}),
248
+ ...(typeof p["description"] === "string" ? { description: p["description"] } : {}),
249
+ ...(p["scope"] === "session" || p["scope"] === "workspace" ? { scope: p["scope"] } : {}),
250
+ };
251
+ }
252
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../src/server/sessions/schedulePrompt/tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/server/sessions/schedulePrompt/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,254 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { access, copyFile, mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
4
+ import { basename, dirname, join } from "node:path";
5
+ import { homedir } from "node:os";
6
+ import { canonicalizeStoredCwd } from "../workingDirectory.js";
7
+ import { isRecord, isNodeErrorWithCode } from "../utils.js";
8
+ export class SessionArchiveStore {
9
+ constructor(filePath = join(homedir(), ".omp-web", "archived-sessions.json"), archiveDir = join(dirname(filePath), "archived-sessions")) {
10
+ this.filePath = filePath;
11
+ this.archiveDir = archiveDir;
12
+ this.operationQueue = Promise.resolve();
13
+ }
14
+ async list() {
15
+ return (await this.read()).sessions;
16
+ }
17
+ async get(sessionId) {
18
+ const sessions = (await this.read()).sessions;
19
+ return sessions.find((session) => session.sessionId === sessionId) ?? sessions.find((session) => session.sessionId.startsWith(sessionId));
20
+ }
21
+ async archive(session) {
22
+ const [record] = await this.archiveMany([session]);
23
+ if (record === undefined)
24
+ throw new Error("Archive operation did not produce a record");
25
+ return record;
26
+ }
27
+ async archiveMany(sessions) {
28
+ if (sessions.length === 0)
29
+ return [];
30
+ return this.exclusive(async () => {
31
+ const data = await this.read();
32
+ const records = [];
33
+ const filesToRemove = [];
34
+ for (const session of sessions) {
35
+ const existingIndex = data.sessions.findIndex((record) => record.sessionId === session.sessionId);
36
+ const existing = existingIndex === -1 ? undefined : data.sessions[existingIndex];
37
+ const archivePath = existing?.archivePath ?? this.archivePathFor(session);
38
+ const record = archiveRecordFromInput(session, {
39
+ archivedAt: existing?.archivedAt ?? new Date().toISOString(),
40
+ originalPath: existing?.originalPath ?? session.path,
41
+ archivePath,
42
+ });
43
+ await copySessionFileToArchive(session.path, archivePath);
44
+ if (existingIndex === -1)
45
+ data.sessions.push(record);
46
+ else
47
+ data.sessions[existingIndex] = record;
48
+ records.push(record);
49
+ filesToRemove.push({ source: session.path, archivePath });
50
+ }
51
+ await this.write(data);
52
+ for (const file of filesToRemove)
53
+ await removeActiveSessionFile(file.source, file.archivePath);
54
+ return records;
55
+ });
56
+ }
57
+ async restore(sessionId) {
58
+ await this.exclusive(async () => {
59
+ const data = await this.read();
60
+ const record = data.sessions.find((session) => session.sessionId === sessionId);
61
+ if (record === undefined)
62
+ return;
63
+ if (record.archivePath !== undefined && record.originalPath !== undefined) {
64
+ await restoreSessionFile(record.archivePath, record.originalPath);
65
+ }
66
+ const sessions = data.sessions.filter((session) => session.sessionId !== sessionId);
67
+ await this.write({ sessions });
68
+ });
69
+ }
70
+ async deleteArchived(sessionId) {
71
+ await this.deleteArchivedMany([sessionId]);
72
+ }
73
+ async deleteArchivedMany(sessionIds) {
74
+ const targetIds = uniqueStrings(sessionIds);
75
+ if (targetIds.length === 0)
76
+ return [];
77
+ return this.exclusive(async () => {
78
+ const data = await this.read();
79
+ const targetIdSet = new Set(targetIds);
80
+ const records = data.sessions.filter((session) => targetIdSet.has(session.sessionId));
81
+ if (records.length === 0)
82
+ return [];
83
+ for (const record of records) {
84
+ if (record.archivePath !== undefined && await pathExists(record.archivePath))
85
+ await unlink(record.archivePath);
86
+ }
87
+ const sessions = data.sessions.filter((session) => !targetIdSet.has(session.sessionId));
88
+ await this.write({ sessions });
89
+ const deletedIds = new Set(records.map((record) => record.sessionId));
90
+ return targetIds.filter((sessionId) => deletedIds.has(sessionId));
91
+ });
92
+ }
93
+ async isArchived(sessionId) {
94
+ return (await this.get(sessionId)) !== undefined;
95
+ }
96
+ archivePathFor(session) {
97
+ const sourceName = basename(session.path);
98
+ const fileName = sourceName === "" ? `${safeFileName(session.sessionId)}.jsonl` : sourceName;
99
+ return join(this.archiveDir, fileName);
100
+ }
101
+ async exclusive(operation) {
102
+ const previous = this.operationQueue;
103
+ let release = () => undefined;
104
+ this.operationQueue = new Promise((resolve) => { release = resolve; });
105
+ await previous.catch(() => undefined);
106
+ try {
107
+ return await operation();
108
+ }
109
+ finally {
110
+ release();
111
+ }
112
+ }
113
+ async read() {
114
+ try {
115
+ const value = JSON.parse(await readFile(this.filePath, "utf8"));
116
+ return parseArchiveFile(value);
117
+ }
118
+ catch (error) {
119
+ if (isNodeErrorWithCode(error, "ENOENT"))
120
+ return { sessions: [] };
121
+ throw error;
122
+ }
123
+ }
124
+ async write(data) {
125
+ await mkdir(dirname(this.filePath), { recursive: true });
126
+ const tempPath = join(dirname(this.filePath), `.${basename(this.filePath)}.${String(process.pid)}.${Date.now().toString()}.${randomUUID()}.tmp`);
127
+ try {
128
+ await writeFile(tempPath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
129
+ await rename(tempPath, this.filePath);
130
+ }
131
+ catch (error) {
132
+ await unlink(tempPath).catch(() => undefined);
133
+ throw error;
134
+ }
135
+ }
136
+ }
137
+ function archiveRecordFromInput(session, archive) {
138
+ return {
139
+ sessionId: session.sessionId,
140
+ cwd: canonicalizeStoredCwd(session.cwd),
141
+ archivedAt: archive.archivedAt,
142
+ originalPath: archive.originalPath,
143
+ archivePath: archive.archivePath,
144
+ created: session.created,
145
+ modified: session.modified,
146
+ messageCount: session.messageCount,
147
+ firstMessage: session.firstMessage,
148
+ ...(session.name === undefined ? {} : { name: session.name }),
149
+ ...(session.parentSessionPath === undefined ? {} : { parentSessionPath: session.parentSessionPath }),
150
+ };
151
+ }
152
+ async function copySessionFileToArchive(source, archivePath) {
153
+ if (source === archivePath)
154
+ return;
155
+ await mkdir(dirname(archivePath), { recursive: true });
156
+ if (await pathExists(archivePath))
157
+ return;
158
+ await copyFile(source, archivePath);
159
+ }
160
+ async function removeActiveSessionFile(source, archivePath) {
161
+ if (source === archivePath)
162
+ return;
163
+ if (await pathExists(source))
164
+ await unlink(source);
165
+ }
166
+ async function restoreSessionFile(archivePath, originalPath) {
167
+ if (archivePath === originalPath)
168
+ return;
169
+ if (await pathExists(originalPath))
170
+ throw new Error(`Cannot restore archived session because a session already exists at ${originalPath}`);
171
+ await mkdir(dirname(originalPath), { recursive: true });
172
+ await moveFile(archivePath, originalPath);
173
+ }
174
+ async function moveFile(source, destination) {
175
+ try {
176
+ await rename(source, destination);
177
+ }
178
+ catch (error) {
179
+ if (!isNodeErrorWithCode(error, "EXDEV"))
180
+ throw error;
181
+ await copyFile(source, destination);
182
+ await unlink(source);
183
+ }
184
+ }
185
+ async function pathExists(path) {
186
+ try {
187
+ await access(path, constants.F_OK);
188
+ return true;
189
+ }
190
+ catch (error) {
191
+ if (isNodeErrorWithCode(error, "ENOENT"))
192
+ return false;
193
+ throw error;
194
+ }
195
+ }
196
+ function parseArchiveFile(value) {
197
+ if (!isRecord(value) || !Array.isArray(value["sessions"]))
198
+ throw new Error("Invalid archive file");
199
+ return { sessions: value["sessions"].map(parseArchivedSessionRecord) };
200
+ }
201
+ function parseArchivedSessionRecord(value) {
202
+ if (!isRecord(value))
203
+ throw new Error("Invalid archived session record");
204
+ const sessionId = value["sessionId"];
205
+ const cwd = value["cwd"];
206
+ const archivedAt = value["archivedAt"];
207
+ if (typeof sessionId !== "string" || typeof cwd !== "string" || typeof archivedAt !== "string")
208
+ throw new Error("Invalid archived session record");
209
+ const canonicalCwd = canonicalizeStoredCwd(cwd);
210
+ const originalPath = optionalString(value, "originalPath");
211
+ const archivePath = optionalString(value, "archivePath");
212
+ const created = optionalString(value, "created");
213
+ const modified = optionalString(value, "modified");
214
+ const messageCount = optionalNumber(value, "messageCount");
215
+ const firstMessage = optionalString(value, "firstMessage");
216
+ const name = optionalString(value, "name");
217
+ const parentSessionPath = optionalString(value, "parentSessionPath");
218
+ return {
219
+ sessionId,
220
+ cwd: canonicalCwd,
221
+ archivedAt,
222
+ ...(originalPath === undefined ? {} : { originalPath }),
223
+ ...(archivePath === undefined ? {} : { archivePath }),
224
+ ...(created === undefined ? {} : { created }),
225
+ ...(modified === undefined ? {} : { modified }),
226
+ ...(messageCount === undefined ? {} : { messageCount }),
227
+ ...(firstMessage === undefined ? {} : { firstMessage }),
228
+ ...(name === undefined ? {} : { name }),
229
+ ...(parentSessionPath === undefined ? {} : { parentSessionPath }),
230
+ };
231
+ }
232
+ function optionalString(record, key) {
233
+ const value = record[key];
234
+ if (value === undefined)
235
+ return undefined;
236
+ if (typeof value !== "string")
237
+ throw new Error("Invalid archived session record");
238
+ return value;
239
+ }
240
+ function optionalNumber(record, key) {
241
+ const value = record[key];
242
+ if (value === undefined)
243
+ return undefined;
244
+ if (typeof value !== "number")
245
+ throw new Error("Invalid archived session record");
246
+ return value;
247
+ }
248
+ function safeFileName(value) {
249
+ return value.replace(/[^a-zA-Z0-9._-]/g, "_") || "session";
250
+ }
251
+ function uniqueStrings(values) {
252
+ return [...new Set(values)];
253
+ }
254
+ //# sourceMappingURL=sessionArchiveStore.js.map