terminal-agent-workboard 0.0.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.
@@ -0,0 +1,96 @@
1
+ export function runWorkboardCommand(value, context) {
2
+ const [command, ...rest] = value.slice(1).trim().split(/\s+/);
3
+ if (command === "new") {
4
+ const { agent, task } = parseNewCommand(rest, context.currentAgent, context.agents);
5
+ if (!task.trim()) {
6
+ throw new Error("Usage: /new [agent] <task>");
7
+ }
8
+ const created = context.workboard.create(agent, task);
9
+ context.setMessage(`created ${created.id}`);
10
+ return;
11
+ }
12
+ if (command === "resume") {
13
+ const [target] = rest;
14
+ if (!target)
15
+ throw new Error("Usage: /resume <history-id-prefix>");
16
+ const matches = context.history.filter((entry) => entry.id.startsWith(target) || entry.id.slice(0, 8) === target || entry.title.includes(target));
17
+ if (matches.length === 0)
18
+ throw new Error(`No history matched "${target}".`);
19
+ if (matches.length > 1) {
20
+ throw new Error(`History match is ambiguous: ${matches.slice(0, 3).map((entry) => entry.id.slice(0, 8)).join(", ")}`);
21
+ }
22
+ const restored = context.workboard.restore(matches[0]);
23
+ context.setMessage(`restored ${restored.id}`);
24
+ return;
25
+ }
26
+ if (command === "send") {
27
+ const [id, ...inputParts] = rest;
28
+ if (!id || inputParts.length === 0)
29
+ throw new Error("Usage: /send <session> <input>");
30
+ context.workboard.send(id, inputParts.join(" "));
31
+ context.setMessage(`sent to ${id}`);
32
+ return;
33
+ }
34
+ if (command === "select") {
35
+ const target = rest.join(" ");
36
+ const index = context.sessions.findIndex((session) => session.id === target || session.title === target);
37
+ if (index < 0)
38
+ throw new Error(`No session matched "${target}".`);
39
+ context.setSelected(index);
40
+ context.setMessage(`selected ${context.sessions[index]?.id ?? target}`);
41
+ return;
42
+ }
43
+ if (command === "status") {
44
+ const [id, ...statusParts] = rest;
45
+ if (!id || statusParts.length === 0)
46
+ throw new Error("Usage: /status <session> <status>");
47
+ context.workboard.setStatus(id, statusParts.join(" "));
48
+ context.setMessage(`status updated for ${id}`);
49
+ return;
50
+ }
51
+ if (command === "open") {
52
+ const session = context.sessions[context.selected];
53
+ if (session)
54
+ context.workboard.attach(session.id);
55
+ return;
56
+ }
57
+ if (command === "review") {
58
+ const [target, lineCount] = rest;
59
+ const session = target ? context.sessions.find((item) => item.id === target || item.id.startsWith(target)) : context.sessions[context.selected];
60
+ if (!session)
61
+ throw new Error(`No session matched "${target ?? ""}".`);
62
+ const lines = lineCount ? Number.parseInt(lineCount, 10) : 30;
63
+ const content = context.workboard.review(session.id, Number.isFinite(lines) ? lines : 30);
64
+ context.setReview(session.id, content);
65
+ context.setMessage(`reviewing ${session.id}`);
66
+ return;
67
+ }
68
+ if (command === "kill") {
69
+ const session = context.sessions[context.selected];
70
+ if (session) {
71
+ context.workboard.kill(session.id);
72
+ context.setMessage(`stopped ${session.id}`);
73
+ }
74
+ return;
75
+ }
76
+ if (command === "refresh") {
77
+ context.setMessage("refreshed");
78
+ return;
79
+ }
80
+ if (command === "help") {
81
+ context.setMessage("/new /history /resume /review /send /select /status /open /kill /refresh /quit");
82
+ return;
83
+ }
84
+ if (command === "quit") {
85
+ context.exit();
86
+ return;
87
+ }
88
+ throw new Error(`Unknown command "/${command}".`);
89
+ }
90
+ export function parseNewCommand(args, currentAgent, agents) {
91
+ const [first, ...rest] = args;
92
+ if (first && agents.includes(first)) {
93
+ return { agent: first, task: rest.join(" ") };
94
+ }
95
+ return { agent: currentAgent, task: args.join(" ") };
96
+ }
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "terminal-agent-workboard",
3
+ "version": "0.0.1",
4
+ "description": "A tmux-backed terminal workboard for routing input across multiple code-agent sessions (Claude Code, Codex, OpenCode, Gemini CLI).",
5
+ "type": "module",
6
+ "bin": {
7
+ "workboard": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist/**/*.js",
11
+ "!dist/**/*.test.js",
12
+ "!dist/testFixtures.js",
13
+ "README.md",
14
+ "LICENSE",
15
+ ".agent-workboard.example.json"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc -p tsconfig.json",
19
+ "dev": "tsx src/index.ts",
20
+ "start": "node dist/index.js",
21
+ "typecheck": "tsc -p tsconfig.json --noEmit",
22
+ "test": "tsx --test src/**/*.test.ts",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "keywords": [
26
+ "tmux",
27
+ "terminal",
28
+ "agent",
29
+ "claude",
30
+ "codex",
31
+ "opencode",
32
+ "gemini",
33
+ "ink",
34
+ "react",
35
+ "cli",
36
+ "workboard"
37
+ ],
38
+ "author": "Lellansin <lellansin@gmail.com>",
39
+ "license": "MIT",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/Lellansin/terminal-agent-workboard.git"
43
+ },
44
+ "bugs": {
45
+ "url": "https://github.com/Lellansin/terminal-agent-workboard/issues"
46
+ },
47
+ "homepage": "https://github.com/Lellansin/terminal-agent-workboard#readme",
48
+ "engines": {
49
+ "node": ">=20"
50
+ },
51
+ "dependencies": {
52
+ "ink": "^7.0.1",
53
+ "react": "^19.2.5"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^24.0.0",
57
+ "@types/react": "^19.2.14",
58
+ "tsx": "^4.20.0",
59
+ "typescript": "^5.8.0"
60
+ }
61
+ }