teamclaws 1.0.0
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/LICENSE +167 -0
- package/README.md +107 -0
- package/dist/app.js +327 -0
- package/dist/app.js.map +1 -0
- package/dist/auth.js +330 -0
- package/dist/auth.js.map +1 -0
- package/dist/broker.js +79 -0
- package/dist/broker.js.map +1 -0
- package/dist/browser.js +33 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.js +21 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/external-chat.js +570 -0
- package/dist/external-chat.js.map +1 -0
- package/dist/http.js +107 -0
- package/dist/http.js.map +1 -0
- package/dist/output.js +298 -0
- package/dist/output.js.map +1 -0
- package/dist/pairing.js +245 -0
- package/dist/pairing.js.map +1 -0
- package/dist/storage.js +324 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.js +458 -0
- package/dist/validation.js.map +1 -0
- package/package.json +42 -0
- package/skills/teamclaws-chat/SKILL.md +65 -0
- package/skills/teamclaws-login/SKILL.md +29 -0
- package/skills/teamclaws-pair/SKILL.md +77 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
import { TeamClawsError } from "./errors.js";
|
|
3
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4
|
+
export function isObject(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
export function assertExactKeys(value, required, optional = [], label = "response") {
|
|
8
|
+
const allowed = new Set([...required, ...optional]);
|
|
9
|
+
for (const key of Object.keys(value)) {
|
|
10
|
+
if (!allowed.has(key)) {
|
|
11
|
+
throw new TeamClawsError("invalid_response", `TeamClaws returned an invalid ${label}.`, { exitCode: 9 });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
for (const key of required) {
|
|
15
|
+
if (!(key in value)) {
|
|
16
|
+
throw new TeamClawsError("invalid_response", `TeamClaws returned an incomplete ${label}.`, { exitCode: 9 });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function requireString(value, label, maxLength = 2_048) {
|
|
21
|
+
if (typeof value !== "string" ||
|
|
22
|
+
value.length === 0 ||
|
|
23
|
+
value.length > maxLength) {
|
|
24
|
+
throw new TeamClawsError("invalid_response", `TeamClaws returned an invalid ${label}.`, {
|
|
25
|
+
exitCode: 9,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
export function requireInteger(value, label, minimum, maximum) {
|
|
31
|
+
if (!Number.isInteger(value) ||
|
|
32
|
+
Number(value) < minimum ||
|
|
33
|
+
Number(value) > maximum) {
|
|
34
|
+
throw new TeamClawsError("invalid_response", `TeamClaws returned an invalid ${label}.`, {
|
|
35
|
+
exitCode: 9,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return Number(value);
|
|
39
|
+
}
|
|
40
|
+
export function normalizeUuid(value, label = "server identifier") {
|
|
41
|
+
const normalized = requireString(value, label, 36).toLowerCase();
|
|
42
|
+
if (!UUID_PATTERN.test(normalized)) {
|
|
43
|
+
throw new TeamClawsError("invalid_target", `The ${label} is not valid.`, {
|
|
44
|
+
exitCode: 2,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
export function canonicalWorkspaceUrl(value) {
|
|
50
|
+
return `${canonicalWorkspaceOrigin(value)}/`;
|
|
51
|
+
}
|
|
52
|
+
export function canonicalWorkspaceOrigin(value) {
|
|
53
|
+
const raw = requireString(value, "workspace address", 2_048);
|
|
54
|
+
let url;
|
|
55
|
+
try {
|
|
56
|
+
url = new URL(raw);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
throw new TeamClawsError("invalid_target", "The workspace address is not valid.", {
|
|
60
|
+
exitCode: 2,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (url.protocol !== "https:" ||
|
|
64
|
+
url.username !== "" ||
|
|
65
|
+
url.password !== "" ||
|
|
66
|
+
url.search !== "" ||
|
|
67
|
+
url.hash !== "" ||
|
|
68
|
+
url.port !== "" ||
|
|
69
|
+
(url.pathname !== "" && url.pathname !== "/") ||
|
|
70
|
+
url.hostname === "localhost" ||
|
|
71
|
+
isIP(url.hostname) !== 0) {
|
|
72
|
+
throw new TeamClawsError("invalid_target", "Use a canonical HTTPS TeamClaws workspace address.", { exitCode: 2 });
|
|
73
|
+
}
|
|
74
|
+
return url.origin;
|
|
75
|
+
}
|
|
76
|
+
export function parsePairingTarget(value) {
|
|
77
|
+
if (UUID_PATTERN.test(value))
|
|
78
|
+
return { server_id: value.toLowerCase() };
|
|
79
|
+
return { workspace_url: canonicalWorkspaceUrl(value) };
|
|
80
|
+
}
|
|
81
|
+
export function validateDirectTarget(value) {
|
|
82
|
+
if (!isObject(value)) {
|
|
83
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid target.", {
|
|
84
|
+
exitCode: 9,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
assertExactKeys(value, [
|
|
88
|
+
"origin",
|
|
89
|
+
"token_poll_path",
|
|
90
|
+
"cancellation_path",
|
|
91
|
+
"credential_verification_path",
|
|
92
|
+
], [], "target");
|
|
93
|
+
const origin = canonicalWorkspaceOrigin(value.origin);
|
|
94
|
+
const target = {
|
|
95
|
+
origin,
|
|
96
|
+
token_poll_path: validateRelativeTargetPath(value.token_poll_path, origin),
|
|
97
|
+
cancellation_path: validateRelativeTargetPath(value.cancellation_path, origin),
|
|
98
|
+
credential_verification_path: validateRelativeTargetPath(value.credential_verification_path, origin),
|
|
99
|
+
};
|
|
100
|
+
return target;
|
|
101
|
+
}
|
|
102
|
+
export function validateRelativeTargetPath(value, origin) {
|
|
103
|
+
const path = requireString(value, "target path", 2_048);
|
|
104
|
+
if (!path.startsWith("/") ||
|
|
105
|
+
path.startsWith("//") ||
|
|
106
|
+
path.includes("\\") ||
|
|
107
|
+
path.includes("?") ||
|
|
108
|
+
path.includes("#")) {
|
|
109
|
+
throw new TeamClawsError("unsafe_target", "TeamClaws returned an unsafe target path.", {
|
|
110
|
+
exitCode: 9,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const resolved = new URL(path, origin);
|
|
114
|
+
if (resolved.origin !== origin || resolved.pathname !== path) {
|
|
115
|
+
throw new TeamClawsError("unsafe_target", "TeamClaws returned an unsafe target path.", {
|
|
116
|
+
exitCode: 9,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return path;
|
|
120
|
+
}
|
|
121
|
+
export function directTargetUrl(target, path) {
|
|
122
|
+
return new URL(path, `${target.origin}/`).toString();
|
|
123
|
+
}
|
|
124
|
+
export function parsePendingPairing(value) {
|
|
125
|
+
if (!isObject(value)) {
|
|
126
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid pairing response.", {
|
|
127
|
+
exitCode: 9,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
assertExactKeys(value, [
|
|
131
|
+
"contract_version",
|
|
132
|
+
"server_id",
|
|
133
|
+
"target",
|
|
134
|
+
"user_code",
|
|
135
|
+
"verification_uri_complete",
|
|
136
|
+
"expires_in",
|
|
137
|
+
"interval",
|
|
138
|
+
"status",
|
|
139
|
+
"device_code",
|
|
140
|
+
], ["agent_action"], "pairing response");
|
|
141
|
+
if (value.contract_version !== 1 || value.status !== "pending") {
|
|
142
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an unsupported pairing response.", {
|
|
143
|
+
exitCode: 9,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const target = validateDirectTarget(value.target);
|
|
147
|
+
const verificationText = requireString(value.verification_uri_complete, "approval address", 2_048);
|
|
148
|
+
const verification = requireHttpsUrl(verificationText, "approval address");
|
|
149
|
+
if (verification.origin !== target.origin) {
|
|
150
|
+
throw new TeamClawsError("unsafe_target", "The pairing approval address does not match the selected workspace.", { exitCode: 9 });
|
|
151
|
+
}
|
|
152
|
+
const userCode = requireString(value.user_code, "user code", 64);
|
|
153
|
+
const deviceCode = requireString(value.device_code, "device code", 4_096);
|
|
154
|
+
const pending = {
|
|
155
|
+
contract_version: 1,
|
|
156
|
+
server_id: normalizeUuid(value.server_id),
|
|
157
|
+
target,
|
|
158
|
+
user_code: userCode,
|
|
159
|
+
verification_uri_complete: verificationText,
|
|
160
|
+
expires_in: requireInteger(value.expires_in, "pairing expiry", 1, 1_800),
|
|
161
|
+
interval: requireInteger(value.interval, "polling interval", 1, 60),
|
|
162
|
+
status: "pending",
|
|
163
|
+
device_code: deviceCode,
|
|
164
|
+
};
|
|
165
|
+
if ("agent_action" in value) {
|
|
166
|
+
pending.agent_action = parseAgentAction(value.agent_action, verificationText, userCode, deviceCode);
|
|
167
|
+
}
|
|
168
|
+
return pending;
|
|
169
|
+
}
|
|
170
|
+
export function parseAgentAction(value, verificationUri, userCode, deviceCode) {
|
|
171
|
+
if (!isObject(value)) {
|
|
172
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid agent action.", { exitCode: 9 });
|
|
173
|
+
}
|
|
174
|
+
assertExactKeys(value, [
|
|
175
|
+
"schema_version",
|
|
176
|
+
"type",
|
|
177
|
+
"message_format",
|
|
178
|
+
"message_markdown",
|
|
179
|
+
"expires_at",
|
|
180
|
+
], [], "agent action");
|
|
181
|
+
const message = requireString(value.message_markdown, "agent action message", 8_192);
|
|
182
|
+
if (value.schema_version !== 1 ||
|
|
183
|
+
value.type !== "deliver_and_stop" ||
|
|
184
|
+
value.message_format !== "markdown" ||
|
|
185
|
+
!message.includes(verificationUri) ||
|
|
186
|
+
!message.includes(userCode) ||
|
|
187
|
+
message.includes(deviceCode)) {
|
|
188
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an unsafe agent action.", { exitCode: 9 });
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
schema_version: 1,
|
|
192
|
+
type: "deliver_and_stop",
|
|
193
|
+
message_format: "markdown",
|
|
194
|
+
message_markdown: message,
|
|
195
|
+
expires_at: requireIsoDate(value.expires_at, "agent action expiry"),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
export function requireHttpsUrl(value, label) {
|
|
199
|
+
const raw = requireString(value, label, 4_096);
|
|
200
|
+
let url;
|
|
201
|
+
try {
|
|
202
|
+
url = new URL(raw);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
throw new TeamClawsError("invalid_response", `TeamClaws returned an invalid ${label}.`, {
|
|
206
|
+
exitCode: 9,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
if (url.protocol !== "https:" || url.username !== "" || url.password !== "") {
|
|
210
|
+
throw new TeamClawsError("invalid_response", `TeamClaws returned an unsafe ${label}.`, {
|
|
211
|
+
exitCode: 9,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return url;
|
|
215
|
+
}
|
|
216
|
+
export function parsePairingCredential(value) {
|
|
217
|
+
if (!isObject(value) || value.status !== "paired") {
|
|
218
|
+
throw new TeamClawsError("invalid_response", "The workspace returned an invalid credential.", {
|
|
219
|
+
exitCode: 9,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (value.token_type !== "Bearer") {
|
|
223
|
+
throw new TeamClawsError("invalid_response", "The workspace returned an unsupported credential.", {
|
|
224
|
+
exitCode: 9,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
device_id: normalizeUuid(value.device_id, "device identifier"),
|
|
229
|
+
device_token: requireString(value.device_token, "device token", 8_192),
|
|
230
|
+
...(Object.hasOwn(value, "external_chat_capabilities")
|
|
231
|
+
? {
|
|
232
|
+
external_chat_capabilities: value.external_chat_capabilities,
|
|
233
|
+
external_chat_capabilities_generated_at: value.external_chat_capabilities_generated_at,
|
|
234
|
+
}
|
|
235
|
+
: {}),
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
export function parseVerifiedDevice(value, expectedDeviceId) {
|
|
239
|
+
if (!isObject(value) || !isObject(value.paired_device)) {
|
|
240
|
+
throw new TeamClawsError("credential_verification_failed", "The workspace credential was not verified.", {
|
|
241
|
+
exitCode: 9,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
const id = normalizeUuid(value.paired_device.id, "device identifier");
|
|
245
|
+
if (id !== expectedDeviceId || value.paired_device.status !== "active") {
|
|
246
|
+
throw new TeamClawsError("credential_verification_failed", "The workspace credential was not verified.", {
|
|
247
|
+
exitCode: 9,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return requireString(value.paired_device.display_name, "workspace device name", 120);
|
|
251
|
+
}
|
|
252
|
+
export function parseVerifiedWorkspace(value, expectedDeviceId, origin) {
|
|
253
|
+
if (!isObject(value)) {
|
|
254
|
+
throw new TeamClawsError("credential_verification_failed", "The workspace credential was not verified.", { exitCode: 9 });
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
display_name: parseVerifiedDevice(value, expectedDeviceId),
|
|
258
|
+
external_chat_handoff: parseExternalChatHandoff(value.external_chat_handoff, origin),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
export function parseExternalChatHandoff(value, origin) {
|
|
262
|
+
if (!isObject(value) ||
|
|
263
|
+
value.schema_version !== 1 ||
|
|
264
|
+
value.contract_version !== 1) {
|
|
265
|
+
throw invalidExternalChatHandoff();
|
|
266
|
+
}
|
|
267
|
+
const reasonCodes = parseReasonCodes(value.reason_codes);
|
|
268
|
+
if (value.status === "re_pair_required" &&
|
|
269
|
+
value.recommended_action === "re_pair" &&
|
|
270
|
+
reasonCodes.length > 0) {
|
|
271
|
+
return {
|
|
272
|
+
schema_version: 1,
|
|
273
|
+
contract_version: 1,
|
|
274
|
+
status: "re_pair_required",
|
|
275
|
+
reason_codes: reasonCodes,
|
|
276
|
+
recommended_action: "re_pair",
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
if (value.status === "unavailable" &&
|
|
280
|
+
value.recommended_action === "retry_later" &&
|
|
281
|
+
reasonCodes.includes("client_bundle_unavailable")) {
|
|
282
|
+
return {
|
|
283
|
+
schema_version: 1,
|
|
284
|
+
contract_version: 1,
|
|
285
|
+
status: "unavailable",
|
|
286
|
+
reason_codes: reasonCodes,
|
|
287
|
+
recommended_action: "retry_later",
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
const skillUrl = `${origin}/teamclaws-admin/device-chat-client/SKILL.md`;
|
|
291
|
+
const bundleSha256 = requireString(value.bundle_sha256, "external chat bundle digest", 64);
|
|
292
|
+
if (value.status !== "ready" ||
|
|
293
|
+
value.recommended_action !== "load_skill" ||
|
|
294
|
+
reasonCodes.length !== 0 ||
|
|
295
|
+
value.skill_name !== "teamclaws-external-chat-client" ||
|
|
296
|
+
value.skill_url !== skillUrl ||
|
|
297
|
+
value.capabilities_url !==
|
|
298
|
+
"/teamclaws-admin/api/device-chat/v1/capabilities/" ||
|
|
299
|
+
!/^[0-9a-f]{64}$/u.test(bundleSha256)) {
|
|
300
|
+
throw invalidExternalChatHandoff();
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
schema_version: 1,
|
|
304
|
+
contract_version: 1,
|
|
305
|
+
status: "ready",
|
|
306
|
+
reason_codes: [],
|
|
307
|
+
skill_url: skillUrl,
|
|
308
|
+
skill_name: "teamclaws-external-chat-client",
|
|
309
|
+
bundle_sha256: bundleSha256,
|
|
310
|
+
capabilities_url: "/teamclaws-admin/api/device-chat/v1/capabilities/",
|
|
311
|
+
recommended_action: "load_skill",
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
export function parseSafeUserResponse(value) {
|
|
315
|
+
if (!isObject(value)) {
|
|
316
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid account response.", {
|
|
317
|
+
exitCode: 9,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
assertExactKeys(value, ["id", "email", "display_name", "expires_at", "token_expired"], [], "account response");
|
|
321
|
+
if (value.token_expired !== false) {
|
|
322
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid account response.", {
|
|
323
|
+
exitCode: 9,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
requireIsoDate(value.expires_at, "access-token expiry");
|
|
327
|
+
return {
|
|
328
|
+
id: normalizeUuid(value.id, "user identifier"),
|
|
329
|
+
display_name: requireString(value.display_name, "display name", 200),
|
|
330
|
+
email: requireString(value.email, "email", 320),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
export function parseServersResponse(value) {
|
|
334
|
+
if (!isObject(value)) {
|
|
335
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid server list.", {
|
|
336
|
+
exitCode: 9,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
assertExactKeys(value, ["servers"], [], "server list");
|
|
340
|
+
if (!Array.isArray(value.servers)) {
|
|
341
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid server list.", {
|
|
342
|
+
exitCode: 9,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
if (value.servers.length > 1_000) {
|
|
346
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned too many servers.", {
|
|
347
|
+
exitCode: 9,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
return value.servers.map((server) => {
|
|
351
|
+
if (!isObject(server)) {
|
|
352
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid server.", {
|
|
353
|
+
exitCode: 9,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
assertExactKeys(server, ["id", "alias", "workspace_url", "status", "pairing_ready"], [], "server");
|
|
357
|
+
if (typeof server.pairing_ready !== "boolean") {
|
|
358
|
+
throw new TeamClawsError("invalid_response", "TeamClaws returned an invalid server.", {
|
|
359
|
+
exitCode: 9,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
server_id: normalizeUuid(server.id),
|
|
364
|
+
alias: requireString(server.alias, "server alias", 200),
|
|
365
|
+
workspace_url: canonicalWorkspaceUrl(server.workspace_url),
|
|
366
|
+
status: requireString(server.status, "server status", 40),
|
|
367
|
+
pairing_ready: server.pairing_ready,
|
|
368
|
+
};
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
export function parseLoginCredential(value) {
|
|
372
|
+
if (!isObject(value))
|
|
373
|
+
throw invalidCredentialFile();
|
|
374
|
+
assertExactKeys(value, ["version", "token_type", "access_token", "refresh_token", "expires_at"], [], "login credential file");
|
|
375
|
+
if (value.version !== 1 || value.token_type !== "Bearer")
|
|
376
|
+
throw invalidCredentialFile();
|
|
377
|
+
return {
|
|
378
|
+
version: 1,
|
|
379
|
+
token_type: "Bearer",
|
|
380
|
+
access_token: requireSecret(value.access_token),
|
|
381
|
+
refresh_token: requireSecret(value.refresh_token),
|
|
382
|
+
expires_at: requireIsoDate(value.expires_at, "login credential expiry"),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
export function parseWorkspaceCredential(value) {
|
|
386
|
+
if (!isObject(value))
|
|
387
|
+
throw invalidCredentialFile();
|
|
388
|
+
assertExactKeys(value, [
|
|
389
|
+
"version",
|
|
390
|
+
"server_id",
|
|
391
|
+
"origin",
|
|
392
|
+
"display_name",
|
|
393
|
+
"device_id",
|
|
394
|
+
"device_token",
|
|
395
|
+
"created_at",
|
|
396
|
+
], [], "workspace credential file");
|
|
397
|
+
if (value.version !== 1)
|
|
398
|
+
throw invalidCredentialFile();
|
|
399
|
+
return {
|
|
400
|
+
version: 1,
|
|
401
|
+
server_id: normalizeUuid(value.server_id),
|
|
402
|
+
origin: canonicalWorkspaceOrigin(value.origin),
|
|
403
|
+
display_name: requireString(value.display_name, "display name", 120),
|
|
404
|
+
device_id: normalizeUuid(value.device_id, "device identifier"),
|
|
405
|
+
device_token: requireSecret(value.device_token),
|
|
406
|
+
created_at: requireIsoDate(value.created_at, "credential creation date"),
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
export function parseStatusWorkspaceCredential(value, expectedServerId) {
|
|
410
|
+
if (!isObject(value) || value.version !== 1)
|
|
411
|
+
throw invalidCredentialFile();
|
|
412
|
+
const serverId = normalizeUuid(value.server_id);
|
|
413
|
+
if (serverId !== normalizeUuid(expectedServerId))
|
|
414
|
+
throw invalidCredentialFile();
|
|
415
|
+
return {
|
|
416
|
+
version: 1,
|
|
417
|
+
server_id: serverId,
|
|
418
|
+
origin: canonicalWorkspaceOrigin(value.origin),
|
|
419
|
+
display_name: typeof value.display_name === "string" && value.display_name.length > 0
|
|
420
|
+
? requireString(value.display_name, "display name", 120)
|
|
421
|
+
: "Paired device",
|
|
422
|
+
device_id: normalizeUuid(value.device_id, "device identifier"),
|
|
423
|
+
device_token: requireSecret(value.device_token),
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
function requireSecret(value) {
|
|
427
|
+
if (typeof value !== "string" || value.length < 8 || value.length > 8_192) {
|
|
428
|
+
throw invalidCredentialFile();
|
|
429
|
+
}
|
|
430
|
+
return value;
|
|
431
|
+
}
|
|
432
|
+
function parseReasonCodes(value) {
|
|
433
|
+
if (!Array.isArray(value) ||
|
|
434
|
+
value.length > 8 ||
|
|
435
|
+
value.some((item) => typeof item !== "string" ||
|
|
436
|
+
item.length === 0 ||
|
|
437
|
+
item.length > 64 ||
|
|
438
|
+
!/^[a-z0-9_]+$/u.test(item))) {
|
|
439
|
+
throw invalidExternalChatHandoff();
|
|
440
|
+
}
|
|
441
|
+
return [...new Set(value)].sort();
|
|
442
|
+
}
|
|
443
|
+
function invalidExternalChatHandoff() {
|
|
444
|
+
return new TeamClawsError("invalid_external_chat_handoff", "The workspace returned an unsupported external chat handoff.", { exitCode: 9 });
|
|
445
|
+
}
|
|
446
|
+
function requireIsoDate(value, label) {
|
|
447
|
+
const text = requireString(value, label, 64);
|
|
448
|
+
if (!Number.isFinite(Date.parse(text))) {
|
|
449
|
+
throw new TeamClawsError("invalid_response", `TeamClaws returned an invalid ${label}.`, {
|
|
450
|
+
exitCode: 9,
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
return text;
|
|
454
|
+
}
|
|
455
|
+
function invalidCredentialFile() {
|
|
456
|
+
return new TeamClawsError("invalid_credential_file", "The local TeamClaws credential file is invalid.", { exitCode: 9 });
|
|
457
|
+
}
|
|
458
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "teamclaws",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official TeamClaws command-line client and agent skills",
|
|
5
|
+
"license": "PolyForm-Shield-1.0.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"private": false,
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=22"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"teamclaws": "./dist/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"skills/",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.build.json",
|
|
22
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
23
|
+
"lint": "eslint .",
|
|
24
|
+
"format:check": "prettier --check .",
|
|
25
|
+
"format": "prettier --write .",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:coverage": "vitest run --coverage",
|
|
28
|
+
"test:package": "npm run build && node scripts/test-packed-package.mjs",
|
|
29
|
+
"audit": "npm audit --audit-level=high",
|
|
30
|
+
"verify": "npm run format:check && npm run lint && npm run typecheck && npm run test:coverage && npm run test:package && npm run audit"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@eslint/js": "10.0.1",
|
|
34
|
+
"@types/node": "22.20.1",
|
|
35
|
+
"@vitest/coverage-v8": "4.1.11",
|
|
36
|
+
"eslint": "10.9.1",
|
|
37
|
+
"prettier": "3.9.6",
|
|
38
|
+
"typescript": "6.0.3",
|
|
39
|
+
"typescript-eslint": "8.68.0",
|
|
40
|
+
"vitest": "4.1.11"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: teamclaws-chat
|
|
3
|
+
description: Start, continue, or resume one external-agent TCChat through the official TeamClaws CLI after this computer is paired with the exact workspace.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TeamClaws external chat
|
|
7
|
+
|
|
8
|
+
Use the official `teamclaws` executable. The CLI owns credential loading,
|
|
9
|
+
authoritative handoff validation, target capability discovery, direct target
|
|
10
|
+
transport, idempotency, and durable request polling.
|
|
11
|
+
|
|
12
|
+
## Required boundary
|
|
13
|
+
|
|
14
|
+
- Do not read, print, copy, transform, or pass the workspace credential.
|
|
15
|
+
- Do not call `www.teamclaws.com` for post-pair chat. The CLI talks directly to
|
|
16
|
+
the paired workspace.
|
|
17
|
+
- Do not download or execute the generated target helper when the installed CLI
|
|
18
|
+
supports these native chat commands.
|
|
19
|
+
- Use only an explicit stable server identifier or canonical workspace origin.
|
|
20
|
+
- Treat the newline-delimited JSON as an allowlisted protocol. Never expose raw
|
|
21
|
+
HTTP responses or provider-native identifiers.
|
|
22
|
+
|
|
23
|
+
## Start one conversation
|
|
24
|
+
|
|
25
|
+
Obtain a non-empty user message, then run:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
teamclaws chat start <target> --message <text> --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Use the workspace recommendation by default. Pass `--provider`, `--model`,
|
|
32
|
+
`--reasoning`, `--fast`, or `--no-fast` only when the user explicitly requests
|
|
33
|
+
an advertised alternative. Preserve `session_id`, `request_id`, `revision`, and
|
|
34
|
+
the last assistant `message_id` from safe output.
|
|
35
|
+
|
|
36
|
+
If `approval_required` appears, present its authenticated
|
|
37
|
+
`owner_conversation_url` and continue waiting. Emit each `assistant_message`
|
|
38
|
+
once. Claim success only after `request_succeeded` with at least one response.
|
|
39
|
+
|
|
40
|
+
## Continue or resume
|
|
41
|
+
|
|
42
|
+
To add a later turn to the same conversation:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
teamclaws chat send <target> --session-id <uuid> --message <text> --json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
To resume monitoring an already-created request without creating anything:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
teamclaws chat watch <target> --session-id <uuid> --request-id <uuid> --known-revision <n> --after-response-message-id <n> --json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Reuse `--client-request-id <uuid>` after an uncertain create response. Never
|
|
55
|
+
invent a new idempotency key to hide uncertainty about whether a turn exists.
|
|
56
|
+
|
|
57
|
+
## Failure handling
|
|
58
|
+
|
|
59
|
+
- `re_pair_required`: direct the user to TCChat Pair & Transfer.
|
|
60
|
+
- `selection_unavailable`: use the advertised recommendation unless the user
|
|
61
|
+
asks for another valid selection.
|
|
62
|
+
- `rejected`, `expired`, or `canceled`: stop and report the terminal state.
|
|
63
|
+
- `failed`: report the safe returned detail and retain the request identifiers.
|
|
64
|
+
- network failure: retain identifiers and resume with `chat watch`; do not
|
|
65
|
+
silently create another session or turn.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: teamclaws-login
|
|
3
|
+
description: Sign the official TeamClaws command-line client in, inspect its safe login status, or sign this computer out without exposing login credentials.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TeamClaws command-line login
|
|
7
|
+
|
|
8
|
+
Use the official executable:
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
npx teamclaws login --json
|
|
12
|
+
npx teamclaws login owner@example.com --json
|
|
13
|
+
npx teamclaws auth status --json
|
|
14
|
+
npx teamclaws logout --json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Login uses OAuth 2.0 Device Authorization Grant against www.teamclaws.com. The
|
|
18
|
+
next owner-facing line is `verification_uri_complete`. Optional email is a bind
|
|
19
|
+
sent to TeamClawsdeploy, not identity asserted by this process. Never transfer a
|
|
20
|
+
model or harness token into this process. The command-line client stores its own
|
|
21
|
+
protected login credential locally.
|
|
22
|
+
|
|
23
|
+
Only treat the fixed structured events as safe. Never expose access tokens,
|
|
24
|
+
refresh tokens, device codes, cookies, or authorization headers.
|
|
25
|
+
|
|
26
|
+
Logout always removes the local command-line login credential. A
|
|
27
|
+
`local_only_warning` status means local logout succeeded but remote revocation
|
|
28
|
+
could not be confirmed. Completed Clawgate workspace credentials are not
|
|
29
|
+
deleted by logout.
|