@sideboard-ai/cli 0.1.103 → 0.1.107
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 +3 -0
- package/dist/index.js +99 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ npm i -g @sideboard-ai/cli
|
|
|
8
8
|
sideboard ls
|
|
9
9
|
sideboard send <thread> "…"
|
|
10
10
|
sideboard mcp # MCP stdio server
|
|
11
|
+
sideboard schedule ls # local jobs that trigger orchestration chats
|
|
11
12
|
```
|
|
12
13
|
|
|
13
14
|
Also installs `side` as a short alias. The MCP server is available as `sideboard mcp`, or via `@sideboard-ai/core`'s `sideboard-mcp` bin.
|
|
@@ -20,3 +21,5 @@ sideboard slack listen
|
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
How to connect and address Personal / Work Macs: [README — Slack](../../README.md#slack).
|
|
24
|
+
|
|
25
|
+
Schedules (Settings, CLI, or MCP `create_schedule`) fire only while Sideboard.app is running. Overnight: Settings → Advanced → Caffeinate while schedules are enabled. Details: [README — Scheduled orchestration](../../README.md#scheduled-orchestration).
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,15 @@ import {
|
|
|
30
30
|
disconnectLinear,
|
|
31
31
|
runSlackListen,
|
|
32
32
|
SLACK_OAUTH_REDIRECT,
|
|
33
|
-
LINEAR_OAUTH_REDIRECT
|
|
33
|
+
LINEAR_OAUTH_REDIRECT,
|
|
34
|
+
createSchedule,
|
|
35
|
+
deleteSchedule,
|
|
36
|
+
fireSchedule,
|
|
37
|
+
formatScheduleWhen,
|
|
38
|
+
getSchedule,
|
|
39
|
+
listSchedules,
|
|
40
|
+
resolveScheduleThreadId,
|
|
41
|
+
updateSchedule
|
|
34
42
|
} from "@sideboard-ai/core";
|
|
35
43
|
var VERSION = "0.1.0";
|
|
36
44
|
async function printUpgradeHint() {
|
|
@@ -504,6 +512,96 @@ ${preview.diffStat}`);
|
|
|
504
512
|
program.command("mcp").description("Run the Sideboard MCP stdio server").action(async () => {
|
|
505
513
|
await startMcpServer();
|
|
506
514
|
});
|
|
515
|
+
const scheduleCmd = program.command("schedule").description(
|
|
516
|
+
"Local jobs that trigger orchestration chats (Sideboard.app must be running to fire)"
|
|
517
|
+
);
|
|
518
|
+
scheduleCmd.command("ls").description("List schedules").action(() => {
|
|
519
|
+
const rows = listSchedules();
|
|
520
|
+
if (rows.length === 0) {
|
|
521
|
+
console.log(chalk.dim("No schedules"));
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
for (const row of rows) {
|
|
525
|
+
const target = row.threadId ? row.threadId.slice(0, 8) : "new chat";
|
|
526
|
+
const on = row.enabled ? chalk.green("on ") : chalk.dim("off");
|
|
527
|
+
console.log(
|
|
528
|
+
`${row.id.slice(0, 8)} ${on} ${formatScheduleWhen(row.when)} next ${row.nextRunAt} ${target} ${row.name}`
|
|
529
|
+
);
|
|
530
|
+
if (row.lastError) console.log(chalk.red(` ${row.lastError}`));
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
scheduleCmd.command("add").requiredOption("--prompt <text>", "prompt / goal queued when the job fires").option("--name <name>", "short label").option("--at <iso>", "one-shot ISO datetime").option("--every <duration>", "interval (15m, 1h, 6h, 1d)").option("--cron <expr>", "5-field cron").option("--tz <iana>", "timezone for cron").option(
|
|
534
|
+
"--thread <id>",
|
|
535
|
+
"existing orchestration chat (or self). Omit to create a new Global chat each run"
|
|
536
|
+
).option("--agent <agent>", "claude|cursor|codex|opencode (new chats only)").action((opts) => {
|
|
537
|
+
const cadence = [opts.at, opts.every, opts.cron].filter(Boolean);
|
|
538
|
+
if (cadence.length !== 1) {
|
|
539
|
+
throw new Error("Pass exactly one of --at, --every, or --cron");
|
|
540
|
+
}
|
|
541
|
+
const when = opts.at ? { kind: "once", at: String(opts.at) } : opts.every ? { kind: "every", every: String(opts.every) } : {
|
|
542
|
+
kind: "cron",
|
|
543
|
+
expr: String(opts.cron),
|
|
544
|
+
tz: opts.tz ? String(opts.tz) : void 0
|
|
545
|
+
};
|
|
546
|
+
const threadId = resolveScheduleThreadId(
|
|
547
|
+
opts.thread ? String(opts.thread) : void 0
|
|
548
|
+
);
|
|
549
|
+
if (String(opts.thread ?? "").trim().toLowerCase() === "self" && !threadId) {
|
|
550
|
+
throw new Error("--thread self needs SIDEBOARD_ORCHESTRATOR_THREAD_ID");
|
|
551
|
+
}
|
|
552
|
+
const agent = opts.agent ? parseAgent(String(opts.agent)) : void 0;
|
|
553
|
+
if (agent === "brightsy") {
|
|
554
|
+
throw new Error("schedules cannot use brightsy \u2014 pick claude, cursor, codex, or opencode");
|
|
555
|
+
}
|
|
556
|
+
const row = createSchedule({
|
|
557
|
+
name: opts.name,
|
|
558
|
+
prompt: String(opts.prompt),
|
|
559
|
+
when,
|
|
560
|
+
threadId,
|
|
561
|
+
agent,
|
|
562
|
+
createdBy: "cli"
|
|
563
|
+
});
|
|
564
|
+
if (!row.threadId && row.when.kind !== "once") {
|
|
565
|
+
console.log(
|
|
566
|
+
chalk.yellow(
|
|
567
|
+
"Recurring schedule has no --thread: each run opens a new orchestration chat."
|
|
568
|
+
)
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
console.log(
|
|
572
|
+
chalk.green(
|
|
573
|
+
`Scheduled ${row.id.slice(0, 8)} ${formatScheduleWhen(row.when)} next ${row.nextRunAt}`
|
|
574
|
+
)
|
|
575
|
+
);
|
|
576
|
+
console.log(chalk.dim("Fires while Sideboard.app is running on this Mac."));
|
|
577
|
+
});
|
|
578
|
+
scheduleCmd.command("enable").argument("<id>", "schedule id").action((id) => {
|
|
579
|
+
const row = updateSchedule(id, { enabled: true });
|
|
580
|
+
console.log(chalk.green(`Enabled ${row.id.slice(0, 8)}`));
|
|
581
|
+
});
|
|
582
|
+
scheduleCmd.command("disable").argument("<id>", "schedule id").action((id) => {
|
|
583
|
+
const row = updateSchedule(id, { enabled: false });
|
|
584
|
+
console.log(chalk.yellow(`Disabled ${row.id.slice(0, 8)}`));
|
|
585
|
+
});
|
|
586
|
+
scheduleCmd.command("rm").argument("<id>", "schedule id").action((id) => {
|
|
587
|
+
const row = getSchedule(id);
|
|
588
|
+
if (!row) throw new Error(`Schedule not found: ${id}`);
|
|
589
|
+
deleteSchedule(row.id);
|
|
590
|
+
console.log(chalk.yellow(`Removed ${row.id.slice(0, 8)}`));
|
|
591
|
+
});
|
|
592
|
+
scheduleCmd.command("run").argument("<id>", "schedule id").description("Fire now").action(async (id) => {
|
|
593
|
+
const row = await fireSchedule(id);
|
|
594
|
+
if (row.lastError) {
|
|
595
|
+
console.error(chalk.red(row.lastError));
|
|
596
|
+
process.exitCode = 1;
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
console.log(
|
|
600
|
+
chalk.green(
|
|
601
|
+
`Fired ${row.id.slice(0, 8)} \u2192 ${row.lastThreadId?.slice(0, 8) ?? "thread"}`
|
|
602
|
+
)
|
|
603
|
+
);
|
|
604
|
+
});
|
|
507
605
|
const brightsyCmd = program.command("brightsy").description(
|
|
508
606
|
"Brightsy team helpers (wraps `brightsy teams` + Sideboard multi-team MCP state)"
|
|
509
607
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sideboard-ai/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.107",
|
|
4
4
|
"description": "Sideboard CLI — agent-agnostic worktree orchestration (includes `sideboard mcp`)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"chalk": "^5.4.1",
|
|
17
17
|
"commander": "^13.1.0",
|
|
18
18
|
"ora": "^8.2.0",
|
|
19
|
-
"@sideboard-ai/core": "0.1.
|
|
19
|
+
"@sideboard-ai/core": "0.1.107"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^22.13.10",
|