@gobi-ai/cli 0.6.11 → 0.6.13

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.
@@ -54,7 +54,7 @@ export async function uploadAttachments(vaultSlug, links, token, options) {
54
54
  console.log(`Uploading [[${link}]]...`);
55
55
  const content = readFileSync(localPath);
56
56
  const queryString = addToSyncfiles ? "?add_to_syncfiles=true" : "";
57
- const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultSlug}/files/${filePath}${queryString}`;
57
+ const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultSlug}/file/${filePath}${queryString}`;
58
58
  const res = await fetch(url, {
59
59
  method: "PUT",
60
60
  headers: {
@@ -100,7 +100,7 @@ export function registerBrainCommand(program) {
100
100
  }
101
101
  const content = readFileSync(filePath, "utf-8");
102
102
  const token = await getValidToken();
103
- const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/files/BRAIN.md`;
103
+ const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/file/BRAIN.md`;
104
104
  const res = await fetch(url, {
105
105
  method: "PUT",
106
106
  headers: {
@@ -125,7 +125,7 @@ export function registerBrainCommand(program) {
125
125
  .action(async () => {
126
126
  const vaultId = getVaultSlug();
127
127
  const token = await getValidToken();
128
- const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/files/BRAIN.md`;
128
+ const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/file/BRAIN.md`;
129
129
  const res = await fetch(url, {
130
130
  method: "DELETE",
131
131
  headers: { Authorization: `Bearer ${token}` },
@@ -16,26 +16,42 @@ export function registerSenseCommand(program) {
16
16
  endTime: opts.endTime,
17
17
  };
18
18
  const resp = (await apiGet("/app/activities", params));
19
- const activities = (resp.activities || []);
20
- const pagination = (resp.pagination || {});
21
- const latestTimestamp = resp.latestTimestamp;
19
+ const strip = ({ id, device_id, created_at, updated_at, ...rest }) => rest;
20
+ const allActivities = (resp.activities || []).map((a) => strip(a));
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;
22
34
  if (isJsonMode(sense)) {
23
- jsonOut({ activities, pagination, latestTimestamp });
35
+ jsonOut({ activities, last_activity, lastSeenTime });
24
36
  return;
25
37
  }
26
- if (!activities.length) {
38
+ if (!activities.length && !last_activity) {
27
39
  console.log("No activities found.");
28
- if (latestTimestamp)
29
- console.log(`Latest data available: ${latestTimestamp}`);
40
+ if (lastSeenTime)
41
+ console.log(`Latest data available: ${lastSeenTime}`);
30
42
  return;
31
43
  }
44
+ if (last_activity) {
45
+ console.log(`Last activity: [${last_activity.device_id}] ${last_activity.category}: ${last_activity.details} (${last_activity.start_time} → ongoing)`);
46
+ }
32
47
  const lines = activities.map((a) => {
33
48
  const endStr = a.end_time ? ` → ${a.end_time}` : "";
34
49
  return `- [${a.device_id}] ${a.category}: ${a.details} (${a.start_time}${endStr})`;
35
50
  });
36
- console.log(`Activities (${activities.length} items):\n` + lines.join("\n"));
37
- if (latestTimestamp)
38
- console.log(`Latest data available: ${latestTimestamp}`);
51
+ if (lines.length)
52
+ console.log(`Activities (${activities.length} items):\n` + lines.join("\n"));
53
+ if (lastSeenTime)
54
+ console.log(`Latest data available: ${lastSeenTime}`);
39
55
  });
40
56
  // ── Transcriptions ──
41
57
  sense
@@ -50,28 +66,47 @@ export function registerSenseCommand(program) {
50
66
  };
51
67
  const resp = (await apiGet("/app/transcriptions", params));
52
68
  const transcriptions = (resp.transcriptions || []);
53
- const pagination = (resp.pagination || {});
54
- const latestTimestamp = resp.latestTimestamp;
69
+ const lastSeenTime = resp.latestTimestamp;
70
+ const allTurns = [];
71
+ for (const t of transcriptions) {
72
+ const rawTurns = (t.turns || []);
73
+ for (const turn of rawTurns) {
74
+ const lines = String(turn.text ?? "").split("\n");
75
+ for (const line of lines) {
76
+ if (!line.trim() || line.trim() === "uv:")
77
+ continue;
78
+ // Me@<timestamp>: <text>
79
+ const meMatch = line.match(/^Me@(\S+):\s*(.*)/);
80
+ if (meMatch) {
81
+ allTurns.push({ speaker: "Me", timestamp: meMatch[1], text: meMatch[2] });
82
+ continue;
83
+ }
84
+ allTurns.push({ speaker: turn.speaker, timestamp: turn.timestamp, text: line });
85
+ }
86
+ }
87
+ }
88
+ // Filter to requested time range and sort
89
+ const startMs = new Date(opts.startTime).getTime();
90
+ const endMs = new Date(opts.endTime).getTime();
91
+ const filtered = allTurns
92
+ .filter((t) => {
93
+ const ts = new Date(t.timestamp).getTime();
94
+ return ts >= startMs && ts <= endMs;
95
+ })
96
+ .sort((a, b) => a.timestamp.localeCompare(b.timestamp));
55
97
  if (isJsonMode(sense)) {
56
- jsonOut({ transcriptions, pagination, latestTimestamp });
98
+ jsonOut({ transcriptions: filtered, lastSeenTime });
57
99
  return;
58
100
  }
59
- if (!transcriptions.length) {
101
+ if (!filtered.length) {
60
102
  console.log("No transcriptions found.");
61
- if (latestTimestamp)
62
- console.log(`Latest data available: ${latestTimestamp}`);
103
+ if (lastSeenTime)
104
+ console.log(`Latest data available: ${lastSeenTime}`);
63
105
  return;
64
106
  }
65
- const lines = [];
66
- for (const t of transcriptions) {
67
- lines.push(`- [${t.device_id}] ${t.created_at}`);
68
- const turns = (t.turns || []);
69
- for (const turn of turns) {
70
- lines.push(` Speaker ${turn.speaker} (${turn.timestamp}): ${turn.text}`);
71
- }
72
- }
73
- console.log(`Transcriptions (${transcriptions.length} items):\n` + lines.join("\n"));
74
- if (latestTimestamp)
75
- console.log(`Latest data available: ${latestTimestamp}`);
107
+ const lines = filtered.map((t) => `- Speaker ${t.speaker} (${t.timestamp}): ${t.text}`);
108
+ console.log(`Transcriptions (${filtered.length} turns):\n` + lines.join("\n"));
109
+ if (lastSeenTime)
110
+ console.log(`Latest data available: ${lastSeenTime}`);
76
111
  });
77
112
  }
@@ -232,7 +232,7 @@ function fileUrl(baseUrl, vaultSlug, filePath) {
232
232
  .split("/")
233
233
  .map((s) => encodeURIComponent(s))
234
234
  .join("/");
235
- return `${baseUrl}/api/v1/vaults/${vaultSlug}/files/${encoded}`;
235
+ return `${baseUrl}/api/v1/vaults/${vaultSlug}/file/${encoded}`;
236
236
  }
237
237
  async function webdriveGet(baseUrl, vaultSlug, filePath, token) {
238
238
  const res = await fetch(fileUrl(baseUrl, vaultSlug, filePath), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobi-ai/cli",
3
- "version": "0.6.11",
3
+ "version": "0.6.13",
4
4
  "description": "CLI client for the Gobi collaborative knowledge platform",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,12 +10,12 @@ description: >-
10
10
  allowed-tools: Bash(gobi:*)
11
11
  metadata:
12
12
  author: gobi-ai
13
- version: "0.6.10"
13
+ version: "0.6.13"
14
14
  ---
15
15
 
16
16
  # gobi-cli
17
17
 
18
- A CLI client for the Gobi collaborative knowledge platform (v0.6.10).
18
+ A CLI client for the Gobi collaborative knowledge platform (v0.6.13).
19
19
 
20
20
  ## Prerequisites
21
21