Files
openclaw/extensions/workboard/index.ts
Peter Steinberger 0acd851a3b feat(agents): add managed git worktree lifecycle (create/provision/snapshot/restore/GC) (#100535)
Centralized managed worktrees under <state-dir>/worktrees/<repo-fingerprint>/<name>
with branch-per-task (openclaw/<name>), .worktreeinclude provisioning, an optional
.openclaw/worktree-setup.sh repo hook, and a SQLite registry in the shared state DB.
Removal always snapshots the tree (untracked included, gitignored excluded) to
refs/openclaw/snapshots/<id>; restore rebuilds the branch at the original commit with
the snapshot content as uncommitted state. Lossless run-end cleanup, 7-day idle GC for
run-owned worktrees (manual exempt), orphan reconciliation, 30-day snapshot retention.
Surfaces: worktrees.* gateway RPC (operator.admin mutations), openclaw worktrees CLI,
Control UI page, plugin-SDK facade + Workboard kind:"worktree" materialization.

E2E-verified on Testbox: full create->work->remove->restore->gc lifecycle.
2026-07-06 05:24:58 +01:00

82 lines
2.5 KiB
TypeScript

// Workboard plugin entrypoint registers its OpenClaw integration.
import { definePluginEntry } from "./api.js";
import { registerWorkboardGatewayMethods } from "./runtime-api.js";
import { registerWorkboardCommand } from "./src/command.js";
import { cleanupWorkboardRunWorktree } from "./src/dispatcher.js";
import { WorkboardStore } from "./src/store.js";
import { createWorkboardTools } from "./src/tools.js";
export default definePluginEntry({
id: "workboard",
name: "Workboard",
description: "Dashboard workboard for agent-owned issues and sessions.",
register(api) {
const store = WorkboardStore.openSqlite();
registerWorkboardGatewayMethods({ api, store });
registerWorkboardCommand({ api, store });
api.on("subagent_ended", async (event) => {
if (event.runId) {
await cleanupWorkboardRunWorktree({
store,
worktrees: api.runtime.worktrees,
runId: event.runId,
});
}
});
api.registerCli(
async ({ program }) => {
const { registerWorkboardCli } = await import("./src/cli.js");
registerWorkboardCli({ program, store });
},
{
descriptors: [
{
name: "workboard",
description: "Manage Workboard cards and worker dispatch",
hasSubcommands: true,
},
],
},
);
api.registerTool((context) => createWorkboardTools({ api, context, store }), {
names: [
"workboard_list",
"workboard_create",
"workboard_link",
"workboard_read",
"workboard_claim",
"workboard_heartbeat",
"workboard_complete",
"workboard_attachment_add",
"workboard_attachment_read",
"workboard_attachment_delete",
"workboard_block",
"workboard_boards",
"workboard_board_create",
"workboard_board_archive",
"workboard_board_delete",
"workboard_stats",
"workboard_runs",
"workboard_specify",
"workboard_decompose",
"workboard_notify_subscribe",
"workboard_notify_list",
"workboard_notify_events",
"workboard_notify_advance",
"workboard_notify_unsubscribe",
"workboard_promote",
"workboard_reassign",
"workboard_reclaim",
"workboard_dispatch",
"workboard_release",
"workboard_comment",
"workboard_proof",
"workboard_worker_log",
"workboard_protocol_violation",
"workboard_unblock",
],
optional: true,
});
},
});