@gobi-ai/cli 1.3.2 → 1.3.3
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.
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
"name": "gobi-ai"
|
|
5
5
|
},
|
|
6
6
|
"description": "Claude Code plugin for the Gobi collaborative knowledge platform CLI",
|
|
7
|
-
"version": "1.3.
|
|
7
|
+
"version": "1.3.3",
|
|
8
8
|
"plugins": [
|
|
9
9
|
{
|
|
10
10
|
"name": "gobi",
|
|
11
11
|
"description": "Manage the Gobi collaborative knowledge platform from the command line. Search and ask brains, publish brain documents, create threads, manage sessions, generate images and videos.",
|
|
12
|
-
"version": "1.3.
|
|
12
|
+
"version": "1.3.3",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "gobi-ai"
|
|
15
15
|
},
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import { apiDelete, apiGet, apiPatch, apiPost } from "../client.js";
|
|
3
|
+
import { isJsonMode, jsonOut, unwrapResp } from "./utils.js";
|
|
4
|
+
function readContent(value) {
|
|
5
|
+
if (value === "-")
|
|
6
|
+
return readFileSync("/dev/stdin", "utf8");
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
function snippet(content, max = 80) {
|
|
10
|
+
const single = content.replace(/\s+/g, " ");
|
|
11
|
+
return single.length > max ? `${single.slice(0, max)}…` : single;
|
|
12
|
+
}
|
|
13
|
+
function formatProposalLine(p) {
|
|
14
|
+
const status = p.status === "pending" ? "·" : p.status === "accepted" ? "✓" : "✗";
|
|
15
|
+
return `- [${status}] p${p.priority} rev${p.revision} ${p.proposalId.slice(0, 8)} ${snippet(p.content)}`;
|
|
16
|
+
}
|
|
17
|
+
export function registerProposalCommand(program) {
|
|
18
|
+
const proposal = program
|
|
19
|
+
.command("proposal")
|
|
20
|
+
.description("Proposals authored by your agent during chat. Top-5 feed the system prompt; accept/reject/revise post into the originating chat session.");
|
|
21
|
+
// ── List ──
|
|
22
|
+
proposal
|
|
23
|
+
.command("list")
|
|
24
|
+
.description("List proposals (priority ASC, then newest first).")
|
|
25
|
+
.option("--limit <number>", "Max proposals to return (1-200)", "50")
|
|
26
|
+
.action(async (opts) => {
|
|
27
|
+
const params = { limit: parseInt(opts.limit, 10) };
|
|
28
|
+
const resp = (await apiGet("/app/proposals", params));
|
|
29
|
+
const items = (resp.data || []);
|
|
30
|
+
if (isJsonMode(proposal)) {
|
|
31
|
+
jsonOut(items);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (!items.length) {
|
|
35
|
+
console.log("No proposals.");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
console.log(`Proposals (${items.length}):`);
|
|
39
|
+
for (const p of items)
|
|
40
|
+
console.log(formatProposalLine(p));
|
|
41
|
+
});
|
|
42
|
+
// ── Get ──
|
|
43
|
+
proposal
|
|
44
|
+
.command("get <proposalId>")
|
|
45
|
+
.description("Show one proposal with its history.")
|
|
46
|
+
.action(async (proposalId) => {
|
|
47
|
+
const resp = (await apiGet(`/app/proposals/${proposalId}`));
|
|
48
|
+
const p = unwrapResp(resp);
|
|
49
|
+
if (isJsonMode(proposal)) {
|
|
50
|
+
jsonOut(p);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
console.log(`Proposal ${p.proposalId}`);
|
|
54
|
+
console.log(` status: ${p.status}`);
|
|
55
|
+
console.log(` priority: ${p.priority}`);
|
|
56
|
+
console.log(` revision: ${p.revision}`);
|
|
57
|
+
console.log(` session: ${p.sessionId ?? "(none)"}`);
|
|
58
|
+
console.log(` created: ${p.createdAt}`);
|
|
59
|
+
console.log("");
|
|
60
|
+
console.log("Content:");
|
|
61
|
+
console.log(p.content);
|
|
62
|
+
if (p.history.length) {
|
|
63
|
+
console.log("");
|
|
64
|
+
console.log("History:");
|
|
65
|
+
for (const h of p.history) {
|
|
66
|
+
const detail = h.type === "revise_requested"
|
|
67
|
+
? `: ${h.comment}`
|
|
68
|
+
: h.type === "prioritized"
|
|
69
|
+
? `: priority=${h.priority}`
|
|
70
|
+
: "";
|
|
71
|
+
console.log(` ${h.createdAt} rev${h.revision} ${h.type}${detail}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
// ── Edit content ──
|
|
76
|
+
proposal
|
|
77
|
+
.command("edit <proposalId> <content>")
|
|
78
|
+
.description("Replace proposal content (bumps revision). Pass '-' for stdin.")
|
|
79
|
+
.action(async (proposalId, content) => {
|
|
80
|
+
const resp = (await apiPatch(`/app/proposals/${proposalId}`, {
|
|
81
|
+
content: readContent(content),
|
|
82
|
+
}));
|
|
83
|
+
const p = unwrapResp(resp);
|
|
84
|
+
if (isJsonMode(proposal)) {
|
|
85
|
+
jsonOut(p);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log(`Updated ${p.proposalId} → rev${p.revision}.`);
|
|
89
|
+
});
|
|
90
|
+
// ── Delete ──
|
|
91
|
+
proposal
|
|
92
|
+
.command("delete <proposalId>")
|
|
93
|
+
.description("Delete a proposal.")
|
|
94
|
+
.action(async (proposalId) => {
|
|
95
|
+
await apiDelete(`/app/proposals/${proposalId}`);
|
|
96
|
+
if (isJsonMode(proposal)) {
|
|
97
|
+
jsonOut({ deleted: proposalId });
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(`Deleted ${proposalId}.`);
|
|
101
|
+
});
|
|
102
|
+
// ── Prioritize ──
|
|
103
|
+
proposal
|
|
104
|
+
.command("prioritize <proposalId> <priority>")
|
|
105
|
+
.description("Set priority (lower = higher). Top 5 feed the system prompt.")
|
|
106
|
+
.action(async (proposalId, priority) => {
|
|
107
|
+
const resp = (await apiPatch(`/app/proposals/${proposalId}/priority`, {
|
|
108
|
+
priority: parseInt(priority, 10),
|
|
109
|
+
}));
|
|
110
|
+
const p = unwrapResp(resp);
|
|
111
|
+
if (isJsonMode(proposal)) {
|
|
112
|
+
jsonOut(p);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
console.log(`Set ${p.proposalId} priority to ${p.priority}.`);
|
|
116
|
+
});
|
|
117
|
+
// ── Accept ──
|
|
118
|
+
proposal
|
|
119
|
+
.command("accept <proposalId>")
|
|
120
|
+
.description('Accept — posts "Accept your proposal X" into the originating chat session.')
|
|
121
|
+
.action(async (proposalId) => {
|
|
122
|
+
const resp = (await apiPost(`/app/proposals/${proposalId}/accept`));
|
|
123
|
+
const p = unwrapResp(resp);
|
|
124
|
+
if (isJsonMode(proposal)) {
|
|
125
|
+
jsonOut(p);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
console.log(`Accepted ${p.proposalId}.`);
|
|
129
|
+
});
|
|
130
|
+
// ── Reject ──
|
|
131
|
+
proposal
|
|
132
|
+
.command("reject <proposalId>")
|
|
133
|
+
.description('Reject — posts "Reject your proposal X" into the originating chat session.')
|
|
134
|
+
.action(async (proposalId) => {
|
|
135
|
+
const resp = (await apiPost(`/app/proposals/${proposalId}/reject`));
|
|
136
|
+
const p = unwrapResp(resp);
|
|
137
|
+
if (isJsonMode(proposal)) {
|
|
138
|
+
jsonOut(p);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
console.log(`Rejected ${p.proposalId}.`);
|
|
142
|
+
});
|
|
143
|
+
// ── Revise ──
|
|
144
|
+
proposal
|
|
145
|
+
.command("revise <proposalId> <comment>")
|
|
146
|
+
.description('Ask the agent to revise — posts "Update your proposal X. Here\'s my comment. {comment}" into the chat session.')
|
|
147
|
+
.action(async (proposalId, comment) => {
|
|
148
|
+
const resp = (await apiPost(`/app/proposals/${proposalId}/revise`, {
|
|
149
|
+
comment: readContent(comment),
|
|
150
|
+
}));
|
|
151
|
+
const p = unwrapResp(resp);
|
|
152
|
+
if (isJsonMode(proposal)) {
|
|
153
|
+
jsonOut(p);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
console.log(`Revision requested on ${p.proposalId}.`);
|
|
157
|
+
});
|
|
158
|
+
}
|
package/dist/main.js
CHANGED
|
@@ -13,6 +13,7 @@ import { registerSenseCommand } from "./commands/sense.js";
|
|
|
13
13
|
import { registerSyncCommand } from "./commands/sync.js";
|
|
14
14
|
import { registerUpdateCommand } from "./commands/update.js";
|
|
15
15
|
import { registerMediaCommand } from "./commands/media.js";
|
|
16
|
+
import { registerProposalCommand } from "./commands/proposal.js";
|
|
16
17
|
const require = createRequire(import.meta.url);
|
|
17
18
|
const { version } = require("../package.json");
|
|
18
19
|
const SKIP_BANNER_COMMANDS = new Set(["auth", "init", "update"]);
|
|
@@ -42,6 +43,7 @@ export async function cli() {
|
|
|
42
43
|
registerSyncCommand(program);
|
|
43
44
|
registerUpdateCommand(program);
|
|
44
45
|
registerMediaCommand(program);
|
|
46
|
+
registerProposalCommand(program);
|
|
45
47
|
// Propagate helpWidth to all subcommands
|
|
46
48
|
const helpWidth = process.stdout.columns || 200;
|
|
47
49
|
for (const cmd of program.commands) {
|