opencode-scheduled 0.1.0 → 0.1.1

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.
package/README.md CHANGED
File without changes
package/index.ts CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-scheduled",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "OpenCode plugin for scheduling prompts from the TUI.",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
package/src/constants.ts CHANGED
File without changes
package/src/format.ts CHANGED
File without changes
File without changes
package/src/scheduler.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
2
- import { emitSchedulerChange } from "./scheduler-events.ts";
2
+ import { emitSchedulerChange, onSchedulerChange } from "./scheduler-events.ts";
3
3
  import { createScheduledPrompt, readStore, updateStore } from "./store.ts";
4
4
  import { formatRunAt } from "./time.ts";
5
5
  import type { ScheduledPrompt } from "./types.ts";
6
6
 
7
- export const TICK_MS = 15_000;
7
+ export const TICK_MS = 2_000;
8
8
  export const SIDEBAR_MAX_JOBS = 6;
9
+ const MAX_TIMER_DELAY_MS = 60_000;
9
10
 
10
11
  export interface ScheduleDialogState {
11
12
  jobs: ScheduledPrompt[];
@@ -147,3 +148,85 @@ export async function deliverDuePrompts(api: TuiPluginApi): Promise<void> {
147
148
  }
148
149
  }
149
150
  }
151
+
152
+ async function nextWakeDelay(): Promise<number> {
153
+ const store = await readStore();
154
+ if (store.settings.paused) {
155
+ return MAX_TIMER_DELAY_MS;
156
+ }
157
+
158
+ const nextJob = store.jobs.filter((job) => job.status === "pending").sort(sortPending)[0];
159
+ if (!nextJob) {
160
+ return MAX_TIMER_DELAY_MS;
161
+ }
162
+
163
+ return Math.max(0, Math.min(nextJob.runAt - Date.now(), MAX_TIMER_DELAY_MS));
164
+ }
165
+
166
+ export function startScheduler(api: TuiPluginApi): () => void {
167
+ let timer: ReturnType<typeof setTimeout> | undefined;
168
+ let disposed = false;
169
+ let running = false;
170
+ let rerun = false;
171
+
172
+ const clearTimer = () => {
173
+ if (timer) {
174
+ clearTimeout(timer);
175
+ timer = undefined;
176
+ }
177
+ };
178
+
179
+ const schedule = async () => {
180
+ if (disposed) {
181
+ return;
182
+ }
183
+
184
+ clearTimer();
185
+ const delay = await nextWakeDelay();
186
+ if (disposed) {
187
+ return;
188
+ }
189
+
190
+ timer = setTimeout(() => {
191
+ void run();
192
+ }, delay);
193
+ };
194
+
195
+ const run = async () => {
196
+ if (disposed) {
197
+ return;
198
+ }
199
+
200
+ if (running) {
201
+ rerun = true;
202
+ return;
203
+ }
204
+
205
+ running = true;
206
+ try {
207
+ await deliverDuePrompts(api);
208
+ } finally {
209
+ running = false;
210
+ }
211
+
212
+ if (rerun) {
213
+ rerun = false;
214
+ void run();
215
+ return;
216
+ }
217
+
218
+ void schedule();
219
+ };
220
+
221
+ const disposeSchedulerChange = onSchedulerChange(() => {
222
+ void run();
223
+ });
224
+
225
+ void run();
226
+
227
+ return () => {
228
+ disposed = true;
229
+ clearTimer();
230
+ disposeSchedulerChange();
231
+ };
232
+ }
package/src/server.ts CHANGED
File without changes
package/src/store.ts CHANGED
File without changes
package/src/time.ts CHANGED
File without changes
File without changes
File without changes
File without changes
package/src/tui/ui.ts CHANGED
File without changes
package/src/tui.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
2
  import type { TuiPlugin, TuiPluginModule } from "@opencode-ai/plugin/tui";
3
3
  import { PLUGIN_ID, SCHEDULE_COMMAND_OPEN } from "./constants.ts";
4
- import { deliverDuePrompts, TICK_MS } from "./scheduler.ts";
4
+ import { startScheduler } from "./scheduler.ts";
5
5
  import { openManager, openScheduler } from "./tui/dialogs.tsx";
6
6
  import { SidebarScheduledPrompts } from "./tui/SidebarScheduledPrompts.tsx";
7
7
 
@@ -30,13 +30,9 @@ const tui: TuiPlugin = async (api) => {
30
30
  },
31
31
  });
32
32
 
33
- const timer = setInterval(() => {
34
- void deliverDuePrompts(api);
35
- }, TICK_MS);
36
-
37
- void deliverDuePrompts(api);
33
+ const disposeScheduler = startScheduler(api);
38
34
  api.lifecycle.onDispose(disposeCommands);
39
- api.lifecycle.onDispose(() => clearInterval(timer));
35
+ api.lifecycle.onDispose(disposeScheduler);
40
36
  };
41
37
 
42
38
  const module: TuiPluginModule & { id: string } = {
package/src/types.ts CHANGED
File without changes