@teamclaws/teamclaw 2026.3.26-2 → 2026.4.2-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.
- package/README.md +52 -8
- package/cli.mjs +538 -224
- package/index.ts +76 -27
- package/openclaw.plugin.json +53 -28
- package/package.json +5 -2
- package/skills/teamclaw/SKILL.md +213 -0
- package/skills/teamclaw/references/api-quick-ref.md +117 -0
- package/skills/teamclaw-setup/SKILL.md +81 -0
- package/skills/teamclaw-setup/references/install-modes.md +136 -0
- package/skills/teamclaw-setup/references/validation-checklist.md +73 -0
- package/src/config.ts +44 -16
- package/src/controller/controller-capacity.ts +2 -2
- package/src/controller/controller-service.ts +193 -47
- package/src/controller/controller-tools.ts +102 -2
- package/src/controller/delivery-report.ts +563 -0
- package/src/controller/http-server.ts +1907 -172
- package/src/controller/kickoff-orchestrator.ts +292 -0
- package/src/controller/managed-gateway-process.ts +330 -0
- package/src/controller/orchestration-manifest.ts +69 -1
- package/src/controller/preview-manager.ts +676 -0
- package/src/controller/prompt-injector.ts +116 -67
- package/src/controller/role-inference.ts +41 -0
- package/src/controller/websocket.ts +3 -1
- package/src/controller/worker-provisioning.ts +429 -74
- package/src/discovery.ts +1 -1
- package/src/git-collaboration.ts +198 -47
- package/src/identity.ts +12 -2
- package/src/interaction-contracts.ts +179 -3
- package/src/networking.ts +99 -0
- package/src/openclaw-workspace.ts +478 -11
- package/src/prompt-policy.ts +381 -0
- package/src/roles.ts +37 -36
- package/src/state.ts +40 -1
- package/src/task-executor.ts +282 -78
- package/src/types.ts +150 -7
- package/src/ui/app.js +1403 -175
- package/src/ui/assets/teamclaw-app-icon.png +0 -0
- package/src/ui/index.html +122 -40
- package/src/ui/style.css +829 -143
- package/src/worker/http-handler.ts +40 -4
- package/src/worker/prompt-injector.ts +9 -38
- package/src/worker/skill-installer.ts +2 -2
- package/src/worker/tools.ts +31 -5
- package/src/worker/worker-service.ts +49 -8
- package/src/workspace-browser.ts +20 -7
- package/src/controller/local-worker-manager.ts +0 -533
package/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
1
3
|
import { definePluginEntry, type OpenClawPluginApi } from "./api.js";
|
|
2
4
|
import { parsePluginConfig } from "./src/types.js";
|
|
3
5
|
import type { TaskAssignmentPayload, TaskExecutionEventInput, TeamState, WorkerIdentity } from "./src/types.js";
|
|
@@ -9,10 +11,10 @@ import { createWorkerPromptInjector } from "./src/worker/prompt-injector.js";
|
|
|
9
11
|
import { createWorkerTools } from "./src/worker/tools.js";
|
|
10
12
|
import { MessageQueue } from "./src/worker/message-queue.js";
|
|
11
13
|
import { createControllerService } from "./src/controller/controller-service.js";
|
|
12
|
-
import { LocalWorkerManager } from "./src/controller/local-worker-manager.js";
|
|
13
14
|
import { createControllerPromptInjector } from "./src/controller/prompt-injector.js";
|
|
14
15
|
import { createControllerTools } from "./src/controller/controller-tools.js";
|
|
15
16
|
import { publishWorkerRepo, syncWorkerRepo } from "./src/git-collaboration.js";
|
|
17
|
+
import { resolveTeamClawProjectsDir } from "./src/openclaw-workspace.js";
|
|
16
18
|
import { installRecommendedSkills } from "./src/worker/skill-installer.js";
|
|
17
19
|
|
|
18
20
|
export default definePluginEntry({
|
|
@@ -34,37 +36,29 @@ export default definePluginEntry({
|
|
|
34
36
|
|
|
35
37
|
function registerController(api: OpenClawPluginApi, config: ReturnType<typeof parsePluginConfig>) {
|
|
36
38
|
const logger = api.logger;
|
|
37
|
-
const localWorkerManager = new LocalWorkerManager({
|
|
38
|
-
config,
|
|
39
|
-
logger,
|
|
40
|
-
runtime: api.runtime,
|
|
41
|
-
});
|
|
42
39
|
let getControllerTeamState = (): TeamState | null => null;
|
|
40
|
+
let controllerUrl = `http://127.0.0.1:${config.port}`;
|
|
41
|
+
let kickoffHandler: ((candidateRoles: import("./src/types.js").RoleId[], complexity: "simple" | "medium" | "complex", requirement: string) => Promise<{ assessments: import("./src/types.js").KickoffAssessment[]; summary: string }>) | undefined;
|
|
43
42
|
|
|
44
43
|
// Service (starts HTTP server + mDNS + WebSocket)
|
|
45
44
|
api.registerService(createControllerService({
|
|
46
45
|
config,
|
|
47
46
|
logger,
|
|
48
47
|
runtime: api.runtime,
|
|
49
|
-
localWorkerManager,
|
|
50
48
|
onTeamStateAvailable: (getter) => {
|
|
51
49
|
getControllerTeamState = getter;
|
|
52
50
|
},
|
|
51
|
+
onActualPort: (port) => {
|
|
52
|
+
controllerUrl = `http://127.0.0.1:${port}`;
|
|
53
|
+
},
|
|
54
|
+
onKickoffHandlerAvailable: (handler) => {
|
|
55
|
+
kickoffHandler = handler;
|
|
56
|
+
logger.info("TeamClaw: kickoff handler registered successfully");
|
|
57
|
+
},
|
|
53
58
|
}));
|
|
54
59
|
|
|
55
60
|
// Prompt injection
|
|
56
61
|
api.on("before_prompt_build", async (_event: unknown, ctx: { sessionKey?: string | null }) => {
|
|
57
|
-
const localIdentity = localWorkerManager.getIdentityForSession(ctx.sessionKey);
|
|
58
|
-
const localMessageQueue = localWorkerManager.getMessageQueueForSession(ctx.sessionKey);
|
|
59
|
-
if (localIdentity && localMessageQueue) {
|
|
60
|
-
const injector = createWorkerPromptInjector(
|
|
61
|
-
{ ...config, role: localIdentity.role },
|
|
62
|
-
() => localIdentity,
|
|
63
|
-
localMessageQueue,
|
|
64
|
-
);
|
|
65
|
-
return injector() ?? {};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
62
|
const state = getControllerTeamState() ?? await loadTeamState(config.teamName);
|
|
69
63
|
const injector = createControllerPromptInjector({
|
|
70
64
|
config,
|
|
@@ -74,21 +68,13 @@ function registerController(api: OpenClawPluginApi, config: ReturnType<typeof pa
|
|
|
74
68
|
});
|
|
75
69
|
|
|
76
70
|
// Tools - register all controller tools via factory returning an array
|
|
77
|
-
const controllerUrl = `http://localhost:${config.port}`;
|
|
78
71
|
api.registerTool((ctx: { sessionKey?: string | null }) => {
|
|
79
|
-
const localIdentity = localWorkerManager.getIdentityForSession(ctx.sessionKey);
|
|
80
|
-
if (localIdentity) {
|
|
81
|
-
return createWorkerTools({
|
|
82
|
-
config: { ...config, role: localIdentity.role },
|
|
83
|
-
getIdentity: () => localIdentity,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
72
|
return createControllerTools({
|
|
88
73
|
config,
|
|
89
74
|
controllerUrl,
|
|
90
75
|
getTeamState: getControllerTeamState,
|
|
91
76
|
sessionKey: ctx.sessionKey ?? null,
|
|
77
|
+
getKickoffHandler: () => kickoffHandler,
|
|
92
78
|
});
|
|
93
79
|
});
|
|
94
80
|
}
|
|
@@ -146,6 +132,41 @@ function registerWorker(api: OpenClawPluginApi, config: ReturnType<typeof parseP
|
|
|
146
132
|
reportExecutionEvent,
|
|
147
133
|
});
|
|
148
134
|
|
|
135
|
+
function resolveProjectSyncPaths(projectDir: string | undefined): { sharedProjectDir: string; localProjectDir: string } | null {
|
|
136
|
+
const normalizedProjectDir = projectDir?.trim();
|
|
137
|
+
const sharedWorkspaceOverride = process.env.TEAMCLAW_WORKSPACE_DIR?.trim();
|
|
138
|
+
if (!normalizedProjectDir || !sharedWorkspaceOverride) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const sharedProjectDir = path.join(resolveTeamClawProjectsDir(), normalizedProjectDir);
|
|
143
|
+
const localEnv = { ...process.env };
|
|
144
|
+
delete localEnv.TEAMCLAW_WORKSPACE_DIR;
|
|
145
|
+
const localProjectDir = path.join(resolveTeamClawProjectsDir(localEnv), normalizedProjectDir);
|
|
146
|
+
if (sharedProjectDir === localProjectDir) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return { sharedProjectDir, localProjectDir };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function pathExists(targetPath: string): Promise<boolean> {
|
|
153
|
+
try {
|
|
154
|
+
await fs.access(targetPath);
|
|
155
|
+
return true;
|
|
156
|
+
} catch {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function syncProjectDir(sourceDir: string, destinationDir: string): Promise<boolean> {
|
|
162
|
+
if (!await pathExists(sourceDir)) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
await fs.mkdir(path.dirname(destinationDir), { recursive: true });
|
|
166
|
+
await fs.cp(sourceDir, destinationDir, { recursive: true, force: true });
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
|
|
149
170
|
// Service
|
|
150
171
|
api.registerService(
|
|
151
172
|
createWorkerService({
|
|
@@ -176,6 +197,20 @@ function registerWorker(api: OpenClawPluginApi, config: ReturnType<typeof parseP
|
|
|
176
197
|
}
|
|
177
198
|
}
|
|
178
199
|
|
|
200
|
+
const syncPaths = resolveProjectSyncPaths(assignment.projectDir);
|
|
201
|
+
if (syncPaths) {
|
|
202
|
+
const restored = await syncProjectDir(syncPaths.sharedProjectDir, syncPaths.localProjectDir);
|
|
203
|
+
if (restored) {
|
|
204
|
+
await reportExecutionEvent(assignment.taskId, {
|
|
205
|
+
type: "lifecycle",
|
|
206
|
+
phase: "project_sync_restored",
|
|
207
|
+
source: "worker",
|
|
208
|
+
status: "running",
|
|
209
|
+
message: `Restored shared project files into the worker runtime from ${syncPaths.sharedProjectDir}.`,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
179
214
|
if (!assignment.repo?.enabled || !controllerUrl) {
|
|
180
215
|
return;
|
|
181
216
|
}
|
|
@@ -210,6 +245,20 @@ function registerWorker(api: OpenClawPluginApi, config: ReturnType<typeof parseP
|
|
|
210
245
|
}
|
|
211
246
|
},
|
|
212
247
|
publishTaskAssignment: async (assignment) => {
|
|
248
|
+
const syncPaths = resolveProjectSyncPaths(assignment.projectDir);
|
|
249
|
+
if (syncPaths) {
|
|
250
|
+
const published = await syncProjectDir(syncPaths.localProjectDir, syncPaths.sharedProjectDir);
|
|
251
|
+
if (published) {
|
|
252
|
+
await reportExecutionEvent(assignment.taskId, {
|
|
253
|
+
type: "lifecycle",
|
|
254
|
+
phase: "project_sync_published",
|
|
255
|
+
source: "worker",
|
|
256
|
+
status: "running",
|
|
257
|
+
message: `Published worker runtime project files back to the shared workspace at ${syncPaths.sharedProjectDir}.`,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
213
262
|
const controllerUrl = currentControllerUrl || config.controllerUrl.trim();
|
|
214
263
|
if (!assignment.repo?.enabled || !controllerUrl) {
|
|
215
264
|
return;
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
"id": "teamclaw",
|
|
3
3
|
"name": "TeamClaw",
|
|
4
4
|
"description": "Virtual team collaboration - multiple OpenClaw instances form a virtual software company with role-based task routing.",
|
|
5
|
-
"version": "2026.
|
|
5
|
+
"version": "2026.4.2-1",
|
|
6
|
+
"skills": [
|
|
7
|
+
"./skills"
|
|
8
|
+
],
|
|
6
9
|
"uiHints": {
|
|
7
10
|
"mode": {
|
|
8
11
|
"label": "Mode",
|
|
@@ -29,8 +32,8 @@
|
|
|
29
32
|
"help": "In milliseconds, minimum 1000"
|
|
30
33
|
},
|
|
31
34
|
"taskTimeoutMs": {
|
|
32
|
-
"label": "Task
|
|
33
|
-
"help": "
|
|
35
|
+
"label": "Task Stall Threshold",
|
|
36
|
+
"help": "In milliseconds, how long TeamClaw waits without visible progress before probing the task instead of failing it"
|
|
34
37
|
},
|
|
35
38
|
"gitEnabled": {
|
|
36
39
|
"label": "Git Collaboration",
|
|
@@ -52,14 +55,22 @@
|
|
|
52
55
|
"label": "Git Author Email",
|
|
53
56
|
"help": "Author email for TeamClaw-managed workspace commits"
|
|
54
57
|
},
|
|
55
|
-
"
|
|
56
|
-
"label": "
|
|
57
|
-
"help": "
|
|
58
|
+
"agentIsolationMode": {
|
|
59
|
+
"label": "Agent Isolation Mode",
|
|
60
|
+
"help": "Use a dedicated TeamClaw agent/workspace by default, or the legacy shared main-agent mode"
|
|
61
|
+
},
|
|
62
|
+
"processModel": {
|
|
63
|
+
"label": "Process Model",
|
|
64
|
+
"help": "TeamClaw runs workers as separate gateway processes"
|
|
58
65
|
},
|
|
59
66
|
"workerProvisioningType": {
|
|
60
67
|
"label": "On-demand Worker Provider",
|
|
61
68
|
"help": "Launch missing workers on demand using process, Docker, or Kubernetes"
|
|
62
69
|
},
|
|
70
|
+
"workerProvisioningDisabled": {
|
|
71
|
+
"label": "Disable On-demand Workers",
|
|
72
|
+
"help": "Force TeamClaw to keep worker provisioning off even for same-host local controllers"
|
|
73
|
+
},
|
|
63
74
|
"workerProvisioningControllerUrl": {
|
|
64
75
|
"label": "Provisioned Worker Controller URL",
|
|
65
76
|
"help": "URL that launched workers use to call back into the controller"
|
|
@@ -124,6 +135,10 @@
|
|
|
124
135
|
"label": "Kubernetes Service Account",
|
|
125
136
|
"help": "Optional service account for launched worker pods"
|
|
126
137
|
},
|
|
138
|
+
"workerProvisioningKubernetesImagePullSecrets": {
|
|
139
|
+
"label": "Kubernetes Image Pull Secrets",
|
|
140
|
+
"help": "Optional secret names added to launched worker pods so they can pull private images"
|
|
141
|
+
},
|
|
127
142
|
"workerProvisioningKubernetesWorkspacePersistentVolumeClaim": {
|
|
128
143
|
"label": "Kubernetes Workspace PVC",
|
|
129
144
|
"help": "Optional PVC mounted as the persistent workspace root for launched worker pods"
|
|
@@ -166,7 +181,7 @@
|
|
|
166
181
|
},
|
|
167
182
|
"teamName": {
|
|
168
183
|
"type": "string",
|
|
169
|
-
"default": "
|
|
184
|
+
"default": "TeamClaw",
|
|
170
185
|
"description": "Team name for mDNS identification"
|
|
171
186
|
},
|
|
172
187
|
"heartbeatIntervalMs": {
|
|
@@ -177,7 +192,7 @@
|
|
|
177
192
|
"taskTimeoutMs": {
|
|
178
193
|
"type": "number",
|
|
179
194
|
"default": 1800000,
|
|
180
|
-
"description": "
|
|
195
|
+
"description": "Inactivity threshold in milliseconds before TeamClaw probes a stalled role task instead of failing it"
|
|
181
196
|
},
|
|
182
197
|
"gitEnabled": {
|
|
183
198
|
"type": "boolean",
|
|
@@ -204,25 +219,22 @@
|
|
|
204
219
|
"default": "teamclaw@local",
|
|
205
220
|
"description": "Git author email used for TeamClaw-managed workspace commits"
|
|
206
221
|
},
|
|
207
|
-
"
|
|
208
|
-
"type": "
|
|
209
|
-
"
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"marketing"
|
|
224
|
-
]
|
|
225
|
-
}
|
|
222
|
+
"agentIsolationMode": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"enum": [
|
|
225
|
+
"independent",
|
|
226
|
+
"main"
|
|
227
|
+
],
|
|
228
|
+
"default": "independent",
|
|
229
|
+
"description": "Runtime isolation mode: dedicated TeamClaw agent/workspace, or legacy main-agent shared mode"
|
|
230
|
+
},
|
|
231
|
+
"processModel": {
|
|
232
|
+
"type": "string",
|
|
233
|
+
"enum": [
|
|
234
|
+
"multi"
|
|
235
|
+
],
|
|
236
|
+
"default": "multi",
|
|
237
|
+
"description": "Worker execution model: TeamClaw runs workers as separate gateway processes"
|
|
226
238
|
},
|
|
227
239
|
"workerProvisioningType": {
|
|
228
240
|
"type": "string",
|
|
@@ -235,6 +247,11 @@
|
|
|
235
247
|
"default": "none",
|
|
236
248
|
"description": "Controller-only on-demand worker launch backend"
|
|
237
249
|
},
|
|
250
|
+
"workerProvisioningDisabled": {
|
|
251
|
+
"type": "boolean",
|
|
252
|
+
"default": false,
|
|
253
|
+
"description": "Explicitly disable controller-managed on-demand workers even when TeamClaw would normally default to same-host process provisioning"
|
|
254
|
+
},
|
|
238
255
|
"workerProvisioningControllerUrl": {
|
|
239
256
|
"type": "string",
|
|
240
257
|
"default": "",
|
|
@@ -267,7 +284,7 @@
|
|
|
267
284
|
},
|
|
268
285
|
"workerProvisioningMaxPerRole": {
|
|
269
286
|
"type": "number",
|
|
270
|
-
"default":
|
|
287
|
+
"default": 3,
|
|
271
288
|
"description": "Maximum on-demand workers to launch per role"
|
|
272
289
|
},
|
|
273
290
|
"workerProvisioningIdleTtlMs": {
|
|
@@ -339,6 +356,14 @@
|
|
|
339
356
|
"default": "",
|
|
340
357
|
"description": "Optional service account name for launched worker pods"
|
|
341
358
|
},
|
|
359
|
+
"workerProvisioningKubernetesImagePullSecrets": {
|
|
360
|
+
"type": "array",
|
|
361
|
+
"default": [],
|
|
362
|
+
"description": "Optional image pull secret names added to launched worker pods",
|
|
363
|
+
"items": {
|
|
364
|
+
"type": "string"
|
|
365
|
+
}
|
|
366
|
+
},
|
|
342
367
|
"workerProvisioningKubernetesWorkspacePersistentVolumeClaim": {
|
|
343
368
|
"type": "string",
|
|
344
369
|
"default": "",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamclaws/teamclaw",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.4.2-1",
|
|
4
4
|
"description": "OpenClaw virtual software team orchestration plugin",
|
|
5
5
|
"private": false,
|
|
6
6
|
"keywords": [
|
|
@@ -36,12 +36,15 @@
|
|
|
36
36
|
"cli.mjs",
|
|
37
37
|
"index.ts",
|
|
38
38
|
"openclaw.plugin.json",
|
|
39
|
+
"skills/",
|
|
39
40
|
"src/",
|
|
40
41
|
"tsconfig.json"
|
|
41
42
|
],
|
|
42
43
|
"scripts": {
|
|
44
|
+
"manifest:sync": "cd .. && node scripts/sync-teamclaw-plugin-manifest.mjs src",
|
|
43
45
|
"pack:dry-run": "npm pack --dry-run --json --ignore-scripts",
|
|
44
|
-
"release:check": "node
|
|
46
|
+
"release:check": "cd .. && node scripts/teamclaw-package-check.mjs src",
|
|
47
|
+
"release:clawhub:dry-run": "cd .. && bash scripts/teamclaw-clawhub-release.sh --dry-run"
|
|
45
48
|
},
|
|
46
49
|
"dependencies": {
|
|
47
50
|
"@sinclair/typebox": "0.34.48",
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: teamclaw
|
|
3
|
+
description: >
|
|
4
|
+
Orchestrate a virtual AI software team to build features, fix bugs, or complete any software task.
|
|
5
|
+
Use when the user wants to delegate work to a multi-role team (developer, architect, QA, etc.),
|
|
6
|
+
check team progress, review task results, or answer worker clarifications.
|
|
7
|
+
Triggers: "build me ...", "create a ...", "team status", "assign to team", "teamclaw",
|
|
8
|
+
"have the team ...", "delegate this to ...", "what are the workers doing".
|
|
9
|
+
version: 1.0.0
|
|
10
|
+
metadata:
|
|
11
|
+
openclaw:
|
|
12
|
+
author: TeamClaws
|
|
13
|
+
homepage: https://github.com/topcheer/teamclaw
|
|
14
|
+
links:
|
|
15
|
+
homepage: https://github.com/topcheer/teamclaw
|
|
16
|
+
repository: https://github.com/topcheer/teamclaw
|
|
17
|
+
documentation: https://github.com/topcheer/teamclaw/blob/main/README.md
|
|
18
|
+
changelog: https://github.com/topcheer/teamclaw/releases
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# TeamClaw — AI Team Orchestration
|
|
22
|
+
|
|
23
|
+
Orchestrate a virtual software team through natural conversation. Submit requirements, monitor progress, review deliverables, and answer clarifications — all without leaving your chat.
|
|
24
|
+
|
|
25
|
+
## When to Use This Skill
|
|
26
|
+
|
|
27
|
+
Activate when the user:
|
|
28
|
+
|
|
29
|
+
- Wants to **build, create, or implement** something (e.g., "build me a todo app", "create an auth system")
|
|
30
|
+
- Asks to **delegate work** to a team (e.g., "have the team work on this", "assign this to the developer")
|
|
31
|
+
- Wants to check **team status** (e.g., "what are the workers doing?", "show me task progress")
|
|
32
|
+
- Needs to **review results** (e.g., "show me what the developer built", "check the QA report")
|
|
33
|
+
- Has **pending clarifications** to answer (e.g., "are there questions from the team?")
|
|
34
|
+
- Mentions **teamclaw** by name
|
|
35
|
+
|
|
36
|
+
## Prerequisites
|
|
37
|
+
|
|
38
|
+
TeamClaw must be running in controller mode. Detect the controller URL:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Default controller URL
|
|
42
|
+
TEAMCLAW_URL="http://127.0.0.1:9527"
|
|
43
|
+
|
|
44
|
+
# Health check — verify the controller is running
|
|
45
|
+
curl -sf "$TEAMCLAW_URL/api/v1/health"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If the health check fails, tell the user to start TeamClaw first (install the `teamclaw-setup` skill for guidance).
|
|
49
|
+
|
|
50
|
+
## Core Workflow
|
|
51
|
+
|
|
52
|
+
### 1. Submit a Requirement
|
|
53
|
+
|
|
54
|
+
When the user describes what they want built, submit it to the controller intake:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
curl -s -X POST "$TEAMCLAW_URL/api/v1/controller/intake" \
|
|
58
|
+
-H "Content-Type: application/json" \
|
|
59
|
+
-d '{"message": "<user requirement here>"}'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The controller will:
|
|
63
|
+
1. Analyze the requirement
|
|
64
|
+
2. Decompose it into tasks for appropriate roles (developer, architect, QA, etc.)
|
|
65
|
+
3. Assign tasks to available workers
|
|
66
|
+
4. Return a controller run with tracking info
|
|
67
|
+
|
|
68
|
+
**Response fields:**
|
|
69
|
+
- `controllerRun.id` — run identifier for tracking
|
|
70
|
+
- `controllerRun.status` — `running`, `completed`, `failed`
|
|
71
|
+
- `result` — the controller agent's orchestration output
|
|
72
|
+
|
|
73
|
+
**Important:** The intake call may take 30-180 seconds as the controller agent plans and decomposes the work. Use `--max-time 300` with curl for large requirements.
|
|
74
|
+
|
|
75
|
+
### 2. Monitor Progress
|
|
76
|
+
|
|
77
|
+
#### Check team overview
|
|
78
|
+
```bash
|
|
79
|
+
curl -s "$TEAMCLAW_URL/api/v1/team/status"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Key response fields:
|
|
83
|
+
- `workers` — map of all workers with their status (`idle`, `busy`, `offline`)
|
|
84
|
+
- `tasks` — map of all tasks with status (`pending`, `assigned`, `in-progress`, `completed`, `failed`)
|
|
85
|
+
- `pendingClarificationCount` — number of unanswered questions from workers
|
|
86
|
+
- `controllerRuns` — orchestration run history
|
|
87
|
+
|
|
88
|
+
#### List tasks
|
|
89
|
+
```bash
|
|
90
|
+
curl -s "$TEAMCLAW_URL/api/v1/tasks"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Get task details with execution history
|
|
94
|
+
```bash
|
|
95
|
+
curl -s "$TEAMCLAW_URL/api/v1/tasks/<taskId>/execution"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Returns the task with full execution log (lifecycle events, progress updates, errors).
|
|
99
|
+
|
|
100
|
+
#### List workers
|
|
101
|
+
```bash
|
|
102
|
+
curl -s "$TEAMCLAW_URL/api/v1/workers"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 3. Review Results
|
|
106
|
+
|
|
107
|
+
When a task completes, its result contract contains structured deliverables:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Get the task to see its resultContract
|
|
111
|
+
curl -s "$TEAMCLAW_URL/api/v1/tasks/<taskId>"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The `resultContract` includes:
|
|
115
|
+
- `summary` — what was accomplished
|
|
116
|
+
- `deliverables[]` — list of files, notes, or artifacts produced
|
|
117
|
+
- `discoveredPatterns[]` — patterns noticed during execution
|
|
118
|
+
- `suggestedNextSteps[]` — recommended follow-up actions
|
|
119
|
+
|
|
120
|
+
### 4. Handle Clarifications
|
|
121
|
+
|
|
122
|
+
Workers may need clarification to proceed. Check and answer them:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# List pending clarifications
|
|
126
|
+
curl -s "$TEAMCLAW_URL/api/v1/clarifications"
|
|
127
|
+
|
|
128
|
+
# Answer a clarification
|
|
129
|
+
curl -s -X POST "$TEAMCLAW_URL/api/v1/clarifications/<clarificationId>/answer" \
|
|
130
|
+
-H "Content-Type: application/json" \
|
|
131
|
+
-d '{"answer": "<your answer>", "answeredBy": "user"}'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 5. Create Individual Tasks
|
|
135
|
+
|
|
136
|
+
For fine-grained control, create tasks directly:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
curl -s -X POST "$TEAMCLAW_URL/api/v1/tasks" \
|
|
140
|
+
-H "Content-Type: application/json" \
|
|
141
|
+
-d '{
|
|
142
|
+
"title": "Implement user login",
|
|
143
|
+
"description": "Create a login form with email/password auth",
|
|
144
|
+
"priority": "high",
|
|
145
|
+
"assignedRole": "developer"
|
|
146
|
+
}'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Valid roles: `pm`, `architect`, `developer`, `qa`, `release-engineer`, `infra-engineer`, `devops`, `security-engineer`, `designer`, `marketing`.
|
|
150
|
+
|
|
151
|
+
Valid priorities: `low`, `medium`, `high`.
|
|
152
|
+
|
|
153
|
+
### 6. Send Messages to the Team
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Direct message to a role
|
|
157
|
+
curl -s -X POST "$TEAMCLAW_URL/api/v1/messages/direct" \
|
|
158
|
+
-H "Content-Type: application/json" \
|
|
159
|
+
-d '{
|
|
160
|
+
"from": "user",
|
|
161
|
+
"toRole": "developer",
|
|
162
|
+
"content": "Please also add input validation"
|
|
163
|
+
}'
|
|
164
|
+
|
|
165
|
+
# Broadcast to all workers
|
|
166
|
+
curl -s -X POST "$TEAMCLAW_URL/api/v1/messages/broadcast" \
|
|
167
|
+
-H "Content-Type: application/json" \
|
|
168
|
+
-d '{
|
|
169
|
+
"from": "user",
|
|
170
|
+
"content": "Deadline moved up — prioritize core features"
|
|
171
|
+
}'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Response Presentation
|
|
175
|
+
|
|
176
|
+
When presenting results to the user:
|
|
177
|
+
|
|
178
|
+
1. **After intake submission**: Summarize what the controller planned — how many tasks, which roles assigned, estimated workflow.
|
|
179
|
+
|
|
180
|
+
2. **For status checks**: Show a concise table of workers and tasks:
|
|
181
|
+
```
|
|
182
|
+
Workers: 3 active (developer: busy, qa: idle, architect: idle)
|
|
183
|
+
Tasks: 5 total (2 completed, 1 in-progress, 2 pending)
|
|
184
|
+
Clarifications: 1 pending
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
3. **For completed tasks**: Highlight the deliverables, key files changed, and suggested next steps.
|
|
188
|
+
|
|
189
|
+
4. **For clarifications**: Present the question clearly and ask the user to provide an answer.
|
|
190
|
+
|
|
191
|
+
## Web UI
|
|
192
|
+
|
|
193
|
+
TeamClaw also provides a web dashboard for visual monitoring:
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
Open in browser: $TEAMCLAW_URL/ui
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Mention this to users who prefer a visual overview.
|
|
200
|
+
|
|
201
|
+
## Troubleshooting
|
|
202
|
+
|
|
203
|
+
| Issue | Solution |
|
|
204
|
+
|-------|----------|
|
|
205
|
+
| Health check fails | Ensure TeamClaw plugin is enabled in controller mode: `openclaw plugins list` |
|
|
206
|
+
| No workers available | Check processModel config; single-process creates workers automatically |
|
|
207
|
+
| Intake times out | Increase `taskTimeoutMs` in TeamClaw config; ensure AI model is responsive |
|
|
208
|
+
| Task stuck in pending | No idle worker for the assigned role; check `GET /api/v1/workers` |
|
|
209
|
+
| Clarification blocking | Answer pending clarifications via `POST /api/v1/clarifications/:id/answer` |
|
|
210
|
+
|
|
211
|
+
## Read references for detailed API docs
|
|
212
|
+
|
|
213
|
+
Read `references/api-quick-ref.md` for the complete endpoint reference when you need exact request/response formats.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# TeamClaw API Quick Reference
|
|
2
|
+
|
|
3
|
+
## Controller URL
|
|
4
|
+
|
|
5
|
+
Default: `http://127.0.0.1:9527`
|
|
6
|
+
|
|
7
|
+
## Endpoints
|
|
8
|
+
|
|
9
|
+
### Health & Status
|
|
10
|
+
|
|
11
|
+
| Method | Path | Description |
|
|
12
|
+
|--------|------|-------------|
|
|
13
|
+
| GET | `/api/v1/health` | Health check → `{"status":"ok"}` |
|
|
14
|
+
| GET | `/api/v1/team/status` | Full team snapshot (workers, tasks, runs, clarifications) |
|
|
15
|
+
| GET | `/api/v1/roles` | List all available roles |
|
|
16
|
+
|
|
17
|
+
### Controller Orchestration
|
|
18
|
+
|
|
19
|
+
| Method | Path | Description |
|
|
20
|
+
|--------|------|-------------|
|
|
21
|
+
| POST | `/api/v1/controller/intake` | Submit requirement → auto-decompose into tasks |
|
|
22
|
+
| GET | `/api/v1/controller/runs` | List orchestration runs |
|
|
23
|
+
|
|
24
|
+
**Intake request:**
|
|
25
|
+
```json
|
|
26
|
+
{ "message": "Build a REST API for user management" }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Intake response:**
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"controllerRun": { "id": "run-abc", "status": "completed", "source": "intake" },
|
|
33
|
+
"result": "Orchestration output text..."
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Tasks
|
|
38
|
+
|
|
39
|
+
| Method | Path | Description |
|
|
40
|
+
|--------|------|-------------|
|
|
41
|
+
| POST | `/api/v1/tasks` | Create task |
|
|
42
|
+
| GET | `/api/v1/tasks` | List all tasks |
|
|
43
|
+
| GET | `/api/v1/tasks/:id` | Get task detail |
|
|
44
|
+
| GET | `/api/v1/tasks/:id/execution` | Get task with execution events |
|
|
45
|
+
| PATCH | `/api/v1/tasks/:id` | Update task (status, priority, progress) |
|
|
46
|
+
| POST | `/api/v1/tasks/:id/assign` | Assign to worker/role |
|
|
47
|
+
| POST | `/api/v1/tasks/:id/handoff` | Hand off to another role |
|
|
48
|
+
| POST | `/api/v1/tasks/:id/result` | Submit result |
|
|
49
|
+
|
|
50
|
+
**Create task:**
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"title": "Implement login form",
|
|
54
|
+
"description": "Email/password login with validation",
|
|
55
|
+
"priority": "high",
|
|
56
|
+
"assignedRole": "developer"
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Task statuses:** `pending` → `assigned` → `in-progress` → `completed` | `failed` | `blocked`
|
|
61
|
+
|
|
62
|
+
**Priorities:** `low`, `medium`, `high`
|
|
63
|
+
|
|
64
|
+
**Roles:** `pm`, `architect`, `developer`, `qa`, `release-engineer`, `infra-engineer`, `devops`, `security-engineer`, `designer`, `marketing`
|
|
65
|
+
|
|
66
|
+
### Workers
|
|
67
|
+
|
|
68
|
+
| Method | Path | Description |
|
|
69
|
+
|--------|------|-------------|
|
|
70
|
+
| GET | `/api/v1/workers` | List workers |
|
|
71
|
+
| POST | `/api/v1/workers/register` | Register worker |
|
|
72
|
+
| POST | `/api/v1/workers/:id/heartbeat` | Heartbeat |
|
|
73
|
+
| DELETE | `/api/v1/workers/:id` | Remove worker |
|
|
74
|
+
|
|
75
|
+
**Worker statuses:** `idle`, `busy`, `offline`
|
|
76
|
+
|
|
77
|
+
**Transport types:** `http` (external or dynamically provisioned worker callback)
|
|
78
|
+
|
|
79
|
+
### Messages
|
|
80
|
+
|
|
81
|
+
| Method | Path | Description |
|
|
82
|
+
|--------|------|-------------|
|
|
83
|
+
| POST | `/api/v1/messages/direct` | Send to specific role |
|
|
84
|
+
| POST | `/api/v1/messages/broadcast` | Send to all workers |
|
|
85
|
+
| POST | `/api/v1/messages/review-request` | Request review from role |
|
|
86
|
+
| GET | `/api/v1/messages` | List messages (query: `limit`, `offset`) |
|
|
87
|
+
|
|
88
|
+
**Direct message:**
|
|
89
|
+
```json
|
|
90
|
+
{ "from": "user", "toRole": "developer", "content": "Add input validation" }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Clarifications
|
|
94
|
+
|
|
95
|
+
| Method | Path | Description |
|
|
96
|
+
|--------|------|-------------|
|
|
97
|
+
| GET | `/api/v1/clarifications` | List all (includes `pendingCount`) |
|
|
98
|
+
| POST | `/api/v1/clarifications` | Request clarification |
|
|
99
|
+
| POST | `/api/v1/clarifications/:id/answer` | Answer clarification |
|
|
100
|
+
|
|
101
|
+
**Answer:**
|
|
102
|
+
```json
|
|
103
|
+
{ "answer": "Use PostgreSQL for the database", "answeredBy": "user" }
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Workspace
|
|
107
|
+
|
|
108
|
+
| Method | Path | Description |
|
|
109
|
+
|--------|------|-------------|
|
|
110
|
+
| GET | `/api/v1/workspace/tree` | Directory tree |
|
|
111
|
+
| GET | `/api/v1/workspace/file?path=<path>` | File content |
|
|
112
|
+
|
|
113
|
+
### Web UI
|
|
114
|
+
|
|
115
|
+
| Path | Description |
|
|
116
|
+
|------|-------------|
|
|
117
|
+
| `/ui` | TeamClaw dashboard |
|