opencode-routines 0.1.2 → 0.1.4

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/dist/index.d.ts CHANGED
@@ -12,56 +12,5 @@
12
12
  * - Environment variable injection (PATH for node/npx)
13
13
  */
14
14
  import type { Plugin } from "@opencode-ai/plugin";
15
- type OpencodeRunFormat = "default" | "json";
16
- interface JobRunSpec {
17
- prompt?: string;
18
- command?: string;
19
- arguments?: string;
20
- files?: string[];
21
- agent?: string;
22
- model?: string;
23
- variant?: string;
24
- title?: string;
25
- share?: boolean;
26
- continue?: boolean;
27
- session?: string;
28
- runFormat?: OpencodeRunFormat;
29
- attachUrl?: string;
30
- port?: number;
31
- }
32
- type JobInvocation = {
33
- command: string;
34
- args: string[];
35
- };
36
- interface Job {
37
- scopeId?: string;
38
- slug: string;
39
- name: string;
40
- schedule: string;
41
- prompt?: string;
42
- attachUrl?: string;
43
- run?: JobRunSpec;
44
- invocation?: JobInvocation;
45
- timeoutSeconds?: number;
46
- source?: string;
47
- workdir?: string;
48
- createdAt: string;
49
- updatedAt?: string;
50
- lastRunAt?: string;
51
- lastRunExitCode?: number;
52
- lastRunError?: string;
53
- lastRunSource?: "manual" | "scheduled";
54
- lastRunStatus?: "running" | "success" | "failed";
55
- }
56
- type RoutinePromptClient = {
57
- session?: {
58
- prompt?: (input: unknown) => Promise<unknown>;
59
- };
60
- };
61
- export declare function __testSubmitSessionPrompt(client: RoutinePromptClient, sessionID: string, prompt: string): Promise<void>;
62
- export declare function __testBuildOpencodeArgs(job: Job): {
63
- command: string;
64
- args: string[];
65
- };
66
15
  export declare const SchedulerPlugin: Plugin;
67
16
  export default SchedulerPlugin;
package/dist/index.js CHANGED
@@ -12969,17 +12969,17 @@ function promptResultError(result) {
12969
12969
  return;
12970
12970
  return typeof error45 === "string" ? error45 : JSON.stringify(error45);
12971
12971
  }
