opencode-routines 0.1.7 → 0.1.8
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 +12 -2
- package/dist/index.js +85 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,17 @@ Add the server plugin to your OpenCode config (`~/.config/opencode/opencode.json
|
|
|
34
34
|
|
|
35
35
|
OpenCode installs the package from npm on next start. Use `@latest` if you want new versions on restart, or pin a version such as `"opencode-routines@0.1.1"`.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
That single entry is the whole packaged experience: on load, the server plugin also installs slash commands (`/loop`, `/loops`, `/stop-loop`, `/schedule-standalone-session`) as managed OpenCode custom command files under `~/.config/opencode/commands/`. These work in **both** the terminal TUI and OpenCode Desktop. The install is idempotent and marker-guarded: only files containing the `managed-by: opencode-routines` marker are ever created or updated, so a user-edited `loop.md` (marker removed) is never touched. Restart OpenCode once after the first install for the commands to appear. Opt out with plugin options:
|
|
38
|
+
|
|
39
|
+
```jsonc
|
|
40
|
+
{
|
|
41
|
+
"plugin": [["opencode-routines@latest", { "commands": false }]]
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Optional native TUI dialogs
|
|
46
|
+
|
|
47
|
+
`opencode-routines-tui` is an optional companion package that replaces the prompt-based commands with native TUI dialogs (interactive loop list, prompt dialogs). It is a **TUI plugin**, which OpenCode loads from `tui.json` — NOT from `opencode.json`'s `plugin` array (that array is for server plugins only; the server loader will reject it with `must default export an object with server()`).
|
|
38
48
|
|
|
39
49
|
Add it to `~/.config/opencode/tui.json` (or a project-level `.opencode/tui.json`, or a custom path via the `OPENCODE_TUI_CONFIG` env var):
|
|
40
50
|
|
|
@@ -48,7 +58,7 @@ Add it to `~/.config/opencode/tui.json` (or a project-level `.opencode/tui.json`
|
|
|
48
58
|
|
|
49
59
|
`opencode-routines-tui` is separate so the terminal TUI can install and load the TUI plugin entrypoint (`exports["./tui"]`). The root package still ships a `./tui` export for advanced/manual loaders, but installs should use the companion package via `tui.json`.
|
|
50
60
|
|
|
51
|
-
TUI
|
|
61
|
+
The TUI plugin only works in the **terminal TUI** (`opencode` in a terminal); OpenCode Desktop builds its slash list from a different command registry and does not load `tui.json` TUI plugins. Note that installing the TUI plugin alongside the managed command files shows both variants of each slash command in the terminal TUI — if that bothers you, disable the managed commands with `{ "commands": false }` (above) and rely on the TUI plugin there.
|
|
52
62
|
|
|
53
63
|
## What it provides
|
|
54
64
|
|
package/dist/index.js
CHANGED
|
@@ -12335,7 +12335,7 @@ function tool(input) {
|
|
|
12335
12335
|
}
|
|
12336
12336
|
tool.schema = exports_external;
|
|
12337
12337
|
// src/index.ts
|
|
12338
|
-
import { createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, unlinkSync } from "fs";
|
|
12338
|
+
import { createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync, unlinkSync } from "fs";
|
|
12339
12339
|
import { basename, dirname, join, resolve as resolvePath } from "path";
|
|
12340
12340
|
import { homedir, platform } from "os";
|
|
12341
12341
|
import { execFileSync, execSync, spawn } from "child_process";
|
|
@@ -14497,8 +14497,91 @@ function getJobLogs(job, options) {
|
|
|
14497
14497
|
return null;
|
|
14498
14498
|
}
|
|
14499
14499
|
}
|
|
14500
|
-
var
|
|
14500
|
+
var MANAGED_COMMAND_MARKER = "managed-by: opencode-routines";
|
|
14501
|
+
var MANAGED_COMMANDS = {
|
|
14502
|
+
"loop.md": `---
|
|
14503
|
+
description: Start a same-session loop (opencode-routines)
|
|
14504
|
+
---
|
|
14505
|
+
<!-- ${MANAGED_COMMAND_MARKER} -->
|
|
14506
|
+
|
|
14507
|
+
Use the LoopCreate tool from opencode-routines to start a same-session loop.
|
|
14508
|
+
|
|
14509
|
+
Arguments: $ARGUMENTS
|
|
14510
|
+
|
|
14511
|
+
Rules:
|
|
14512
|
+
- If the first argument looks like an interval (30s, 5m, 1h), pass it as \`interval\` and the rest as \`prompt\`.
|
|
14513
|
+
- Otherwise start a dynamic loop with the full arguments as \`prompt\`.
|
|
14514
|
+
- If no arguments were provided, ask what prompt to loop.
|
|
14515
|
+
- Confirm the created loop id and mode in one short sentence.
|
|
14516
|
+
`,
|
|
14517
|
+
"loops.md": `---
|
|
14518
|
+
description: List active same-session loops (opencode-routines)
|
|
14519
|
+
---
|
|
14520
|
+
<!-- ${MANAGED_COMMAND_MARKER} -->
|
|
14521
|
+
|
|
14522
|
+
Call the LoopList tool from opencode-routines and show the active loops as a short table (id, mode/interval, fires, prompt). If there are none, say so in one sentence.
|
|
14523
|
+
`,
|
|
14524
|
+
"stop-loop.md": `---
|
|
14525
|
+
description: Stop a same-session loop (opencode-routines)
|
|
14526
|
+
---
|
|
14527
|
+
<!-- ${MANAGED_COMMAND_MARKER} -->
|
|
14528
|
+
|
|
14529
|
+
Stop a same-session loop using opencode-routines tools.
|
|
14530
|
+
|
|
14531
|
+
Arguments: $ARGUMENTS
|
|
14532
|
+
|
|
14533
|
+
Rules:
|
|
14534
|
+
- If an argument matches a loop id, call LoopDelete with it.
|
|
14535
|
+
- Otherwise call LoopList first; if exactly one loop is active, stop it; if several, list them and ask which to stop.
|
|
14536
|
+
`,
|
|
14537
|
+
"schedule-standalone-session.md": `---
|
|
14538
|
+
description: Create a durable standalone scheduled opencode run (opencode-routines)
|
|
14539
|
+
---
|
|
14540
|
+
<!-- ${MANAGED_COMMAND_MARKER} -->
|
|
14541
|
+
|
|
14542
|
+
Create a durable OS-backed standalone schedule using the ScheduleCreate tool from opencode-routines.
|
|
14543
|
+
|
|
14544
|
+
Arguments: $ARGUMENTS
|
|
14545
|
+
|
|
14546
|
+
Rules:
|
|
14547
|
+
- Derive a short job name and a 5-field cron expression from the arguments; ask if the schedule is ambiguous.
|
|
14548
|
+
- Use the remaining text as the prompt for the standalone run.
|
|
14549
|
+
- After creating, report the job name, cron, and next steps (ScheduleList / ScheduleLogs) in two sentences max.
|
|
14550
|
+
`
|
|
14551
|
+
};
|
|
14552
|
+
function managedCommandsDir() {
|
|
14553
|
+
const xdg = process.env.XDG_CONFIG_HOME?.trim();
|
|
14554
|
+
const base = xdg ? xdg : join(homedir(), ".config");
|
|
14555
|
+
return join(base, "opencode", "commands");
|
|
14556
|
+
}
|
|
14557
|
+
function syncManagedCommands() {
|
|
14558
|
+
const dir = managedCommandsDir();
|
|
14559
|
+
ensureDir(dir);
|
|
14560
|
+
for (const [filename, content] of Object.entries(MANAGED_COMMANDS)) {
|
|
14561
|
+
const dest = join(dir, filename);
|
|
14562
|
+
const desired = `${content.trimEnd()}
|
|
14563
|
+
`;
|
|
14564
|
+
try {
|
|
14565
|
+
if (existsSync(dest)) {
|
|
14566
|
+
const current = readFileSync(dest, "utf-8");
|
|
14567
|
+
if (!current.includes(MANAGED_COMMAND_MARKER))
|
|
14568
|
+
continue;
|
|
14569
|
+
if (current === desired)
|
|
14570
|
+
continue;
|
|
14571
|
+
}
|
|
14572
|
+
const staged = `${dest}.opencode-routines.tmp`;
|
|
14573
|
+
writeFileSync(staged, desired);
|
|
14574
|
+
renameSync(staged, dest);
|
|
14575
|
+
} catch (error45) {
|
|
14576
|
+
console.error(`[opencode-routines] failed to install command ${filename}:`, error45);
|
|
14577
|
+
}
|
|
14578
|
+
}
|
|
14579
|
+
}
|
|
14580
|
+
var SchedulerPlugin = async (input, options) => {
|
|
14501
14581
|
const client = input?.client;
|
|
14582
|
+
if (options?.commands !== false) {
|
|
14583
|
+
syncManagedCommands();
|
|
14584
|
+
}
|
|
14502
14585
|
async function executeTool(name, args, context) {
|
|
14503
14586
|
const plugin = await SchedulerPlugin(input);
|
|
14504
14587
|
const definition = plugin.tool?.[name];
|
package/package.json
CHANGED