@gobi-ai/cli 0.3.2 → 0.3.4
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/astra.js +16 -14
- package/dist/commands/brain.js +31 -8
- package/dist/commands/sessions.js +39 -45
- package/package.json +1 -1
package/dist/commands/astra.js
CHANGED
|
@@ -28,13 +28,15 @@ export function registerAstraCommand(program) {
|
|
|
28
28
|
.command("get-thread <threadId>")
|
|
29
29
|
.description("Get a thread and its replies (paginated).")
|
|
30
30
|
.option("--limit <number>", "Replies per page", "20")
|
|
31
|
-
.option("--
|
|
31
|
+
.option("--cursor <string>", "Pagination cursor from previous response")
|
|
32
32
|
.action(async (threadId, opts) => {
|
|
33
33
|
const spaceSlug = resolveSpaceSlug(space);
|
|
34
|
-
const
|
|
34
|
+
const params = {
|
|
35
35
|
limit: parseInt(opts.limit, 10),
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
};
|
|
37
|
+
if (opts.cursor)
|
|
38
|
+
params.cursor = opts.cursor;
|
|
39
|
+
const resp = (await apiGet(`/spaces/${spaceSlug}/threads/${threadId}`, params));
|
|
38
40
|
const data = unwrapResp(resp);
|
|
39
41
|
const pagination = (resp.pagination || {});
|
|
40
42
|
if (isJsonMode(space)) {
|
|
@@ -43,9 +45,6 @@ export function registerAstraCommand(program) {
|
|
|
43
45
|
}
|
|
44
46
|
const thread = (data.thread || data);
|
|
45
47
|
const replies = (data.items || []);
|
|
46
|
-
const totalReplies = pagination.total ||
|
|
47
|
-
thread.replyCount ||
|
|
48
|
-
0;
|
|
49
48
|
const author = thread.author?.name ||
|
|
50
49
|
`User ${thread.authorId}`;
|
|
51
50
|
const replyLines = [];
|
|
@@ -62,8 +61,9 @@ export function registerAstraCommand(program) {
|
|
|
62
61
|
"",
|
|
63
62
|
thread.content,
|
|
64
63
|
"",
|
|
65
|
-
`Replies (${replies.length}
|
|
64
|
+
`Replies (${replies.length} items):`,
|
|
66
65
|
...replyLines,
|
|
66
|
+
...(pagination.hasMore ? [` Next cursor: ${pagination.nextCursor}`] : []),
|
|
67
67
|
].join("\n");
|
|
68
68
|
console.log(output);
|
|
69
69
|
});
|
|
@@ -71,13 +71,15 @@ export function registerAstraCommand(program) {
|
|
|
71
71
|
.command("list-threads")
|
|
72
72
|
.description("List threads in a space (paginated).")
|
|
73
73
|
.option("--limit <number>", "Items per page", "20")
|
|
74
|
-
.option("--
|
|
74
|
+
.option("--cursor <string>", "Pagination cursor from previous response")
|
|
75
75
|
.action(async (opts) => {
|
|
76
76
|
const spaceSlug = resolveSpaceSlug(space);
|
|
77
|
-
const
|
|
77
|
+
const params = {
|
|
78
78
|
limit: parseInt(opts.limit, 10),
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
};
|
|
80
|
+
if (opts.cursor)
|
|
81
|
+
params.cursor = opts.cursor;
|
|
82
|
+
const resp = (await apiGet(`/spaces/${spaceSlug}/threads`, params));
|
|
81
83
|
if (isJsonMode(space)) {
|
|
82
84
|
jsonOut({
|
|
83
85
|
items: resp.data || [],
|
|
@@ -97,8 +99,8 @@ export function registerAstraCommand(program) {
|
|
|
97
99
|
`User ${t.authorId}`;
|
|
98
100
|
lines.push(`- [${t.id}] "${t.title}" by ${author} (${t.replyCount} replies, ${t.createdAt})`);
|
|
99
101
|
}
|
|
100
|
-
const
|
|
101
|
-
console.log(`Threads (${items.length}
|
|
102
|
+
const footer = pagination.hasMore ? `\n Next cursor: ${pagination.nextCursor}` : "";
|
|
103
|
+
console.log(`Threads (${items.length} items):\n` + lines.join("\n") + footer);
|
|
102
104
|
});
|
|
103
105
|
space
|
|
104
106
|
.command("create-thread")
|
package/dist/commands/brain.js
CHANGED
|
@@ -47,15 +47,33 @@ export function registerBrainCommand(program) {
|
|
|
47
47
|
.description("Ask a brain a question. Creates a targeted session (1:1 conversation).")
|
|
48
48
|
.requiredOption("--vault-slug <vaultSlug>", "Slug of the brain/vault to ask")
|
|
49
49
|
.requiredOption("--space-slug <spaceSlug>", "Space slug where the brain belongs")
|
|
50
|
-
.
|
|
50
|
+
.option("--question <question>", "The question to ask (markdown supported)")
|
|
51
|
+
.option("--rich-text <richText>", "Rich-text JSON array (e.g. [{\"type\":\"text\",\"text\":\"hello\"}])")
|
|
51
52
|
.option("--mode <mode>", 'Session mode: "auto" or "manual"')
|
|
52
53
|
.action(async (opts) => {
|
|
54
|
+
if (!opts.question && !opts.richText) {
|
|
55
|
+
throw new Error("Provide either --question or --rich-text.");
|
|
56
|
+
}
|
|
57
|
+
if (opts.question && opts.richText) {
|
|
58
|
+
throw new Error("--question and --rich-text are mutually exclusive.");
|
|
59
|
+
}
|
|
53
60
|
const spaceSlug = opts.spaceSlug;
|
|
54
61
|
const body = {
|
|
55
62
|
vaultSlug: opts.vaultSlug,
|
|
56
63
|
spaceSlug,
|
|
57
|
-
question: opts.question,
|
|
58
64
|
};
|
|
65
|
+
if (opts.question != null)
|
|
66
|
+
body.question = opts.question;
|
|
67
|
+
if (opts.richText != null) {
|
|
68
|
+
let parsed;
|
|
69
|
+
try {
|
|
70
|
+
parsed = JSON.parse(opts.richText);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
throw new Error("Invalid --rich-text JSON.");
|
|
74
|
+
}
|
|
75
|
+
body.richText = parsed;
|
|
76
|
+
}
|
|
59
77
|
if (opts.mode != null)
|
|
60
78
|
body.mode = opts.mode;
|
|
61
79
|
const resp = (await apiPost(`/session/targeted`, body));
|
|
@@ -126,21 +144,26 @@ export function registerBrainCommand(program) {
|
|
|
126
144
|
// ── Updates (list, post, edit, delete) ──
|
|
127
145
|
brain
|
|
128
146
|
.command("list-updates")
|
|
129
|
-
.description("List recent brain updates for
|
|
147
|
+
.description("List recent brain updates. Without --space-slug, lists all updates for you. With --space-slug, lists updates for that space. Use --mine to show only updates by you.")
|
|
130
148
|
.option("--vault-slug <vaultSlug>", "Vault slug (overrides .gobi/settings.yaml)")
|
|
149
|
+
.option("--space-slug <spaceSlug>", "List updates for a space")
|
|
131
150
|
.option("--mine", "List only my own brain updates")
|
|
132
151
|
.option("--limit <number>", "Items per page", "20")
|
|
133
|
-
.option("--
|
|
152
|
+
.option("--cursor <string>", "Pagination cursor from previous response")
|
|
134
153
|
.action(async (opts) => {
|
|
135
154
|
const params = {
|
|
136
155
|
limit: parseInt(opts.limit, 10),
|
|
137
|
-
offset: parseInt(opts.offset, 10),
|
|
138
156
|
};
|
|
157
|
+
if (opts.cursor)
|
|
158
|
+
params.cursor = opts.cursor;
|
|
139
159
|
if (opts.mine)
|
|
140
160
|
params.mine = true;
|
|
141
161
|
if (opts.vaultSlug)
|
|
142
162
|
params.vaultSlug = opts.vaultSlug;
|
|
143
|
-
const
|
|
163
|
+
const path = opts.spaceSlug
|
|
164
|
+
? `/spaces/${opts.spaceSlug}/brain-updates`
|
|
165
|
+
: `/brain-updates`;
|
|
166
|
+
const resp = (await apiGet(path, params));
|
|
144
167
|
if (isJsonMode(brain)) {
|
|
145
168
|
jsonOut({
|
|
146
169
|
items: resp.data || [],
|
|
@@ -162,8 +185,8 @@ export function registerBrainCommand(program) {
|
|
|
162
185
|
"?";
|
|
163
186
|
lines.push(`- [${u.id}] "${u.title}" by ${author} (vault: ${vaultSlug}, ${u.createdAt})`);
|
|
164
187
|
}
|
|
165
|
-
const
|
|
166
|
-
console.log(`Brain updates (${items.length}
|
|
188
|
+
const footer = pagination.hasMore ? `\n Next cursor: ${pagination.nextCursor}` : "";
|
|
189
|
+
console.log(`Brain updates (${items.length} items):\n` + lines.join("\n") + footer);
|
|
167
190
|
});
|
|
168
191
|
brain
|
|
169
192
|
.command("post-update")
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { apiGet, apiPost
|
|
1
|
+
import { apiGet, apiPost } from "../client.js";
|
|
2
2
|
import { isJsonMode, jsonOut, unwrapResp } from "./utils.js";
|
|
3
3
|
export function registerSessionsCommand(program) {
|
|
4
4
|
const sessions = program
|
|
5
5
|
.command("session")
|
|
6
|
-
.description("Session commands (get, list, reply
|
|
6
|
+
.description("Session commands (get, list, reply).");
|
|
7
7
|
// ── Get ──
|
|
8
8
|
sessions
|
|
9
9
|
.command("get <sessionId>")
|
|
10
10
|
.description("Get a session and its messages (paginated).")
|
|
11
11
|
.option("--limit <number>", "Messages per page", "20")
|
|
12
|
-
.option("--
|
|
12
|
+
.option("--cursor <string>", "Pagination cursor from previous response")
|
|
13
13
|
.action(async (sessionId, opts) => {
|
|
14
|
-
const
|
|
14
|
+
const params = {
|
|
15
15
|
limit: parseInt(opts.limit, 10),
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
};
|
|
17
|
+
if (opts.cursor)
|
|
18
|
+
params.cursor = opts.cursor;
|
|
19
|
+
const resp = (await apiGet(`/session/${sessionId}`, params));
|
|
18
20
|
const data = unwrapResp(resp);
|
|
19
21
|
if (isJsonMode(sessions)) {
|
|
20
22
|
jsonOut(data);
|
|
@@ -23,7 +25,6 @@ export function registerSessionsCommand(program) {
|
|
|
23
25
|
const session = (data.session || data);
|
|
24
26
|
const messages = (data.messages || []);
|
|
25
27
|
const pagination = (data.pagination || {});
|
|
26
|
-
const totalMessages = pagination.total || messages.length;
|
|
27
28
|
const msgLines = [];
|
|
28
29
|
for (const m of messages) {
|
|
29
30
|
const author = m.author?.name ||
|
|
@@ -39,8 +40,9 @@ export function registerSessionsCommand(program) {
|
|
|
39
40
|
` Mode: ${session.mode}`,
|
|
40
41
|
` Last activity: ${session.lastMessageAt}`,
|
|
41
42
|
"",
|
|
42
|
-
`Messages (${messages.length}
|
|
43
|
+
`Messages (${messages.length} items):`,
|
|
43
44
|
...msgLines,
|
|
45
|
+
...(pagination.hasMore ? [` Next cursor: ${pagination.nextCursor}`] : []),
|
|
44
46
|
].join("\n");
|
|
45
47
|
console.log(output);
|
|
46
48
|
});
|
|
@@ -50,17 +52,16 @@ export function registerSessionsCommand(program) {
|
|
|
50
52
|
.description("List all sessions you are part of, sorted by most recent activity.")
|
|
51
53
|
.option("--space-slug <spaceSlug>", "Filter by space slug")
|
|
52
54
|
.option("--limit <number>", "Items per page", "20")
|
|
53
|
-
.option("--
|
|
55
|
+
.option("--cursor <string>", "Pagination cursor from previous response")
|
|
54
56
|
.action(async (opts) => {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
const query = { limit: parseInt(opts.limit, 10) };
|
|
58
|
+
if (opts.cursor)
|
|
59
|
+
query.cursor = opts.cursor;
|
|
58
60
|
if (opts.spaceSlug)
|
|
59
61
|
query.spaceSlug = opts.spaceSlug;
|
|
60
62
|
const resp = (await apiGet(`/session/my-sessions`, query));
|
|
61
63
|
const items = (resp.data || []);
|
|
62
64
|
const pagination = (resp.pagination || {});
|
|
63
|
-
const total = pagination.total ?? items.length;
|
|
64
65
|
if (isJsonMode(sessions)) {
|
|
65
66
|
jsonOut({
|
|
66
67
|
items,
|
|
@@ -87,17 +88,37 @@ export function registerSessionsCommand(program) {
|
|
|
87
88
|
}
|
|
88
89
|
lines.push(`- [${s.id}] "${title}" (mode: ${s.mode}, last activity: ${s.lastMessageAt})${memberInfo}`);
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
+
const footer = pagination.hasMore ? `\n Next cursor: ${pagination.nextCursor}` : "";
|
|
92
|
+
console.log(`Sessions (${items.length} items):\n` + lines.join("\n") + footer);
|
|
91
93
|
});
|
|
92
94
|
// ── Reply ──
|
|
93
95
|
sessions
|
|
94
96
|
.command("reply <sessionId>")
|
|
95
97
|
.description("Send a human reply to a session you are a member of.")
|
|
96
|
-
.
|
|
98
|
+
.option("--content <content>", "Reply content (markdown supported)")
|
|
99
|
+
.option("--rich-text <richText>", "Rich-text JSON array (e.g. [{\"type\":\"text\",\"text\":\"hello\"}])")
|
|
97
100
|
.action(async (sessionId, opts) => {
|
|
98
|
-
|
|
99
|
-
content
|
|
100
|
-
}
|
|
101
|
+
if (!opts.content && !opts.richText) {
|
|
102
|
+
throw new Error("Provide either --content or --rich-text.");
|
|
103
|
+
}
|
|
104
|
+
if (opts.content && opts.richText) {
|
|
105
|
+
throw new Error("--content and --rich-text are mutually exclusive.");
|
|
106
|
+
}
|
|
107
|
+
const body = {};
|
|
108
|
+
if (opts.richText != null) {
|
|
109
|
+
let parsed;
|
|
110
|
+
try {
|
|
111
|
+
parsed = JSON.parse(opts.richText);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
throw new Error("Invalid --rich-text JSON.");
|
|
115
|
+
}
|
|
116
|
+
body.richText = parsed;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
body.content = opts.content;
|
|
120
|
+
}
|
|
121
|
+
const resp = (await apiPost(`/session/${sessionId}/reply`, body));
|
|
101
122
|
const msg = unwrapResp(resp);
|
|
102
123
|
if (isJsonMode(sessions)) {
|
|
103
124
|
jsonOut(msg);
|
|
@@ -108,31 +129,4 @@ export function registerSessionsCommand(program) {
|
|
|
108
129
|
` Source: ${msg.source}\n` +
|
|
109
130
|
` Created: ${msg.createdAt}`);
|
|
110
131
|
});
|
|
111
|
-
// ── Update ──
|
|
112
|
-
sessions
|
|
113
|
-
.command("update <sessionId>")
|
|
114
|
-
.description('Update a session. "auto" lets the AI respond automatically; "manual" requires human replies.')
|
|
115
|
-
.option("--mode <mode>", 'Session mode: "auto" or "manual"')
|
|
116
|
-
.action(async (sessionId, opts) => {
|
|
117
|
-
if (!opts.mode) {
|
|
118
|
-
throw new Error("Provide at least one option to update (e.g. --mode).");
|
|
119
|
-
}
|
|
120
|
-
const body = {};
|
|
121
|
-
if (opts.mode != null) {
|
|
122
|
-
if (opts.mode !== "auto" && opts.mode !== "manual") {
|
|
123
|
-
throw new Error('Invalid mode. Must be "auto" or "manual".');
|
|
124
|
-
}
|
|
125
|
-
body.mode = opts.mode;
|
|
126
|
-
}
|
|
127
|
-
const resp = (await apiPatch(`/session/${sessionId}`, body));
|
|
128
|
-
const data = unwrapResp(resp);
|
|
129
|
-
if (isJsonMode(sessions)) {
|
|
130
|
-
jsonOut(data);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const session = (data.session || data);
|
|
134
|
-
console.log(`Session updated!\n` +
|
|
135
|
-
` ID: ${session.id}\n` +
|
|
136
|
-
` Mode: ${session.mode}`);
|
|
137
|
-
});
|
|
138
132
|
}
|