@bli-cockpit/cli 0.2.239 → 0.2.240
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/dist/commands/cal-delete.js +13 -3
- package/dist/commands/cal-scope.js +71 -0
- package/dist/commands/cal.js +7 -0
- package/dist/commands/docs-share.js +81 -0
- package/dist/commands/docs.js +5 -0
- package/dist/commands/drills-render.js +2 -2
- package/dist/commands/drills.js +4 -4
- package/dist/commands/issue-list-page.js +101 -0
- package/dist/commands/issue.js +23 -5
- package/dist/commands/local-args-tower-cal.js +97 -6
- package/dist/commands/local-args-tower-docs-msg.js +30 -3
- package/dist/commands/local-args-tower-drills.js +1 -1
- package/dist/commands/local-args-tower-msg.js +43 -6
- package/dist/commands/local-args-tower-work.js +74 -6
- package/dist/commands/local-help-commands-tower-ops.js +3 -3
- package/dist/commands/local-help-commands-tower.js +14 -10
- package/dist/commands/msg-write.js +118 -0
- package/dist/commands/msg.js +20 -29
- package/dist/commands/project.js +15 -3
- package/dist/commands/public-root.js +1 -1
- package/package.json +2 -2
package/dist/commands/msg.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `cockpit msg` — channels and messages, typed (BLI-3706, BLI-3749).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Eleven verbs over `/api/msg/**` (BLI-3654 Wave 1a), which already accepts the
|
|
5
5
|
* collector device token through `resolveCaller({ allowDeviceToken: true })`
|
|
6
6
|
* on every route — no server-side door change was needed for this terminal.
|
|
7
7
|
*
|
|
@@ -15,14 +15,15 @@
|
|
|
15
15
|
* silently adding a stranger. `dm` does not have to name the caller — the
|
|
16
16
|
* door unions them in.
|
|
17
17
|
*/
|
|
18
|
+
import { randomUUID } from "node:crypto";
|
|
18
19
|
import { askAgentDoor, emitAgentDoor, failAgentDoor, openAgentDoor, } from "./agent-door.js";
|
|
19
|
-
import {
|
|
20
|
+
import { writeLine } from "./cli-io.js";
|
|
20
21
|
import { cacheAgeLabel, cacheCoverage, readThroughCache } from "./read-cache.js";
|
|
21
22
|
import { markReadThrough } from "./msg-read-line.js";
|
|
23
|
+
import { deleteMessage, editMessage, messageOutcome, messageText, readContent, refuseMsgWrite } from "./msg-write.js";
|
|
22
24
|
const TAG = "[msg cli]";
|
|
23
25
|
const READ_DEADLINE_MS = 30_000;
|
|
24
26
|
const WRITE_DEADLINE_MS = 30_000;
|
|
25
|
-
const CONTENT_MAX_CHARS = 8_000;
|
|
26
27
|
export async function runMsg(command, io) {
|
|
27
28
|
const door = await openAgentDoor("msg", command, io);
|
|
28
29
|
switch (command.action) {
|
|
@@ -36,6 +37,12 @@ export async function runMsg(command, io) {
|
|
|
36
37
|
return markUnread(command, door);
|
|
37
38
|
case "send":
|
|
38
39
|
return sendMessage(command, door);
|
|
40
|
+
case "edit":
|
|
41
|
+
return editMessage(command, door);
|
|
42
|
+
case "delete":
|
|
43
|
+
return deleteMessage(command, door);
|
|
44
|
+
case "outcome":
|
|
45
|
+
return messageOutcome(command, door);
|
|
39
46
|
case "thread":
|
|
40
47
|
return readThread(command, door);
|
|
41
48
|
case "create":
|
|
@@ -180,7 +187,7 @@ async function readChannel(command, door) {
|
|
|
180
187
|
for (const message of [...messages].reverse()) {
|
|
181
188
|
// An imported Slack message has no Tower user; its Slack name is the label.
|
|
182
189
|
const who = message.agent_label ?? message.user_id ?? message.slack_author_label ?? "someone";
|
|
183
|
-
writeLine(door.io.stdout, `${message.id} ${message.created_at} ${who} ${message
|
|
190
|
+
writeLine(door.io.stdout, `${message.id} ${message.created_at} ${who} ${messageText(message)}`);
|
|
184
191
|
}
|
|
185
192
|
if (readMove) {
|
|
186
193
|
writeLine(readMove.ok ? door.io.stdout : door.io.stderr, readMove.ok
|
|
@@ -243,29 +250,10 @@ async function readThread(command, door) {
|
|
|
243
250
|
}
|
|
244
251
|
for (const message of [...messages].reverse()) {
|
|
245
252
|
const who = message.agent_label ?? message.user_id;
|
|
246
|
-
writeLine(door.io.stdout, `${message.id} ${message.created_at} ${who} ${message
|
|
253
|
+
writeLine(door.io.stdout, `${message.id} ${message.created_at} ${who} ${messageText(message)}`);
|
|
247
254
|
}
|
|
248
255
|
return 0;
|
|
249
256
|
}
|
|
250
|
-
async function readContent(io) {
|
|
251
|
-
if (isInteractiveStdin(io)) {
|
|
252
|
-
return {
|
|
253
|
-
ok: false,
|
|
254
|
-
reason: "nothing_piped",
|
|
255
|
-
detail: "Pipe the message in, e.g. `echo \"hello\" | cockpit msg send general`. A message never travels on the command line.",
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
try {
|
|
259
|
-
const text = await readPipedText(io.stdin, {
|
|
260
|
-
maxChars: CONTENT_MAX_CHARS,
|
|
261
|
-
overflowMessage: `A message is limited to ${CONTENT_MAX_CHARS} characters.`,
|
|
262
|
-
});
|
|
263
|
-
return { ok: true, text: text.trim() };
|
|
264
|
-
}
|
|
265
|
-
catch (error) {
|
|
266
|
-
return { ok: false, reason: "content_too_long", detail: error instanceof Error ? error.message : String(error) };
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
257
|
async function sendMessage(command, door) {
|
|
270
258
|
const ref = command.channelRef ?? "";
|
|
271
259
|
const resolved = await resolveChannelId(door, ref);
|
|
@@ -278,6 +266,8 @@ async function sendMessage(command, door) {
|
|
|
278
266
|
return failAgentDoor(door, TAG, content.reason, content.detail);
|
|
279
267
|
if (content.text === "")
|
|
280
268
|
return failAgentDoor(door, TAG, "invalid_body", "There was nothing to send. Nothing was sent.");
|
|
269
|
+
// BLI-21314: every send carries a request id, so a lost response can be checked and a retry posts once.
|
|
270
|
+
const requestId = command.requestId ?? randomUUID();
|
|
281
271
|
const answer = await askAgentDoor(door, {
|
|
282
272
|
path: `/api/msg/channels/${encodeURIComponent(resolved.id)}/messages`,
|
|
283
273
|
method: "POST",
|
|
@@ -285,15 +275,16 @@ async function sendMessage(command, door) {
|
|
|
285
275
|
timeoutMs: WRITE_DEADLINE_MS,
|
|
286
276
|
body: {
|
|
287
277
|
content: content.text,
|
|
278
|
+
request_id: requestId,
|
|
288
279
|
...(command.threadId ? { thread_parent_id: command.threadId } : {}),
|
|
289
280
|
},
|
|
290
281
|
});
|
|
291
282
|
if (!answer.ok)
|
|
292
|
-
return
|
|
293
|
-
const message = answer.body
|
|
294
|
-
writeLine(door.io.stderr, `${TAG} sent ${JSON.stringify({ channel_id: resolved.id, message_id: message?.id ?? null, chars: content.text.length })}`);
|
|
283
|
+
return refuseMsgWrite(door, answer, requestId, "send");
|
|
284
|
+
const { message = null, mutation = null } = answer.body;
|
|
285
|
+
writeLine(door.io.stderr, `${TAG} sent ${JSON.stringify({ channel_id: resolved.id, message_id: message?.id ?? null, request_id: requestId, chars: content.text.length })}`);
|
|
295
286
|
if (door.json)
|
|
296
|
-
return emitAgentDoor(door, { ok: true, message });
|
|
287
|
+
return emitAgentDoor(door, { ok: true, message, mutation });
|
|
297
288
|
writeLine(door.io.stdout, `Sent to ${ref} (${message?.id ?? "?"}).`);
|
|
298
289
|
return 0;
|
|
299
290
|
}
|
|
@@ -386,7 +377,7 @@ async function showMessage(command, door) {
|
|
|
386
377
|
writeLine(door.io.stdout, body.href ?? "Message context");
|
|
387
378
|
for (const page of [body.channelPage, body.threadPage]) {
|
|
388
379
|
for (const row of [...(page?.messages ?? [])].reverse())
|
|
389
|
-
writeLine(door.io.stdout, `${row.id} ${row.created_at} ${row
|
|
380
|
+
writeLine(door.io.stdout, `${row.id} ${row.created_at} ${messageText(row)}`);
|
|
390
381
|
if (page?.nextCursor)
|
|
391
382
|
writeLine(door.io.stdout, `More history: --before ${page.nextCursor}`);
|
|
392
383
|
}
|
package/dist/commands/project.js
CHANGED
|
@@ -10,21 +10,30 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { askAgentDoor, emitAgentDoor, failAgentDoor, openAgentDoor } from "./agent-door.js";
|
|
12
12
|
import { writeLine } from "./cli-io.js";
|
|
13
|
+
import { pageFieldsOf, pageFooter } from "./issue-list-page.js";
|
|
13
14
|
const TAG = "[project cli]";
|
|
14
15
|
const READ_DEADLINE_MS = 30_000;
|
|
15
16
|
export async function runProject(command, io) {
|
|
16
17
|
const door = await openAgentDoor("project", command, io);
|
|
18
|
+
const params = new URLSearchParams();
|
|
19
|
+
if (command.includeArchived)
|
|
20
|
+
params.set("include_archived", "true");
|
|
21
|
+
if (command.limit !== undefined)
|
|
22
|
+
params.set("limit", String(command.limit));
|
|
23
|
+
if (command.cursor)
|
|
24
|
+
params.set("cursor", command.cursor);
|
|
17
25
|
const answer = await askAgentDoor(door, {
|
|
18
|
-
path: `/api/work/projects${
|
|
26
|
+
path: `/api/work/projects${params.toString() ? `?${params.toString()}` : ""}`,
|
|
19
27
|
method: "GET",
|
|
20
28
|
label: "project list",
|
|
21
29
|
timeoutMs: READ_DEADLINE_MS,
|
|
22
30
|
});
|
|
23
31
|
if (!answer.ok)
|
|
24
32
|
return failAgentDoor(door, TAG, answer.reason, answer.detail);
|
|
25
|
-
const
|
|
33
|
+
const body = answer.body;
|
|
34
|
+
const projects = body.projects ?? [];
|
|
26
35
|
if (door.json)
|
|
27
|
-
return emitAgentDoor(door, { ok: true, projects });
|
|
36
|
+
return emitAgentDoor(door, { ok: true, projects, ...pageFieldsOf(body) });
|
|
28
37
|
if (projects.length === 0) {
|
|
29
38
|
writeLine(door.io.stdout, "No projects.");
|
|
30
39
|
return 0;
|
|
@@ -34,5 +43,8 @@ export async function runProject(command, io) {
|
|
|
34
43
|
}
|
|
35
44
|
writeLine(door.io.stdout, "");
|
|
36
45
|
writeLine(door.io.stdout, `${projects.length} project(s).`);
|
|
46
|
+
const footer = pageFooter(body, "projects");
|
|
47
|
+
if (footer)
|
|
48
|
+
writeLine(door.io.stdout, footer);
|
|
37
49
|
return 0;
|
|
38
50
|
}
|
|
@@ -21,7 +21,7 @@ export async function runCockpitCli(argv, io) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (command === "--version" || command === "-V" || command === "version") {
|
|
24
|
-
writeLine(io?.stdout ?? process.stdout, "0.2.
|
|
24
|
+
writeLine(io?.stdout ?? process.stdout, "0.2.240");
|
|
25
25
|
return 0;
|
|
26
26
|
}
|
|
27
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.240",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@bli-cockpit/memory-mcp": "0.1.70",
|
|
31
|
-
"@bli-cockpit/mcp": "0.1.
|
|
31
|
+
"@bli-cockpit/mcp": "0.1.145",
|
|
32
32
|
"@bli-cockpit/telemetry-core": "0.1.77"
|
|
33
33
|
},
|
|
34
34
|
"repository": {
|