@gobi-ai/cli 1.3.1 → 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.
- package/.claude-plugin/marketplace.json +3 -2
- package/.claude-plugin/plugin.json +2 -1
- package/README.md +13 -0
- package/dist/commands/notes.js +153 -0
- package/dist/commands/proposal.js +158 -0
- package/dist/main.js +4 -0
- package/package.json +1 -1
- package/skills/gobi-notes/SKILL.md +52 -0
- package/skills/gobi-notes/references/notes.md +82 -0
|
@@ -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
|
},
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"./skills/gobi-space",
|
|
21
21
|
"./skills/gobi-brain",
|
|
22
22
|
"./skills/gobi-feed",
|
|
23
|
+
"./skills/gobi-notes",
|
|
23
24
|
"./skills/gobi-media",
|
|
24
25
|
"./skills/gobi-sense",
|
|
25
26
|
"./skills/gobi-homepage"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gobi",
|
|
3
3
|
"description": "Manage the Gobi collaborative knowledge platform from the command line",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.3",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "gobi-ai"
|
|
7
7
|
},
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"./skills/gobi-space",
|
|
12
12
|
"./skills/gobi-brain",
|
|
13
13
|
"./skills/gobi-feed",
|
|
14
|
+
"./skills/gobi-notes",
|
|
14
15
|
"./skills/gobi-media",
|
|
15
16
|
"./skills/gobi-sense",
|
|
16
17
|
"./skills/gobi-homepage"
|
package/README.md
CHANGED
|
@@ -137,6 +137,19 @@ Public brains are accessible at `https://gobispace.com/@{vaultSlug}`.
|
|
|
137
137
|
|
|
138
138
|
Times are ISO 8601 UTC (e.g. `2026-03-20T00:00:00Z`).
|
|
139
139
|
|
|
140
|
+
### Notes
|
|
141
|
+
|
|
142
|
+
| Command | Description |
|
|
143
|
+
|---------|-------------|
|
|
144
|
+
| `gobi notes list [--date YYYY-MM-DD]` | List your notes (recent via cursor, or all for a day) |
|
|
145
|
+
| `gobi notes get <id>` | Get a single note |
|
|
146
|
+
| `gobi notes create --content <c>` | Create a note (use `-` to read content from stdin) |
|
|
147
|
+
| `gobi notes edit <id> [--content <c>] [--agent-id <id>]` | Edit a note (at least one required; `--agent-id null` clears the link) |
|
|
148
|
+
| `gobi notes delete <id>` | Delete a note you authored |
|
|
149
|
+
|
|
150
|
+
`notes list` and `notes create` accept `--timezone <iana>` (default: system timezone) for day boundaries.
|
|
151
|
+
`notes list` also accepts `--limit`/`--cursor` for pagination.
|
|
152
|
+
|
|
140
153
|
### Sync
|
|
141
154
|
|
|
142
155
|
| Command | Description |
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import { apiGet, apiPost, apiPatch, apiDelete } from "../client.js";
|
|
3
|
+
import { isJsonMode, jsonOut, unwrapResp } from "./utils.js";
|
|
4
|
+
function defaultTimezone() {
|
|
5
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
6
|
+
}
|
|
7
|
+
function formatNoteLine(note) {
|
|
8
|
+
const content = note.content ?? "";
|
|
9
|
+
const snippet = content
|
|
10
|
+
? content.length > 80
|
|
11
|
+
? content.slice(0, 80) + "…"
|
|
12
|
+
: content
|
|
13
|
+
: "(no content)";
|
|
14
|
+
const attachments = (note.attachments || []);
|
|
15
|
+
const attachStr = attachments.length
|
|
16
|
+
? `, ${attachments.length} ${attachments.length === 1 ? "attachment" : "attachments"}`
|
|
17
|
+
: "";
|
|
18
|
+
const agent = note.agentId != null ? `, agent: ${note.agentId}` : "";
|
|
19
|
+
return `- [${note.id}] "${snippet.replace(/\n/g, " ")}" (${note.eventDate}${agent}${attachStr}, updated ${note.updatedAt})`;
|
|
20
|
+
}
|
|
21
|
+
export function registerNotesCommand(program) {
|
|
22
|
+
const notes = program
|
|
23
|
+
.command("notes")
|
|
24
|
+
.description("Personal notes (create, list, get, edit, delete).");
|
|
25
|
+
// ── List ──
|
|
26
|
+
notes
|
|
27
|
+
.command("list")
|
|
28
|
+
.description("List your notes. Without --date, returns recent notes via cursor pagination. With --date, returns all notes for that day.")
|
|
29
|
+
.option("--date <date>", "Filter to a single day (YYYY-MM-DD)")
|
|
30
|
+
.option("--timezone <tz>", "IANA timezone name (default: system timezone)")
|
|
31
|
+
.option("--limit <number>", "Items per page (1-100)", "50")
|
|
32
|
+
.option("--cursor <string>", "Pagination cursor from previous response")
|
|
33
|
+
.action(async (opts) => {
|
|
34
|
+
const params = {
|
|
35
|
+
timezone: opts.timezone || defaultTimezone(),
|
|
36
|
+
limit: parseInt(opts.limit, 10),
|
|
37
|
+
};
|
|
38
|
+
if (opts.date)
|
|
39
|
+
params.date = opts.date;
|
|
40
|
+
if (opts.cursor)
|
|
41
|
+
params.cursor = opts.cursor;
|
|
42
|
+
const resp = (await apiGet(`/app/notes`, params));
|
|
43
|
+
const items = (resp.data || []);
|
|
44
|
+
const pagination = (resp.pagination || {});
|
|
45
|
+
if (isJsonMode(notes)) {
|
|
46
|
+
jsonOut({ items, pagination });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (!items.length) {
|
|
50
|
+
console.log("No notes found.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const lines = items.map(formatNoteLine);
|
|
54
|
+
const footer = pagination.hasMore
|
|
55
|
+
? `\n Next cursor: ${pagination.nextCursor}`
|
|
56
|
+
: "";
|
|
57
|
+
console.log(`Notes (${items.length} items):\n` + lines.join("\n") + footer);
|
|
58
|
+
});
|
|
59
|
+
// ── Get ──
|
|
60
|
+
notes
|
|
61
|
+
.command("get <noteId>")
|
|
62
|
+
.description("Get a single note by id.")
|
|
63
|
+
.action(async (noteId) => {
|
|
64
|
+
const resp = (await apiGet(`/app/notes/${noteId}`));
|
|
65
|
+
const note = unwrapResp(resp);
|
|
66
|
+
if (isJsonMode(notes)) {
|
|
67
|
+
jsonOut(note);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const attachments = (note.attachments || []);
|
|
71
|
+
const attachLines = attachments.map((a) => ` - [${a.id}] ${a.mediaUrl} (position ${a.position})`);
|
|
72
|
+
const agentLine = note.agentId != null ? `Agent: ${note.agentId}\n` : "";
|
|
73
|
+
const output = [
|
|
74
|
+
`Note: ${note.id}`,
|
|
75
|
+
`Date: ${note.eventDate}`,
|
|
76
|
+
`Created: ${note.createdAt}`,
|
|
77
|
+
`Updated: ${note.updatedAt}`,
|
|
78
|
+
agentLine.trimEnd(),
|
|
79
|
+
"",
|
|
80
|
+
note.content || "(no content)",
|
|
81
|
+
...(attachLines.length ? ["", `Attachments (${attachLines.length}):`, ...attachLines] : []),
|
|
82
|
+
]
|
|
83
|
+
.filter((line) => line !== "")
|
|
84
|
+
.concat([""])
|
|
85
|
+
.join("\n")
|
|
86
|
+
.trimEnd();
|
|
87
|
+
console.log(output);
|
|
88
|
+
});
|
|
89
|
+
// ── Create ──
|
|
90
|
+
notes
|
|
91
|
+
.command("create")
|
|
92
|
+
.description("Create a note. Provide --content (use '-' for stdin) and/or attachments.")
|
|
93
|
+
.option("--content <content>", 'Note content (markdown supported, use "-" for stdin)')
|
|
94
|
+
.option("--timezone <tz>", "IANA timezone name (default: system timezone)")
|
|
95
|
+
.option("--agent-id <number>", "Optional agent id to associate with the note")
|
|
96
|
+
.action(async (opts) => {
|
|
97
|
+
if (!opts.content) {
|
|
98
|
+
throw new Error("--content is required (use '-' to read from stdin)");
|
|
99
|
+
}
|
|
100
|
+
const content = opts.content === "-" ? readFileSync("/dev/stdin", "utf8") : opts.content;
|
|
101
|
+
const body = {
|
|
102
|
+
content,
|
|
103
|
+
timezone: opts.timezone || defaultTimezone(),
|
|
104
|
+
};
|
|
105
|
+
if (opts.agentId)
|
|
106
|
+
body.agentId = parseInt(opts.agentId, 10);
|
|
107
|
+
const resp = (await apiPost(`/app/notes`, body));
|
|
108
|
+
const note = unwrapResp(resp);
|
|
109
|
+
if (isJsonMode(notes)) {
|
|
110
|
+
jsonOut(note);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
console.log(`Note created!\n ID: ${note.id}\n Date: ${note.eventDate}\n Created: ${note.createdAt}`);
|
|
114
|
+
});
|
|
115
|
+
// ── Edit ──
|
|
116
|
+
notes
|
|
117
|
+
.command("edit <noteId>")
|
|
118
|
+
.description("Edit a note. Provide --content and/or --agent-id.")
|
|
119
|
+
.option("--content <content>", 'New note content (markdown supported, use "-" for stdin)')
|
|
120
|
+
.option("--agent-id <number>", 'New agent id, or "null" to clear the association')
|
|
121
|
+
.action(async (noteId, opts) => {
|
|
122
|
+
if (opts.content == null && opts.agentId == null) {
|
|
123
|
+
throw new Error("Provide at least --content or --agent-id to update.");
|
|
124
|
+
}
|
|
125
|
+
const body = {};
|
|
126
|
+
if (opts.content != null) {
|
|
127
|
+
body.content =
|
|
128
|
+
opts.content === "-" ? readFileSync("/dev/stdin", "utf8") : opts.content;
|
|
129
|
+
}
|
|
130
|
+
if (opts.agentId != null) {
|
|
131
|
+
body.agentId = opts.agentId === "null" ? null : parseInt(opts.agentId, 10);
|
|
132
|
+
}
|
|
133
|
+
const resp = (await apiPatch(`/app/notes/${noteId}`, body));
|
|
134
|
+
const note = unwrapResp(resp);
|
|
135
|
+
if (isJsonMode(notes)) {
|
|
136
|
+
jsonOut(note);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
console.log(`Note edited!\n ID: ${note.id}\n Updated: ${note.updatedAt}`);
|
|
140
|
+
});
|
|
141
|
+
// ── Delete ──
|
|
142
|
+
notes
|
|
143
|
+
.command("delete <noteId>")
|
|
144
|
+
.description("Delete a note you authored.")
|
|
145
|
+
.action(async (noteId) => {
|
|
146
|
+
await apiDelete(`/app/notes/${noteId}`);
|
|
147
|
+
if (isJsonMode(notes)) {
|
|
148
|
+
jsonOut({ id: noteId });
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
console.log(`Note ${noteId} deleted.`);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
@@ -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
|
@@ -7,11 +7,13 @@ import { registerInitCommand, printContext } from "./commands/init.js";
|
|
|
7
7
|
import { registerSpaceCommand } from "./commands/space.js";
|
|
8
8
|
import { registerBrainCommand } from "./commands/brain.js";
|
|
9
9
|
import { registerFeedCommand } from "./commands/feed.js";
|
|
10
|
+
import { registerNotesCommand } from "./commands/notes.js";
|
|
10
11
|
import { registerSessionsCommand } from "./commands/sessions.js";
|
|
11
12
|
import { registerSenseCommand } from "./commands/sense.js";
|
|
12
13
|
import { registerSyncCommand } from "./commands/sync.js";
|
|
13
14
|
import { registerUpdateCommand } from "./commands/update.js";
|
|
14
15
|
import { registerMediaCommand } from "./commands/media.js";
|
|
16
|
+
import { registerProposalCommand } from "./commands/proposal.js";
|
|
15
17
|
const require = createRequire(import.meta.url);
|
|
16
18
|
const { version } = require("../package.json");
|
|
17
19
|
const SKIP_BANNER_COMMANDS = new Set(["auth", "init", "update"]);
|
|
@@ -35,11 +37,13 @@ export async function cli() {
|
|
|
35
37
|
registerSpaceCommand(program);
|
|
36
38
|
registerBrainCommand(program);
|
|
37
39
|
registerFeedCommand(program);
|
|
40
|
+
registerNotesCommand(program);
|
|
38
41
|
registerSessionsCommand(program);
|
|
39
42
|
registerSenseCommand(program);
|
|
40
43
|
registerSyncCommand(program);
|
|
41
44
|
registerUpdateCommand(program);
|
|
42
45
|
registerMediaCommand(program);
|
|
46
|
+
registerProposalCommand(program);
|
|
43
47
|
// Propagate helpWidth to all subcommands
|
|
44
48
|
const helpWidth = process.stdout.columns || 200;
|
|
45
49
|
for (const cmd of program.commands) {
|
package/package.json
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gobi-notes
|
|
3
|
+
description: >-
|
|
4
|
+
Gobi notes commands for personal note-taking: create, list (by day or
|
|
5
|
+
cursor), get, edit, and delete notes. Notes are private, dated entries
|
|
6
|
+
optionally tied to an agent. Use when the user wants to capture, review,
|
|
7
|
+
or modify their own notes.
|
|
8
|
+
allowed-tools: Bash(gobi:*)
|
|
9
|
+
metadata:
|
|
10
|
+
author: gobi-ai
|
|
11
|
+
version: "1.3.2"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# gobi-notes
|
|
15
|
+
|
|
16
|
+
Gobi notes commands for personal note-taking (v1.3.2).
|
|
17
|
+
|
|
18
|
+
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
19
|
+
|
|
20
|
+
## What is a note?
|
|
21
|
+
|
|
22
|
+
A note is a private, dated entry you keep for yourself. Each note has:
|
|
23
|
+
- **content** — markdown text (optional if attachments are present, but the CLI requires `--content` since it doesn't yet upload attachments)
|
|
24
|
+
- **eventDate** — derived from your timezone at create time, used to group notes by day
|
|
25
|
+
- **agentId** — optional association with a Gobi agent
|
|
26
|
+
|
|
27
|
+
Notes are user-private — only you can see, edit, or delete your own notes.
|
|
28
|
+
|
|
29
|
+
## Timezone
|
|
30
|
+
|
|
31
|
+
`gobi notes list` and `gobi notes create` need a timezone to compute the calendar day. The CLI auto-detects your system timezone via `Intl.DateTimeFormat().resolvedOptions().timeZone`. Override with `--timezone <iana-name>` (e.g. `America/Los_Angeles`).
|
|
32
|
+
|
|
33
|
+
## Important: JSON Mode
|
|
34
|
+
|
|
35
|
+
For programmatic/agent usage, always pass `--json` as a **global** option (before the subcommand):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
gobi --json notes list --date 2026-04-27
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Available Commands
|
|
42
|
+
|
|
43
|
+
- `gobi notes` — Personal notes (create, list, get, edit, delete).
|
|
44
|
+
- `gobi notes list` — List your notes. Without --date, returns recent notes via cursor pagination. With --date, returns all notes for that day.
|
|
45
|
+
- `gobi notes get` — Get a single note by id.
|
|
46
|
+
- `gobi notes create` — Create a note. Provide --content (use '-' for stdin) and/or attachments.
|
|
47
|
+
- `gobi notes edit` — Edit a note. Provide --content and/or --agent-id.
|
|
48
|
+
- `gobi notes delete` — Delete a note you authored.
|
|
49
|
+
|
|
50
|
+
## Reference Documentation
|
|
51
|
+
|
|
52
|
+
- [gobi notes](references/notes.md)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# gobi notes
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Usage: gobi notes [options] [command]
|
|
5
|
+
|
|
6
|
+
Personal notes (create, list, get, edit, delete).
|
|
7
|
+
|
|
8
|
+
Options:
|
|
9
|
+
-h, --help display help for command
|
|
10
|
+
|
|
11
|
+
Commands:
|
|
12
|
+
list [options] List your notes. Without --date, returns recent notes via cursor pagination. With --date, returns all notes for that day.
|
|
13
|
+
get <noteId> Get a single note by id.
|
|
14
|
+
create [options] Create a note. Provide --content (use '-' for stdin) and/or attachments.
|
|
15
|
+
edit [options] <noteId> Edit a note. Provide --content and/or --agent-id.
|
|
16
|
+
delete <noteId> Delete a note you authored.
|
|
17
|
+
help [command] display help for command
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## list
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Usage: gobi notes list [options]
|
|
24
|
+
|
|
25
|
+
List your notes. Without --date, returns recent notes via cursor pagination. With --date, returns all notes for that day.
|
|
26
|
+
|
|
27
|
+
Options:
|
|
28
|
+
--date <date> Filter to a single day (YYYY-MM-DD)
|
|
29
|
+
--timezone <tz> IANA timezone name (default: system timezone)
|
|
30
|
+
--limit <number> Items per page (1-100) (default: "50")
|
|
31
|
+
--cursor <string> Pagination cursor from previous response
|
|
32
|
+
-h, --help display help for command
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## get
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
Usage: gobi notes get [options] <noteId>
|
|
39
|
+
|
|
40
|
+
Get a single note by id.
|
|
41
|
+
|
|
42
|
+
Options:
|
|
43
|
+
-h, --help display help for command
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## create
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Usage: gobi notes create [options]
|
|
50
|
+
|
|
51
|
+
Create a note. Provide --content (use '-' for stdin) and/or attachments.
|
|
52
|
+
|
|
53
|
+
Options:
|
|
54
|
+
--content <content> Note content (markdown supported, use "-" for stdin)
|
|
55
|
+
--timezone <tz> IANA timezone name (default: system timezone)
|
|
56
|
+
--agent-id <number> Optional agent id to associate with the note
|
|
57
|
+
-h, --help display help for command
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## edit
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Usage: gobi notes edit [options] <noteId>
|
|
64
|
+
|
|
65
|
+
Edit a note. Provide --content and/or --agent-id.
|
|
66
|
+
|
|
67
|
+
Options:
|
|
68
|
+
--content <content> New note content (markdown supported, use "-" for stdin)
|
|
69
|
+
--agent-id <number> New agent id, or "null" to clear the association
|
|
70
|
+
-h, --help display help for command
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## delete
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
Usage: gobi notes delete [options] <noteId>
|
|
77
|
+
|
|
78
|
+
Delete a note you authored.
|
|
79
|
+
|
|
80
|
+
Options:
|
|
81
|
+
-h, --help display help for command
|
|
82
|
+
```
|