@gobi-ai/cli 2.0.36 → 2.0.40
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +24 -33
- package/commands/login.md +1 -1
- package/commands/logout.md +1 -1
- package/commands/post.md +1 -1
- package/commands/space-explore.md +3 -5
- package/commands/space-share.md +7 -7
- package/commands/warp.md +1 -1
- package/dist/commands/personal.js +39 -15
- package/dist/commands/sense.js +162 -111
- package/dist/commands/space.js +35 -0
- package/dist/commands/update.js +2 -2
- package/dist/commands/utils.js +1 -1
- package/dist/main.js +2 -6
- package/package.json +1 -1
- package/skills/gobi-artifact/SKILL.md +3 -3
- package/skills/gobi-artifact/references/personal.md +2 -2
- package/skills/gobi-core/SKILL.md +5 -6
- package/skills/gobi-homepage/SKILL.md +1 -1
- package/skills/gobi-media/SKILL.md +3 -3
- package/skills/gobi-sense/SKILL.md +62 -12
- package/skills/gobi-sense/references/personal.md +50 -0
- package/skills/gobi-sense/references/space.md +53 -0
- package/skills/gobi-space/SKILL.md +22 -40
- package/skills/gobi-space/references/personal.md +42 -6
- package/skills/gobi-vault/SKILL.md +3 -3
- package/dist/commands/global.js +0 -438
- package/skills/gobi-sense/references/sense.md +0 -41
- package/skills/gobi-space/references/global.md +0 -175
package/dist/commands/sense.js
CHANGED
|
@@ -1,129 +1,180 @@
|
|
|
1
1
|
import { apiGet } from "../client.js";
|
|
2
2
|
import { isJsonMode, jsonOut } from "./utils.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
// One-liner for a transcript turn. The backend resolves speaker identities at
|
|
4
|
+
// read time into `speakerLabel` (a managed-voice name, "Me", a session-stable
|
|
5
|
+
// "Speaker N", or "Unknown"); fall back to the raw diarization token only if
|
|
6
|
+
// it's somehow absent.
|
|
7
|
+
function formatTurnLine(t) {
|
|
8
|
+
const who = t.speakerLabel || t.speaker || "Unknown";
|
|
9
|
+
return `- ${who} (${t.timestamp}): ${t.text}`;
|
|
10
|
+
}
|
|
11
|
+
function printTranscriptTurns(turns) {
|
|
12
|
+
const cleaned = (turns || [])
|
|
13
|
+
.map((t) => ({ ...t, text: String(t.text ?? "").trim() }))
|
|
14
|
+
.filter((t) => t.text);
|
|
15
|
+
if (!cleaned.length) {
|
|
16
|
+
console.log("No transcript available.");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
console.log(`Transcript (${cleaned.length} turns):\n` + cleaned.map(formatTurnLine).join("\n"));
|
|
20
|
+
}
|
|
21
|
+
function formatActivityLine(a) {
|
|
22
|
+
const end = a.end_time ? ` → ${a.end_time}` : " → ongoing";
|
|
23
|
+
const details = a.details ? `: ${a.details}` : "";
|
|
24
|
+
// Space activities carry the recorder(s); personal ones don't.
|
|
25
|
+
const recorders = Array.isArray(a.recorders) && a.recorders.length
|
|
26
|
+
? ` by ${a.recorders
|
|
27
|
+
.map((r) => r.name || `user ${r.id}`)
|
|
28
|
+
.join(", ")}`
|
|
29
|
+
: "";
|
|
30
|
+
return `- [${a.id}] ${a.category ?? "activity"}${details} (${a.start_time}${end})${recorders}`;
|
|
31
|
+
}
|
|
32
|
+
function formatConversationLine(c) {
|
|
33
|
+
const durMs = typeof c.durationMs === "number" ? c.durationMs : null;
|
|
34
|
+
const dur = durMs != null ? ` (${Math.max(1, Math.round(durMs / 60000))}m)` : "";
|
|
35
|
+
const cat = c.category ? ` — ${c.category}` : "";
|
|
36
|
+
const status = c.status ? ` [${c.status}]` : "";
|
|
37
|
+
// Space conversations carry the recorder (whose conversation it is); personal
|
|
38
|
+
// ones don't.
|
|
39
|
+
const rec = c.recorder && typeof c.recorder === "object"
|
|
40
|
+
? ` by ${c.recorder.name ?? "someone"}`
|
|
41
|
+
: "";
|
|
42
|
+
return `- [${c.id}] ${c.source ?? "conversation"}${status}${cat} (${c.startTime}${dur})${rec}`;
|
|
43
|
+
}
|
|
44
|
+
function paginationFooter(pagination) {
|
|
45
|
+
return pagination?.hasMore ? `\n Next cursor: ${pagination.nextCursor}` : "";
|
|
46
|
+
}
|
|
47
|
+
// ── Activities ──
|
|
48
|
+
//
|
|
49
|
+
// Registers the `activities` subcommand tree under `parent` (a `gobi space` or
|
|
50
|
+
// `gobi personal` group). Replaces the old top-level `gobi sense list-activities`.
|
|
51
|
+
export function registerActivitiesSubcommands(parent, scope, description) {
|
|
52
|
+
const activities = parent.command("activities").description(description);
|
|
53
|
+
// ── List ──
|
|
54
|
+
activities
|
|
55
|
+
.command("list")
|
|
56
|
+
.description("List Sense activities in this scope (newest first).")
|
|
57
|
+
.option("--limit <n>", "Max items to return (default 30, max 100)")
|
|
58
|
+
.option("--before <cursor>", "Pagination cursor from a previous response (nextCursor)")
|
|
59
|
+
.option("--mine", "Only activities you recorded (space scope; no-op for personal, already yours)")
|
|
13
60
|
.action(async (opts) => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const lastSeenTime = resp.latestTimestamp;
|
|
22
|
-
// Pull out the last activity with null end_time as "last_activity"
|
|
23
|
-
let lastActivityIdx = -1;
|
|
24
|
-
for (let i = allActivities.length - 1; i >= 0; i--) {
|
|
25
|
-
if (allActivities[i].end_time == null) {
|
|
26
|
-
lastActivityIdx = i;
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const last_activity = lastActivityIdx !== -1 ? allActivities[lastActivityIdx] : undefined;
|
|
31
|
-
const activities = lastActivityIdx !== -1
|
|
32
|
-
? allActivities.filter((_, i) => i !== lastActivityIdx)
|
|
33
|
-
: allActivities;
|
|
34
|
-
if (isJsonMode(sense)) {
|
|
35
|
-
jsonOut({ activities, last_activity, lastSeenTime });
|
|
61
|
+
const { items, pagination } = await scope.listActivities({
|
|
62
|
+
limit: opts.limit ? parseInt(opts.limit, 10) : undefined,
|
|
63
|
+
before: opts.before,
|
|
64
|
+
mine: opts.mine,
|
|
65
|
+
});
|
|
66
|
+
if (isJsonMode(activities)) {
|
|
67
|
+
jsonOut({ activities: items, pagination: pagination ?? {} });
|
|
36
68
|
return;
|
|
37
69
|
}
|
|
38
|
-
if (!
|
|
70
|
+
if (!items.length) {
|
|
39
71
|
console.log("No activities found.");
|
|
40
|
-
if (lastSeenTime)
|
|
41
|
-
console.log(`Latest data available: ${lastSeenTime}`);
|
|
42
72
|
return;
|
|
43
73
|
}
|
|
44
|
-
|
|
45
|
-
|
|
74
|
+
console.log(`Activities (${items.length} items, newest first):\n` +
|
|
75
|
+
items.map(formatActivityLine).join("\n") +
|
|
76
|
+
paginationFooter(pagination));
|
|
77
|
+
});
|
|
78
|
+
// ── Get (by id; scope-independent) ──
|
|
79
|
+
activities
|
|
80
|
+
.command("get <activityId>")
|
|
81
|
+
.description("Get one activity's details (visible to you if you recorded it or are a member of its space).")
|
|
82
|
+
.action(async (activityId) => {
|
|
83
|
+
const a = (await apiGet(`/app/activity/${activityId}`));
|
|
84
|
+
if (isJsonMode(activities)) {
|
|
85
|
+
jsonOut(a);
|
|
86
|
+
return;
|
|
46
87
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
88
|
+
console.log(`Activity ${a.id}\n` +
|
|
89
|
+
` category: ${a.category ?? "(none)"}\n` +
|
|
90
|
+
(a.details ? ` details: ${a.details}\n` : "") +
|
|
91
|
+
` start: ${a.start_time}\n` +
|
|
92
|
+
` end: ${a.end_time ?? "ongoing"}`);
|
|
93
|
+
});
|
|
94
|
+
// ── Transcript (by id; owner-only) ──
|
|
95
|
+
activities
|
|
96
|
+
.command("transcript <activityId>")
|
|
97
|
+
.description("Get an activity's transcript (owner-only; 403 for other space members).")
|
|
98
|
+
.action(async (activityId) => {
|
|
99
|
+
const resp = (await apiGet(`/app/activity/${activityId}/transcript`));
|
|
100
|
+
const turns = (resp.turns || []);
|
|
101
|
+
if (isJsonMode(activities)) {
|
|
102
|
+
jsonOut({ turns });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
printTranscriptTurns(turns);
|
|
55
106
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
107
|
+
}
|
|
108
|
+
// ── Conversations ──
|
|
109
|
+
//
|
|
110
|
+
// Registers the `conversations` subcommand tree under `parent`. The `space`
|
|
111
|
+
// group lists via `/spaces/:slug/conversations` (every member's, keyset-paged);
|
|
112
|
+
// the `personal` group lists via the cross-scope `/app/conversations` filtered
|
|
113
|
+
// to the personal scope. Replaces the old top-level `gobi sense list-transcriptions`.
|
|
114
|
+
export function registerConversationsSubcommands(parent, scope, description) {
|
|
115
|
+
const conversations = parent.command("conversations").description(description);
|
|
116
|
+
// ── List ──
|
|
117
|
+
conversations
|
|
118
|
+
.command("list")
|
|
119
|
+
.description("List conversations captured in this scope (newest first).")
|
|
120
|
+
.option("--limit <n>", "Max items to return (default 30, max 100). Ignored for personal.")
|
|
121
|
+
.option("--before <cursor>", "Pagination cursor from a previous response (nextCursor). Space scope only.")
|
|
122
|
+
.option("--mine", "Only conversations you recorded (space scope; no-op for personal, already yours)")
|
|
62
123
|
.action(async (opts) => {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (!text)
|
|
76
|
-
continue;
|
|
77
|
-
allTurns.push({
|
|
78
|
-
speaker: String(turn.speaker ?? ""),
|
|
79
|
-
timestamp: String(turn.timestamp ?? ""),
|
|
80
|
-
text,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
124
|
+
const { items, pagination } = await scope.listConversations({
|
|
125
|
+
limit: opts.limit ? parseInt(opts.limit, 10) : undefined,
|
|
126
|
+
before: opts.before,
|
|
127
|
+
mine: opts.mine,
|
|
128
|
+
});
|
|
129
|
+
if (isJsonMode(conversations)) {
|
|
130
|
+
jsonOut({ conversations: items, pagination: pagination ?? {} });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (!items.length) {
|
|
134
|
+
console.log("No conversations found.");
|
|
135
|
+
return;
|
|
83
136
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
137
|
+
console.log(`Conversations (${items.length} items, newest first):\n` +
|
|
138
|
+
items.map(formatConversationLine).join("\n") +
|
|
139
|
+
paginationFooter(pagination));
|
|
140
|
+
});
|
|
141
|
+
// ── Transcript (by id) ──
|
|
142
|
+
conversations
|
|
143
|
+
.command("transcript <conversationId>")
|
|
144
|
+
.description("Get a conversation's transcript and summary (owner-only).")
|
|
145
|
+
.action(async (conversationId) => {
|
|
146
|
+
const resp = (await apiGet(`/app/conversations/${conversationId}/transcript`));
|
|
147
|
+
const turns = (resp.turns || []);
|
|
148
|
+
const summary = resp.summary || null;
|
|
149
|
+
if (isJsonMode(conversations)) {
|
|
150
|
+
jsonOut(resp);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (summary && (summary.category || summary.details)) {
|
|
154
|
+
console.log(`Summary: ${summary.category ?? "(uncategorized)"}` +
|
|
155
|
+
(summary.details ? `\n ${summary.details}` : ""));
|
|
156
|
+
console.log("");
|
|
157
|
+
}
|
|
158
|
+
if (resp.status && resp.status !== "ready") {
|
|
159
|
+
console.log(`Status: ${resp.status}`);
|
|
160
|
+
}
|
|
161
|
+
printTranscriptTurns(turns);
|
|
162
|
+
});
|
|
163
|
+
// ── Audio (by id; signed URL, owner-only) ──
|
|
164
|
+
conversations
|
|
165
|
+
.command("audio <conversationId>")
|
|
166
|
+
.description("Get a signed URL for a conversation's combined recording (owner-only; null for analyzer conversations).")
|
|
167
|
+
.action(async (conversationId) => {
|
|
168
|
+
const resp = (await apiGet(`/app/conversations/${conversationId}/audio`));
|
|
169
|
+
const url = resp.url ?? null;
|
|
170
|
+
if (isJsonMode(conversations)) {
|
|
171
|
+
jsonOut({ url });
|
|
116
172
|
return;
|
|
117
173
|
}
|
|
118
|
-
if (!
|
|
119
|
-
console.log("No
|
|
120
|
-
if (lastSeenTime)
|
|
121
|
-
console.log(`Latest data available: ${lastSeenTime}`);
|
|
174
|
+
if (!url) {
|
|
175
|
+
console.log("No audio available for this conversation.");
|
|
122
176
|
return;
|
|
123
177
|
}
|
|
124
|
-
|
|
125
|
-
console.log(`Transcriptions (${filtered.length} turns):\n` + lines.join("\n"));
|
|
126
|
-
if (lastSeenTime)
|
|
127
|
-
console.log(`Latest data available: ${lastSeenTime}`);
|
|
178
|
+
console.log(url);
|
|
128
179
|
});
|
|
129
180
|
}
|
package/dist/commands/space.js
CHANGED
|
@@ -4,6 +4,7 @@ import { requireSpace, selectSpace, setSpaceRequirement, writeSpaceSetting, } fr
|
|
|
4
4
|
import { buildMentionMap, formatAttachmentLines, formatAttachmentSummary, formatPostLabel, formatReactionChips, formatReplyLine, isJsonMode, jsonOut, postBodyText, readStdin, resolveSpaceSlug, unwrapResp, } from "./utils.js";
|
|
5
5
|
import { uploadPostAttachments, assertPostAttachmentMix, } from "../attachments.js";
|
|
6
6
|
import { registerArtifactSubcommands } from "./artifact.js";
|
|
7
|
+
import { registerActivitiesSubcommands, registerConversationsSubcommands, } from "./sense.js";
|
|
7
8
|
function readContent(value) {
|
|
8
9
|
if (value === "-")
|
|
9
10
|
return readStdin();
|
|
@@ -729,4 +730,38 @@ export function registerSpaceCommand(program) {
|
|
|
729
730
|
registerArtifactSubcommands(space, { resolve: () => ({ spaceSlug: resolveSpaceSlug(space) }) }, "Versioned creations attached to posts, scoped to this space (visible to its " +
|
|
730
731
|
"members). Kinds: image | video | gif | markdown | meeting_summary. Always " +
|
|
731
732
|
"human-owned; revisions form a draft/published tree (one published per artifact).");
|
|
733
|
+
// ── Sense: activities + conversations (scoped to this space) ──
|
|
734
|
+
//
|
|
735
|
+
// The conversations list endpoint spans all the user's scopes (returns the caller's recent
|
|
736
|
+
// conversations across all scopes, each tagged with spaceId), so the scope
|
|
737
|
+
// resolves this space's numeric id — via GET /spaces/:slug — to filter it.
|
|
738
|
+
const senseScope = {
|
|
739
|
+
label: "space",
|
|
740
|
+
listActivities: async (params) => {
|
|
741
|
+
const q = { limit: params.limit, before: params.before };
|
|
742
|
+
if (params.mine)
|
|
743
|
+
q.mine = true;
|
|
744
|
+
const resp = (await apiGet(`/spaces/${resolveSpaceSlug(space)}/activities`, q));
|
|
745
|
+
return {
|
|
746
|
+
items: (resp.activities || []),
|
|
747
|
+
pagination: resp.pagination,
|
|
748
|
+
};
|
|
749
|
+
},
|
|
750
|
+
listConversations: async (params) => {
|
|
751
|
+
const q = { limit: params.limit, before: params.before };
|
|
752
|
+
if (params.mine)
|
|
753
|
+
q.mine = true;
|
|
754
|
+
const resp = (await apiGet(`/spaces/${resolveSpaceSlug(space)}/conversations`, q));
|
|
755
|
+
return {
|
|
756
|
+
items: (resp.conversations || []),
|
|
757
|
+
pagination: resp.pagination,
|
|
758
|
+
};
|
|
759
|
+
},
|
|
760
|
+
};
|
|
761
|
+
registerActivitiesSubcommands(space, senseScope, "This space's Sense activities — every member's, attributed to each recorder " +
|
|
762
|
+
"(browse-only). Use `gobi space --space-slug <slug> activities …` or set the " +
|
|
763
|
+
"active space with `gobi space warp`.");
|
|
764
|
+
registerConversationsSubcommands(space, senseScope, "This space's Sense conversations — every member's, attributed to each recorder " +
|
|
765
|
+
"(browse-only; transcript/audio stay owner-only). Use `gobi space --space-slug " +
|
|
766
|
+
"<slug> conversations …` or set the active space with `gobi space warp`.");
|
|
732
767
|
}
|
package/dist/commands/update.js
CHANGED
|
@@ -28,8 +28,8 @@ function detectInstallMethod() {
|
|
|
28
28
|
return "brew";
|
|
29
29
|
}
|
|
30
30
|
try {
|
|
31
|
-
const
|
|
32
|
-
if (gobiBin && gobiBin.includes(
|
|
31
|
+
const npmRootDir = execSync("npm root -g", { encoding: "utf-8" }).trim();
|
|
32
|
+
if (gobiBin && gobiBin.includes(npmRootDir.replace("/lib/node_modules", ""))) {
|
|
33
33
|
return "npm";
|
|
34
34
|
}
|
|
35
35
|
}
|
package/dist/commands/utils.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getSpaceSlug, getVaultSlug } from "./init.js";
|
|
|
5
5
|
export function readStdin() {
|
|
6
6
|
return readFileSync(0, "utf8");
|
|
7
7
|
}
|
|
8
|
-
// The
|
|
8
|
+
// The top-level `--json` flag lives on the root program. Walk up the ancestry so
|
|
9
9
|
// this works regardless of how deeply the calling command is nested (e.g. a
|
|
10
10
|
// leaf under `gobi space artifact …`, not just a direct child of the program).
|
|
11
11
|
export function isJsonMode(cmd) {
|
package/dist/main.js
CHANGED
|
@@ -5,10 +5,8 @@ import { ApiError, GobiError } from "./errors.js";
|
|
|
5
5
|
import { registerAuthCommand } from "./commands/auth.js";
|
|
6
6
|
import { commandRequiresSpace, commandRequiresVault, readSettings, } from "./commands/init.js";
|
|
7
7
|
import { registerSpaceCommand } from "./commands/space.js";
|
|
8
|
-
import { registerGlobalCommand } from "./commands/global.js";
|
|
9
8
|
import { registerPersonalCommand } from "./commands/personal.js";
|
|
10
9
|
import { registerVaultCommand } from "./commands/vault.js";
|
|
11
|
-
import { registerSenseCommand } from "./commands/sense.js";
|
|
12
10
|
import { registerUpdateCommand } from "./commands/update.js";
|
|
13
11
|
import { registerMediaCommand } from "./commands/media.js";
|
|
14
12
|
const require = createRequire(import.meta.url);
|
|
@@ -57,14 +55,12 @@ export async function cli() {
|
|
|
57
55
|
// Register all command groups
|
|
58
56
|
registerAuthCommand(program);
|
|
59
57
|
registerSpaceCommand(program);
|
|
60
|
-
registerGlobalCommand(program);
|
|
61
58
|
registerPersonalCommand(program);
|
|
62
59
|
registerVaultCommand(program);
|
|
63
|
-
registerSenseCommand(program);
|
|
64
60
|
registerUpdateCommand(program);
|
|
65
61
|
registerMediaCommand(program);
|
|
66
|
-
// Artifact subcommands live under `gobi space`
|
|
67
|
-
// by those groups), not as
|
|
62
|
+
// Artifact, activities, and conversations subcommands live under `gobi space`
|
|
63
|
+
// and `gobi personal` (registered by those groups), not as top-level groups.
|
|
68
64
|
// Propagate helpWidth to all subcommands
|
|
69
65
|
const helpWidth = process.stdout.columns || 200;
|
|
70
66
|
for (const cmd of program.commands) {
|
package/package.json
CHANGED
|
@@ -11,12 +11,12 @@ description: >-
|
|
|
11
11
|
allowed-tools: Bash(gobi:*)
|
|
12
12
|
metadata:
|
|
13
13
|
author: gobi-ai
|
|
14
|
-
version: "2.0.
|
|
14
|
+
version: "2.0.40"
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
# gobi-artifact
|
|
18
18
|
|
|
19
|
-
Gobi artifact commands for versioned, post-attachable creations (v2.0.
|
|
19
|
+
Gobi artifact commands for versioned, post-attachable creations (v2.0.40).
|
|
20
20
|
|
|
21
21
|
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
22
22
|
|
|
@@ -51,7 +51,7 @@ Markdown bodies can reference vault notes with `[[wikilinks]]`. Resolution again
|
|
|
51
51
|
|
|
52
52
|
## Important: JSON Mode
|
|
53
53
|
|
|
54
|
-
For programmatic/agent usage, always pass `--json` as a **
|
|
54
|
+
For programmatic/agent usage, always pass `--json` as a **top-level** option (before everything else):
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
57
|
gobi --json personal artifact list --limit 20
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
```
|
|
4
4
|
Usage: gobi personal [options] [command]
|
|
5
5
|
|
|
6
|
-
Personal-space commands (private posts and replies visible only to you).
|
|
7
|
-
|
|
6
|
+
Personal-space commands (private posts and replies visible only to you). Posts/replies live in the same data model as space posts, scoped via personalSpaceUserId so they never surface on the public
|
|
7
|
+
feed.
|
|
8
8
|
|
|
9
9
|
Options:
|
|
10
10
|
-h, --help display help for command
|
|
@@ -8,12 +8,12 @@ description: >-
|
|
|
8
8
|
allowed-tools: Bash(gobi:*)
|
|
9
9
|
metadata:
|
|
10
10
|
author: gobi-ai
|
|
11
|
-
version: "2.0.
|
|
11
|
+
version: "2.0.40"
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
# gobi-core
|
|
15
15
|
|
|
16
|
-
Core CLI commands for the Gobi collaborative knowledge platform (v2.0.
|
|
16
|
+
Core CLI commands for the Gobi collaborative knowledge platform (v2.0.40).
|
|
17
17
|
|
|
18
18
|
## Prerequisites
|
|
19
19
|
|
|
@@ -38,7 +38,6 @@ brew tap gobi-ai/tap && brew install gobi
|
|
|
38
38
|
## Key Concepts
|
|
39
39
|
|
|
40
40
|
- **Vault**: A filetree-backed knowledge home. A local directory becomes a vault when it contains `.gobi/settings.yaml` with a `vaultSlug`. Each vault has a slug (e.g. `brave-path-zr962w`); public profile is configured by a `PUBLISH.md` document at the vault root and pushed via `gobi vault publish`.
|
|
41
|
-
- **Personal Post**: A post on the author's profile that surfaces in the public global feed. Same `Post` data model as a Space Post — only the scope differs.
|
|
42
41
|
- **Space Post**: A post inside a community space.
|
|
43
42
|
- **Space**: A shared community knowledge area. A user can be a member of one or more spaces; each space contains posts, replies, and connected vaults.
|
|
44
43
|
- **Artifact**: A versioned, human-owned creation (image, video, gif, markdown, or meeting_summary) attached to posts. Its revisions form a draft/published tree (at most one published). See the **gobi-artifact** skill.
|
|
@@ -72,19 +71,19 @@ gobi auth status
|
|
|
72
71
|
|
|
73
72
|
| Command family | Needs vault in `.gobi`? | Needs space in `.gobi`? | Per-call override |
|
|
74
73
|
|----------------|------------------------|------------------------|-------------------|
|
|
75
|
-
| `auth …`, `update`, `
|
|
74
|
+
| `auth …`, `update`, `media …`, `personal artifact/activities/conversations …` | no | no | – |
|
|
75
|
+
| `space artifact …` / `space activities …` / `space conversations …` | no | **yes** | parent `--space-slug <slug>` |
|
|
76
76
|
| `vault publish` / `unpublish` / `sync` | **yes** | no | none — must run `gobi vault init` first |
|
|
77
77
|
| `vault init` | no (it sets it up) | no | – |
|
|
78
78
|
| `space list` / `warp [slug]` / `get [slug]` | no | no | – |
|
|
79
79
|
| `space list-topics` / `feed` / `list-posts` / `get-post` / `create-post` / `edit-post` / `delete-post` / `create-reply` / `edit-reply` / `delete-reply` / `list-topic-posts` | no | **yes** | parent `--space-slug <slug>` |
|
|
80
|
-
| `global feed` / `list-posts` / `get-post` / `create-post` / `edit-post` / `delete-post` / `create-reply` / `edit-reply` / `delete-reply` | no | no | – |
|
|
81
80
|
| `personal feed` / `list-posts` / `get-post` / `create-post` / `edit-post` / `delete-post` / `create-reply` / `edit-reply` / `delete-reply` | no | no | – |
|
|
82
81
|
|
|
83
82
|
When a command needs vault or space and neither `.gobi` nor an override flag provides it, the CLI prints a one-line warning before the command runs (e.g. `Vault not set. Run 'gobi vault init' first, or pass --vault-slug.`). The warning is suppressed under `--json`.
|
|
84
83
|
|
|
85
84
|
## Important: JSON Mode
|
|
86
85
|
|
|
87
|
-
For programmatic/agent usage, always pass `--json` as a **
|
|
86
|
+
For programmatic/agent usage, always pass `--json` as a **top-level** option (before the subcommand) to get structured JSON output:
|
|
88
87
|
|
|
89
88
|
```bash
|
|
90
89
|
gobi --json space list
|
|
@@ -10,18 +10,18 @@ description: >-
|
|
|
10
10
|
allowed-tools: Bash(gobi:*)
|
|
11
11
|
metadata:
|
|
12
12
|
author: gobi-ai
|
|
13
|
-
version: "2.0.
|
|
13
|
+
version: "2.0.40"
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# gobi-media
|
|
17
17
|
|
|
18
|
-
Gobi media generation commands (v2.0.
|
|
18
|
+
Gobi media generation commands (v2.0.40).
|
|
19
19
|
|
|
20
20
|
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
21
21
|
|
|
22
22
|
## Important: JSON Mode
|
|
23
23
|
|
|
24
|
-
For programmatic/agent usage, always pass `--json` as a **
|
|
24
|
+
For programmatic/agent usage, always pass `--json` as a **top-level** option (before the subcommand):
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
gobi --json media generate-image --prompt "a sunset over mountains"
|
|
@@ -1,38 +1,88 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gobi-sense
|
|
3
3
|
description: >-
|
|
4
|
-
Gobi
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Gobi Sense commands for browsing activities and conversations captured by the
|
|
5
|
+
wearable and mobile app. Activities (what you were doing) and conversations
|
|
6
|
+
(phone-mic Audio Logs + detected conversations, with transcripts) are scoped
|
|
7
|
+
to a space: `gobi personal activities/conversations …` (your personal space)
|
|
8
|
+
or `gobi space activities/conversations …` (the active team space). Read-only.
|
|
9
|
+
Use when the user wants to review their Sense activities or conversations.
|
|
7
10
|
allowed-tools: Bash(gobi:*)
|
|
8
11
|
metadata:
|
|
9
12
|
author: gobi-ai
|
|
10
|
-
version: "2.0.
|
|
13
|
+
version: "2.0.40"
|
|
11
14
|
---
|
|
12
15
|
|
|
13
16
|
# gobi-sense
|
|
14
17
|
|
|
15
|
-
Gobi
|
|
18
|
+
Gobi Sense commands for browsing activities and conversations (v2.0.40).
|
|
16
19
|
|
|
17
20
|
Requires gobi-cli installed and authenticated. See the **gobi-core** skill for setup.
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
Sense data is captured by Gobi Sense (the wearable) and the mobile app, then ingested by the cloud pipeline. The CLI surface is **read-only** — list records and fetch transcripts, then feed them to whatever analysis you want to run.
|
|
23
|
+
|
|
24
|
+
## Scope: personal vs space
|
|
25
|
+
|
|
26
|
+
Sense data is tagged with the space it was captured in — either your **personal space** or a **team space**. The commands are the same under each scope; pick the group that matches where the data lives:
|
|
27
|
+
|
|
28
|
+
- `gobi personal activities …` / `gobi personal conversations …` — your personal space (visible only to you).
|
|
29
|
+
- `gobi space activities …` / `gobi space conversations …` — the active team space. The space comes from `.gobi/settings.yaml` (set with `gobi space warp <slug>`) or `gobi space --space-slug <slug> activities …`.
|
|
30
|
+
|
|
31
|
+
The examples below use `personal`; swap in `space` to browse a team space.
|
|
32
|
+
|
|
33
|
+
## Activities vs conversations
|
|
34
|
+
|
|
35
|
+
- **activities** — a running log of what you were doing (category + details), each with a start/end time. In a team space, every member's activities show up, attributed to their recorder. Transcripts are owner-only.
|
|
36
|
+
- **conversations** — phone-mic Audio Log recordings plus Sense-detected conversations, each with a transcript and an auto-generated summary. In a team space, every member's conversations show up, attributed to their recorder (the transcript and `audio` signed URL stay owner-only). In your personal space, you see your own.
|
|
37
|
+
|
|
38
|
+
The old `gobi sense list-activities` / `gobi sense list-transcriptions` commands are gone — transcriptions were unified into **conversations**, and both concepts are now space-scoped.
|
|
20
39
|
|
|
21
40
|
## Important: JSON Mode
|
|
22
41
|
|
|
23
|
-
For programmatic/agent usage, always pass `--json` as a **
|
|
42
|
+
For programmatic/agent usage, always pass `--json` as a **top-level** option (before the subcommand):
|
|
24
43
|
|
|
25
44
|
```bash
|
|
26
|
-
gobi --json
|
|
45
|
+
gobi --json personal activities list --limit 30
|
|
46
|
+
gobi --json personal conversations list
|
|
47
|
+
gobi --json space --space-slug my-team activities transcript 978
|
|
27
48
|
```
|
|
28
49
|
|
|
29
|
-
|
|
50
|
+
JSON mode wraps the response as `{"success": true, "data": <…>}` (or `{"success": false, "error": "…"}`).
|
|
51
|
+
|
|
52
|
+
## Typical workflow
|
|
53
|
+
|
|
54
|
+
List recent activities (newest first, paged with `--limit` / `--before`), then pull one's transcript:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gobi --json personal activities list --limit 30
|
|
58
|
+
gobi --json personal activities get 978
|
|
59
|
+
gobi --json personal activities transcript 978
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
List recent conversations in a space, then read a transcript (with its summary) or grab the recording:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
gobi --json space --space-slug my-team conversations list
|
|
66
|
+
gobi --json space --space-slug my-team conversations transcript 12345
|
|
67
|
+
gobi --json space --space-slug my-team conversations audio 12345
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Both list commands are newest-first and page with `--limit` / `--before` (pass a previous response's `nextCursor` to `--before`). Scope difference: **`gobi space … activities/conversations list`** is a complete, fully-paginated per-space history (every member's records). **`gobi personal … conversations list`** is filtered from the cross-scope conversations feed, so it shows your recent personal conversations rather than a fully paginated history (`gobi personal activities list` is fully paginated).
|
|
30
71
|
|
|
31
72
|
## Available Commands
|
|
32
73
|
|
|
33
|
-
|
|
34
|
-
|
|
74
|
+
Under `gobi personal …` (personal space) or `gobi space …` (active team space):
|
|
75
|
+
|
|
76
|
+
- `activities list` — List Sense activities in this scope (`--limit`, `--before`, `--mine`).
|
|
77
|
+
- `activities get <activityId>` — Get one activity's details.
|
|
78
|
+
- `activities transcript <activityId>` — Get an activity's transcript (owner-only).
|
|
79
|
+
- `conversations list` — List conversations captured in this scope, newest first (`--limit`, `--before`, `--mine`). In a space, every member's (attributed to each recorder).
|
|
80
|
+
- `conversations transcript <conversationId>` — Get a conversation's transcript and summary.
|
|
81
|
+
- `conversations audio <conversationId>` — Get a signed URL for the recording (owner-only).
|
|
82
|
+
|
|
83
|
+
All commands are read-only. In a space, `--mine` on either `list` restricts it to records **you** recorded (`user_id = you`); it's a no-op in the personal lane, which is already all yours.
|
|
35
84
|
|
|
36
85
|
## Reference Documentation
|
|
37
86
|
|
|
38
|
-
- [gobi
|
|
87
|
+
- [gobi personal](references/personal.md)
|
|
88
|
+
- [gobi space](references/space.md)
|