12972
- async function __testSubmitSessionPrompt(client, sessionID, prompt) {
12972
+ async function testSubmitSessionPrompt(client, sessionID, prompt) {
12973
12973
  await submitSessionPrompt(client, sessionID, prompt);
12974
12974
  }
12975
12975
  async function submitSessionPrompt(client, sessionID, prompt) {
12976
12976
  const session = client.session;
12977
- const send = session?.prompt;
12977
+ const send = session?.promptAsync;
12978
12978
  if (!send)
12979
- throw new Error("Current opencode client does not expose session.prompt");
12979
+ throw new Error("Current opencode client does not expose session.promptAsync");
12980
12980
  const result = await send.call(session, {
12981
- sessionID,
12982
- parts: [{ type: "text", text: prompt }]
12981
+ path: { id: sessionID },
12982
+ body: { parts: [{ type: "text", text: prompt }] }
12983
12983
  });
12984
12984
  const error45 = promptResultError(result);
12985
12985
  if (error45)
@@ -14182,7 +14182,7 @@ function buildOpencodeArgs(job) {
14182
14182
  args.push(run.command ? run.arguments ?? "" : run.prompt ?? "");
14183
14183
  return { command, args };
14184
14184
  }
14185
- function __testBuildOpencodeArgs(job) {
14185
+ function testBuildOpencodeArgs(job) {
14186
14186
  return buildOpencodeArgs(job);
14187
14187
  }
14188
14188
  function buildRunEnvironment() {
@@ -15386,10 +15386,12 @@ ${logs}`, { job, logPath, logs });
15386
15386
  }
15387
15387
  };
15388
15388
  };
15389
+ SchedulerPlugin.__test = {
15390
+ buildOpencodeArgs: testBuildOpencodeArgs,
15391
+ submitSessionPrompt: testSubmitSessionPrompt
15392
+ };
15389
15393
  var src_default = SchedulerPlugin;
15390
15394
  export {
15391
15395
  src_default as default,
15392
- __testSubmitSessionPrompt,
15393
- __testBuildOpencodeArgs,
15394
15396
  SchedulerPlugin
15395
15397
  };
package/dist/tui.d.ts CHANGED
@@ -1,59 +1,4 @@
1
- type TuiApi = {
2
- route: {
3
- current: {
4
- name: string;
5
- params?: Record<string, any>;
6
- };
7
- navigate?: (name: string, params?: Record<string, unknown>) => void;
8
- };
9
- client: {
10
- session: {
11
- prompt: (input: any) => Promise<unknown>;
12
- };
13
- };
14
- ui: {
15
- dialog: {
16
- replace: (render: () => any) => void;
17
- clear: () => void;
18
- };
19
- DialogAlert: (props: {
20
- title: string;
21
- message: string;
22
- }) => any;
23
- DialogPrompt: (props: {
24
- title: string;
25
- placeholder?: string;
26
- onConfirm?: (value: string) => void;
27
- }) => any;
28
- DialogSelect: (props: {
29
- title: string;
30
- options: Array<{
31
- title: string;
32
- value: string;
33
- description?: string;
34
- footer?: string;
35
- }>;
36
- onSelect?: (option: {
37
- value: string;
38
- }) => void;
39
- }) => any;
40
- toast: (input: {
41
- variant?: "info" | "success" | "warning" | "error";
42
- title?: string;
43
- message: string;
44
- }) => void;
45
- };
46
- lifecycle: {
47
- onDispose: (fn: () => void) => void;
48
- };
49
- keymap: {
50
- registerLayer: (input: {
51
- commands: any[];
52
- bindings?: any[];
53
- }) => unknown;
54
- };
55
- };
56
- type TuiPlugin = (api: TuiApi, options?: Record<string, unknown>, meta?: Record<string, unknown>) => Promise<void>;
1
+ import type { TuiPlugin } from "@opencode-ai/plugin/tui";
57
2
  declare const _default: {
58
3
  id: string;
59
4
  tui: TuiPlugin;
package/dist/tui.js CHANGED
@@ -54,11 +54,9 @@ function loopID() {
54
54
  }
55
55
  async function submitPrompt(api, loop) {
56
56
  loop.fires += 1;
57
- await api.client.session.prompt({
58
- path: { sessionID: loop.sessionID },
59
- body: {
60
- parts: [{ type: "text", text: loop.prompt }]
61
- }
57
+ await api.client.session.promptAsync({
58
+ sessionID: loop.sessionID,
59
+ parts: [{ type: "text", text: loop.prompt }]
62
60
  });
63
61
  }
64
62
  function scheduleFixed(api, loop) {
@@ -113,11 +111,92 @@ function showLoops(api) {
113
111
  }
114
112
  }));
115
113
  }
114
+ function openLoopPrompt(api) {
115
+ const sessionID = activeSessionID(api);
116
+ if (!sessionID) {
117
+ api.ui.toast({ variant: "warning", message: "Open a session before starting /loop." });
118
+ return;
119
+ }
120
+ api.ui.dialog.replace(() => api.ui.DialogPrompt({
121
+ title: "Start loop",
122
+ placeholder: "5m /babysit-prs or /babysit-prs",
123
+ onConfirm: (value) => {
124
+ const parsed = parseLoop(value);
125
+ if (!parsed) {
126
+ api.ui.toast({ variant: "warning", message: "Usage: /loop 5m <prompt> or /loop <prompt>" });
127
+ return;
128
+ }
129
+ const loop = {
130
+ id: loopID(),
131
+ sessionID,
132
+ prompt: parsed.prompt,
133
+ mode: parsed.intervalSeconds === undefined ? "dynamic" : "fixed",
134
+ intervalSeconds: parsed.intervalSeconds,
135
+ createdAt: new Date().toISOString(),
136
+ fires: 0
137
+ };
138
+ loops.set(loop.id, loop);
139
+ if (loop.mode === "fixed")
140
+ scheduleFixed(api, loop);
141
+ else
142
+ submitPrompt(api, loop);
143
+ api.ui.toast({
144
+ variant: "success",
145
+ title: "Loop started",
146
+ message: loop.mode === "fixed" ? `${loop.id} every ${loop.intervalSeconds}s` : `${loop.id} dynamic mode; use ScheduleWakeup to continue`
147
+ });
148
+ api.ui.dialog.clear();
149
+ }
150
+ }));
151
+ }
152
+ function showStandaloneSchedulesHelp(api) {
153
+ api.ui.dialog.replace(() => api.ui.DialogAlert({
154
+ title: "Standalone schedules",
155
+ message: "Use the ScheduleCreate tool (or natural language like 'create a standalone scheduled run...') to create durable OS-backed standalone sessions. The ambiguous /schedule command is intentionally not registered."
156
+ }));
157
+ }
158
+ function legacyCommands(api) {
159
+ return [
160
+ {
161
+ title: "Start same-session loop",
162
+ value: "routines.loop",
163
+ description: "Start a same-session loop. Fixed: 5m <prompt>; dynamic: <prompt>.",
164
+ category: "Scheduler",
165
+ slash: { name: "loop" },
166
+ onSelect: () => openLoopPrompt(api)
167
+ },
168
+ {
169
+ title: "List active loops",
170
+ value: "routines.loops",
171
+ description: "List and stop active same-session loops.",
172
+ category: "Scheduler",
173
+ slash: { name: "loops" },
174
+ onSelect: () => showLoops(api)
175
+ },
176
+ {
177
+ title: "Stop a same-session loop",
178
+ value: "routines.stop-loop",
179
+ description: "List active loops and select one to stop.",
180
+ category: "Scheduler",
181
+ slash: { name: "stop-loop" },
182
+ onSelect: () => showLoops(api)
183
+ },
184
+ {
185
+ title: "Create standalone scheduled session",
186
+ value: "routines.schedule-standalone-session",
187
+ description: "Show help for durable OS-backed standalone schedules.",
188
+ category: "Scheduler",
189
+ slash: { name: "schedule-standalone-session" },
190
+ onSelect: () => showStandaloneSchedulesHelp(api)
191
+ }
192
+ ];
193
+ }
116
194
  var tui = async (api) => {
117
195
  api.lifecycle.onDispose(() => {
118
196
  for (const id of [...loops.keys()])
119
197
  stopLoop(id);
120
198
  });
199
+ api.command?.register(() => legacyCommands(api));
121
200
  api.keymap.registerLayer({
122
201
  commands: [
123
202
  {
@@ -125,78 +204,28 @@ var tui = async (api) => {
125
204
  title: "Start same-session loop",
126
205
  category: "Scheduler",
127
206
  namespace: "palette",
128
- slashName: "loop",
129
- run() {
130
- const sessionID = activeSessionID(api);
131
- if (!sessionID) {
132
- api.ui.toast({ variant: "warning", message: "Open a session before starting /loop." });
133
- return;
134
- }
135
- api.ui.dialog.replace(() => api.ui.DialogPrompt({
136
- title: "Start loop",
137
- placeholder: "5m /babysit-prs or /babysit-prs",
138
- onConfirm: (value) => {
139
- const parsed = parseLoop(value);
140
- if (!parsed) {
141
- api.ui.toast({ variant: "warning", message: "Usage: /loop 5m <prompt> or /loop <prompt>" });
142
- return;
143
- }
144
- const loop = {
145
- id: loopID(),
146
- sessionID,
147
- prompt: parsed.prompt,
148
- mode: parsed.intervalSeconds === undefined ? "dynamic" : "fixed",
149
- intervalSeconds: parsed.intervalSeconds,
150
- createdAt: new Date().toISOString(),
151
- fires: 0
152
- };
153
- loops.set(loop.id, loop);
154
- if (loop.mode === "fixed")
155
- scheduleFixed(api, loop);
156
- else
157
- submitPrompt(api, loop);
158
- api.ui.toast({
159
- variant: "success",
160
- title: "Loop started",
161
- message: loop.mode === "fixed" ? `${loop.id} every ${loop.intervalSeconds}s` : `${loop.id} dynamic mode; use ScheduleWakeup to continue`
162
- });
163
- api.ui.dialog.clear();
164
- }
165
- }));
166
- }
207
+ run: () => openLoopPrompt(api)
167
208
  },
168
209
  {
169
210
  name: "routines.loops",
170
211
  title: "List active loops",
171
212
  category: "Scheduler",
172
213
  namespace: "palette",
173
- slashName: "loops",
174
- run() {
175
- showLoops(api);
176
- }
214
+ run: () => showLoops(api)
177
215
  },
178
216
  {
179
217
  name: "routines.stop_loop",
180
218
  title: "Stop a same-session loop",
181
219
  category: "Scheduler",
182
220
  namespace: "palette",
183
- slashName: "stop-loop",
184
- run() {
185
- showLoops(api);
186
- }
221
+ run: () => showLoops(api)
187
222
  },
188
223
  {
189
224
  name: "routines.schedule_standalone_session",
190
225
  title: "Create standalone scheduled session",
191
226
  category: "Scheduler",
192
227
  namespace: "palette",
193
- slashName: "schedule-standalone-session",
194
- run() {
195
- api.ui.dialog.replace(() => api.ui.DialogAlert({
196
- title: "Standalone schedules",
197
- message: "Use the ScheduleCreate tool (or natural language like 'create a standalone scheduled run...') to create durable OS-backed standalone sessions. The ambiguous /schedule command is intentionally not registered."
198
- }));
199
- }
228
+ run: () => showStandaloneSchedulesHelp(api)
200
229
  }
201
230
  ]
202
231
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-routines",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "OpenCode routines: same-session loops, cron prompts, and host-backed standalone scheduled agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -54,13 +54,13 @@
54
54
  },
55
55
  "homepage": "https://github.com/EmilioEsposito/opencode-routines#readme",
56
56
  "dependencies": {
57
- "@opencode-ai/plugin": "^1.1.1"
57
+ "@opencode-ai/plugin": "^1.17.3"
58
58
  },
59
59
  "devDependencies": {
60
60
  "bun-types": "latest",
61
61
  "typescript": "^5.7.3"
62
62
  },
63
63
  "peerDependencies": {
64
- "@opencode-ai/plugin": ">=1.1.1"
64
+ "@opencode-ai/plugin": ">=1.17.3"
65
65
  }
66
66
  }