@kiipu/cli 0.0.8 → 0.0.9

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/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # Kiipu CLI
2
2
 
3
- Publish to Kiipu from your terminal.
3
+ Create Kiipu notes from your terminal.
4
4
 
5
- `@kiipu/cli` is the official command line interface for Kiipu. It is the best place to start if you want to authenticate locally and post directly from the command line.
5
+ `@kiipu/cli` is the official command line interface for Kiipu. It is the best place to start if you want to authenticate locally and note directly from the command line.
6
6
 
7
7
  Use it to:
8
8
 
9
9
  - sign in on the current device
10
- - ask questions over your saved posts
11
- - publish posts from the command line
12
- - delete, restore, or permanently remove posts by id
10
+ - ask questions over your saved notes
11
+ - create notes from the command line
12
+ - delete, restore, or permanently remove notes by id
13
13
  - verify local authentication and API access with `kiipu doctor`
14
14
 
15
15
  If you want Claude Code integration on top of the CLI, use `@kiipu/claude-plugin`.
@@ -28,10 +28,10 @@ npm install -g @kiipu/cli
28
28
  kiipu auth login
29
29
  ```
30
30
 
31
- 2. Publish a post:
31
+ 2. Create a note:
32
32
 
33
33
  ```bash
34
- kiipu post create "Hello Kiipu"
34
+ kiipu note create "Hello Kiipu"
35
35
  ```
36
36
 
37
37
  3. Confirm local setup:
@@ -40,7 +40,7 @@ kiipu post create "Hello Kiipu"
40
40
  kiipu doctor
41
41
  ```
42
42
 
43
- 4. Ask over your saved posts:
43
+ 4. Ask over your saved notes:
44
44
 
45
45
  ```bash
46
46
  kiipu ask "What did I save about the roadmap?"
@@ -51,7 +51,7 @@ kiipu ask "What did I save about the roadmap?"
51
51
  ```bash
52
52
  kiipu auth login
53
53
  kiipu ask "What should I follow up on?"
54
- kiipu post create "Ship the beta today"
54
+ kiipu note create "Ship the beta today"
55
55
  kiipu auth status
56
56
  ```
57
57
 
@@ -73,21 +73,21 @@ kiipu auth status
73
73
  kiipu auth logout
74
74
  ```
75
75
 
76
- ## Posting
76
+ ## Noteing
77
77
 
78
- Create a post:
78
+ Create a note:
79
79
 
80
80
  ```bash
81
- kiipu post create "Ship the beta today"
82
- kiipu post create --content "Ship the beta today"
81
+ kiipu note create "Ship the beta today"
82
+ kiipu note create --content "Ship the beta today"
83
83
  ```
84
84
 
85
- Delete, restore, or permanently remove a post by id:
85
+ Delete, restore, or permanently remove a note by id:
86
86
 
87
87
  ```bash
88
- kiipu post delete --id post_123
89
- kiipu post restore --id post_123
90
- kiipu post purge --id post_123
88
+ kiipu note delete --id note_123
89
+ kiipu note restore --id note_123
90
+ kiipu note purge --id note_123
91
91
  ```
92
92
 
93
93
  ## Ask
@@ -118,10 +118,10 @@ kiipu ask "What did I save about the roadmap?"
118
118
  kiipu ask history --limit 10
119
119
  kiipu ask show --id conv_123
120
120
 
121
- kiipu post create "Hello Kiipu"
122
- kiipu post delete --id post_123
123
- kiipu post restore --id post_123
124
- kiipu post purge --id post_123
121
+ kiipu note create "Hello Kiipu"
122
+ kiipu note delete --id note_123
123
+ kiipu note restore --id note_123
124
+ kiipu note purge --id note_123
125
125
 
126
126
  kiipu doctor
127
127
  kiipu --help
@@ -152,5 +152,5 @@ See the full command reference in the terminal:
152
152
  kiipu --help
153
153
  kiipu auth --help
154
154
  kiipu ask --help
155
- kiipu post --help
155
+ kiipu note --help
156
156
  ```
@@ -90,12 +90,7 @@ function readQuestion(args) {
90
90
  if (explicit) {
91
91
  return explicit;
92
92
  }
93
- return stripKnownFlags(args, [
94
- '--question',
95
- '--conversation-id',
96
- '--top-k',
97
- '--source-mode',
98
- ])
93
+ return stripKnownFlags(args, ['--question', '--conversation-id', '--top-k', '--source-mode'])
99
94
  .join(' ')
100
95
  .trim();
101
96
  }
@@ -1,5 +1,5 @@
1
1
  import { saveKiipuConfig } from '../config/config.js';
2
- import { createAuthState, createLoopbackServer, createPkcePair, getDefaultDeviceName, openBrowser, waitForEnterBeforeOpeningBrowser } from '../lib/browser-auth.js';
2
+ import { createAuthState, createLoopbackServer, createPkcePair, getDefaultDeviceName, openBrowser, waitForEnterBeforeOpeningBrowser, } from '../lib/browser-auth.js';
3
3
  import { KiipuUserApiClient } from '../lib/kiipu-user-client.js';
4
4
  import { logCliEvent } from '../logger/cli-logger.js';
5
5
  async function storeAuthenticatedConfig(config, payload) {
@@ -14,11 +14,15 @@ export async function runDoctorCommand(config) {
14
14
  const checks = [];
15
15
  let ok = true;
16
16
  const apiBaseUrlConfig = getConfiguredApiBaseUrl();
17
- checks.push(config.apiKey ? `OK API key: ${config.keyPrefix ?? 'configured'}` : 'Missing API key. Run `kiipu auth login`.');
17
+ checks.push(config.apiKey
18
+ ? `OK API key: ${config.keyPrefix ?? 'configured'}`
19
+ : 'Missing API key. Run `kiipu auth login`.');
18
20
  if (!(config.apiKey || process.env.KIIPU_API_KEY)) {
19
21
  ok = false;
20
22
  }
21
- checks.push(config.apiKey || process.env.KIIPU_API_KEY ? 'OK post API auth: configured' : 'Missing API key for post requests.');
23
+ checks.push(config.apiKey || process.env.KIIPU_API_KEY
24
+ ? 'OK note API auth: configured'
25
+ : 'Missing API key for note requests.');
22
26
  checks.push(apiBaseUrlConfig.source === 'env'
23
27
  ? `WARN API base URL override: ${config.apiBaseUrl}`
24
28
  : `OK API base URL: ${config.apiBaseUrl}`);
@@ -42,7 +46,9 @@ export async function runDoctorCommand(config) {
42
46
  if (!authStatus.ok) {
43
47
  ok = false;
44
48
  }
45
- checks.push(authStatus.ok ? `OK API key auth: ${authStatus.data.username}` : `API key auth failed: ${authStatus.error.message}`);
49
+ checks.push(authStatus.ok
50
+ ? `OK API key auth: ${authStatus.data.username}`
51
+ : `API key auth failed: ${authStatus.error.message}`);
46
52
  }
47
53
  try {
48
54
  await access(configPath);
@@ -16,7 +16,7 @@ export function getHelpResult(command) {
16
16
  ' kiipu ask show --id <conversationId>',
17
17
  '',
18
18
  'Description:',
19
- ' Ask questions over your Kiipu posts using the same conversation-aware Ask surface as the web app.',
19
+ ' Ask questions over your Kiipu notes using the same conversation-aware Ask surface as the web app.',
20
20
  '',
21
21
  'Options:',
22
22
  ' --question "<text>" Question to ask when not using a positional argument',
@@ -36,64 +36,64 @@ export function getHelpResult(command) {
36
36
  ]),
37
37
  };
38
38
  }
39
- if (command === 'post') {
39
+ if (command === 'note') {
40
40
  return {
41
41
  ok: true,
42
42
  message: block([
43
43
  'Kiipu CLI',
44
44
  '',
45
45
  'Usage:',
46
- ' kiipu post create --content "<text>"',
47
- ' kiipu post create "<text>"',
48
- ' kiipu post list [--tag <tag>] [--sort <updatedAt|createdAt|title>] [--starred] [--deleted]',
49
- ' kiipu post search <query>',
50
- ' kiipu post search --query "<query>"',
51
- ' kiipu post show --id <postId>',
52
- ' kiipu post update --id <postId> --content "<text>" [--title "<title>"] [--visibility public|private] [--tags <a,b,c>]',
53
- ' kiipu post star --id <postId>',
54
- ' kiipu post pin --id <postId>',
55
- ' kiipu post delete --id <postId>',
56
- ' kiipu post restore --id <postId>',
57
- ' kiipu post purge --id <postId>',
46
+ ' kiipu note create --content "<text>"',
47
+ ' kiipu note create "<text>"',
48
+ ' kiipu note list [--tag <tag>] [--sort <updatedAt|createdAt|title>] [--starred] [--deleted]',
49
+ ' kiipu note search <query>',
50
+ ' kiipu note search --query "<query>"',
51
+ ' kiipu note show --id <noteId>',
52
+ ' kiipu note update --id <noteId> --content "<text>" [--title "<title>"] [--visibility public|private] [--tags <a,b,c>]',
53
+ ' kiipu note star --id <noteId>',
54
+ ' kiipu note pin --id <noteId>',
55
+ ' kiipu note delete --id <noteId>',
56
+ ' kiipu note restore --id <noteId>',
57
+ ' kiipu note purge --id <noteId>',
58
58
  '',
59
59
  'Description:',
60
- ' Run direct Kiipu post actions from the local CLI.',
60
+ ' Run direct Kiipu note actions from the local CLI.',
61
61
  '',
62
62
  'Actions:',
63
- ' create Create a new post',
64
- ' list List your published, starred, or deleted posts',
65
- ' search Search your published posts',
66
- ' show Show one post with full metadata',
67
- ' update Update post content and metadata',
68
- ' star Toggle a post star',
69
- ' pin Toggle a post pin',
70
- ' delete Soft-delete an existing post by explicit id',
71
- ' restore Restore a deleted post by explicit id',
72
- ' purge Permanently delete a post by explicit id',
63
+ ' create Create a new note',
64
+ ' list List your active, starred, or deleted notes',
65
+ ' search Search your active notes',
66
+ ' show Show one note with full metadata',
67
+ ' update Update note content and metadata',
68
+ ' star Toggle a note star',
69
+ ' pin Toggle a note pin',
70
+ ' delete Soft-delete an existing note by explicit id',
71
+ ' restore Restore a deleted note by explicit id',
72
+ ' purge Permanently delete a note by explicit id',
73
73
  '',
74
74
  'Options:',
75
- ' --content "<text>" Post content for create',
76
- ' --id <postId> Required for show, update, star, pin, delete, restore, and purge',
77
- ' --query "<query>" Search query for post search',
78
- ' --tag <tag> Filter post list results by tag',
75
+ ' --content "<text>" Note content for create',
76
+ ' --id <noteId> Required for show, update, star, pin, delete, restore, and purge',
77
+ ' --query "<query>" Search query for note search',
78
+ ' --tag <tag> Filter note list results by tag',
79
79
  ' --sort <field> One of updatedAt, createdAt, or title',
80
- ' --starred List only starred posts',
81
- ' --deleted List only deleted posts',
82
- ' --title "<title>" Optional title for post update',
83
- ' --visibility <value> Optional visibility for post update',
84
- ' --tags <a,b,c> Optional comma-separated tags for post update',
80
+ ' --starred List only starred notes',
81
+ ' --deleted List only deleted notes',
82
+ ' --title "<title>" Optional title for note update',
83
+ ' --visibility <value> Optional visibility for note update',
84
+ ' --tags <a,b,c> Optional comma-separated tags for note update',
85
85
  '',
86
86
  'Examples:',
87
- ' kiipu post create "Hello Kiipu"',
88
- ' kiipu post list --sort updatedAt',
89
- ' kiipu post search "roadmap"',
90
- ' kiipu post show --id 123',
91
- ' kiipu post update --id 123 --content "Updated text" --tags work,#notes',
92
- ' kiipu post star --id 123',
93
- ' kiipu post pin --id 123',
94
- ' kiipu post create --content "Hello Kiipu"',
95
- ' kiipu post delete --id 123',
96
- ' kiipu post restore --id 123',
87
+ ' kiipu note create "Hello Kiipu"',
88
+ ' kiipu note list --sort updatedAt',
89
+ ' kiipu note search "roadmap"',
90
+ ' kiipu note show --id 123',
91
+ ' kiipu note update --id 123 --content "Updated text" --tags work,#notes',
92
+ ' kiipu note star --id 123',
93
+ ' kiipu note pin --id 123',
94
+ ' kiipu note create --content "Hello Kiipu"',
95
+ ' kiipu note delete --id 123',
96
+ ' kiipu note restore --id 123',
97
97
  ]),
98
98
  };
99
99
  }
@@ -173,8 +173,8 @@ export function getHelpResult(command) {
173
173
  ' kiipu <command> [options]',
174
174
  '',
175
175
  'Core commands:',
176
- ' ask Ask questions over your Kiipu posts and browse Ask conversations',
177
- ' post Create, browse, update, and delete posts with direct CLI arguments',
176
+ ' ask Ask questions over your Kiipu notes and browse Ask conversations',
177
+ ' note Create, browse, update, and delete notes with direct CLI arguments',
178
178
  ' auth Manage local API key authentication',
179
179
  ' doctor Check local setup, API access, and wrapper readiness',
180
180
  ' skills Show where the Claude Code plugin package lives',
@@ -182,10 +182,10 @@ export function getHelpResult(command) {
182
182
  'Core examples:',
183
183
  ' kiipu ask "What changed in my roadmap notes?"',
184
184
  ' kiipu ask history --limit 10',
185
- ' kiipu post create "Hello Kiipu"',
186
- ' kiipu post list --starred',
187
- ' kiipu post search "Hello"',
188
- ' kiipu post delete --id 123',
185
+ ' kiipu note create "Hello Kiipu"',
186
+ ' kiipu note list --starred',
187
+ ' kiipu note search "Hello"',
188
+ ' kiipu note delete --id 123',
189
189
  ' kiipu auth login',
190
190
  ' kiipu doctor',
191
191
  ' claude --plugin-dir ./packages/claude-plugin',
@@ -1,6 +1,6 @@
1
- import { formatPostCollection, formatPostDetail } from '../lib/post-formatters.js';
1
+ import { formatNoteCollection, formatNoteDetail } from '../lib/note-formatters.js';
2
2
  import { KiipuUserApiClient } from '../lib/kiipu-user-client.js';
3
- import { executePostAction } from '../lib/post-actions.js';
3
+ import { executeNoteAction } from '../lib/note-actions.js';
4
4
  import { hasFlag, readFlag } from '../utils/args.js';
5
5
  const actions = new Set([
6
6
  'create',
@@ -18,21 +18,21 @@ const sortValues = new Set(['updatedAt', 'createdAt', 'title']);
18
18
  function usage(action) {
19
19
  switch (action) {
20
20
  case 'create':
21
- return 'Usage: kiipu post create --content "<text>"\n or: kiipu post create "<text>"';
21
+ return 'Usage: kiipu note create --content "<text>"\n or: kiipu note create "<text>"';
22
22
  case 'list':
23
- return 'Usage: kiipu post list [--tag <tag>] [--sort <updatedAt|createdAt|title>] [--starred] [--deleted]';
23
+ return 'Usage: kiipu note list [--tag <tag>] [--sort <updatedAt|createdAt|title>] [--starred] [--deleted]';
24
24
  case 'search':
25
- return 'Usage: kiipu post search <query>\n or: kiipu post search --query "<query>"';
25
+ return 'Usage: kiipu note search <query>\n or: kiipu note search --query "<query>"';
26
26
  case 'show':
27
- return 'Usage: kiipu post show --id <postId>';
27
+ return 'Usage: kiipu note show --id <noteId>';
28
28
  case 'update':
29
- return 'Usage: kiipu post update --id <postId> --content "<text>" [--title "<title>"] [--visibility public|private] [--tags <a,b,c>]';
29
+ return 'Usage: kiipu note update --id <noteId> --content "<text>" [--title "<title>"] [--visibility public|private] [--tags <a,b,c>]';
30
30
  case 'star':
31
- return 'Usage: kiipu post star --id <postId>';
31
+ return 'Usage: kiipu note star --id <noteId>';
32
32
  case 'pin':
33
- return 'Usage: kiipu post pin --id <postId>';
33
+ return 'Usage: kiipu note pin --id <noteId>';
34
34
  default:
35
- return `Usage: kiipu post ${action} --id <postId>`;
35
+ return `Usage: kiipu note ${action} --id <noteId>`;
36
36
  }
37
37
  }
38
38
  function error(message) {
@@ -81,9 +81,9 @@ function validateSort(sort) {
81
81
  }
82
82
  return sortValues.has(sort) ? sort : null;
83
83
  }
84
- function parsePostId(args, action) {
85
- const postId = readFlag(args, '--id')?.trim();
86
- return postId ? postId : error(usage(action));
84
+ function parseNoteId(args, action) {
85
+ const noteId = readFlag(args, '--id')?.trim();
86
+ return noteId ? noteId : error(usage(action));
87
87
  }
88
88
  function parseTags(input) {
89
89
  if (!input) {
@@ -105,19 +105,19 @@ function parseTags(input) {
105
105
  }
106
106
  return Array.from(unique.values());
107
107
  }
108
- function toCliPost(post) {
108
+ function toCliNote(note) {
109
109
  return {
110
- id: post.id,
111
- title: post.title,
112
- rawText: post.rawText,
113
- finalText: post.finalText,
114
- visibility: post.visibility,
115
- tags: post.tags,
116
- folder: post.folder ?? null,
117
- isPinned: post.isPinned,
118
- isStarred: post.isStarred,
119
- createdAt: post.createdAt,
120
- updatedAt: post.updatedAt,
110
+ id: note.id,
111
+ title: note.title,
112
+ rawText: note.rawText,
113
+ finalText: note.finalText,
114
+ visibility: note.visibility,
115
+ tags: note.tags,
116
+ folder: note.folder ?? null,
117
+ isPinned: note.isPinned,
118
+ isStarred: note.isStarred,
119
+ createdAt: note.createdAt,
120
+ updatedAt: note.updatedAt,
121
121
  };
122
122
  }
123
123
  async function handleMutationAction(config, action, args) {
@@ -126,13 +126,13 @@ async function handleMutationAction(config, action, args) {
126
126
  if (!content) {
127
127
  return error(usage('create'));
128
128
  }
129
- return executePostAction(config, { action: 'create', content });
129
+ return executeNoteAction(config, { action: 'create', content });
130
130
  }
131
- const postId = parsePostId(args, action);
132
- if (typeof postId !== 'string') {
133
- return postId;
131
+ const noteId = parseNoteId(args, action);
132
+ if (typeof noteId !== 'string') {
133
+ return noteId;
134
134
  }
135
- return executePostAction(config, { action, postId });
135
+ return executeNoteAction(config, { action, noteId });
136
136
  }
137
137
  async function handleList(config, args) {
138
138
  const { client, error: clientError } = requireUserClient(config);
@@ -149,36 +149,36 @@ async function handleList(config, args) {
149
149
  return error(`--starred and --deleted cannot be used together.\n${usage('list')}`);
150
150
  }
151
151
  const tag = readFlag(args, '--tag');
152
- let posts;
152
+ let notes;
153
153
  let responseData;
154
154
  if (starred) {
155
- const response = await client.listStarredPosts({ tag, sort });
155
+ const response = await client.listStarredNotes({ tag, sort });
156
156
  if (!response.ok) {
157
157
  return error(response.error.message);
158
158
  }
159
- posts = response.data.map((entry) => toCliPost(entry.post));
159
+ notes = response.data.map((entry) => toCliNote(entry.note));
160
160
  responseData = response.data;
161
161
  }
162
162
  else if (deleted) {
163
- const response = await client.listDeletedPosts({ sort });
163
+ const response = await client.listDeletedNotes({ sort });
164
164
  if (!response.ok) {
165
165
  return error(response.error.message);
166
166
  }
167
- posts = response.data.map(toCliPost);
167
+ notes = response.data.map(toCliNote);
168
168
  responseData = response.data;
169
169
  }
170
170
  else {
171
- const response = await client.listPosts({ tag, sort });
171
+ const response = await client.listNotes({ tag, sort });
172
172
  if (!response.ok) {
173
173
  return error(response.error.message);
174
174
  }
175
- posts = response.data.map(toCliPost);
175
+ notes = response.data.map(toCliNote);
176
176
  responseData = response.data;
177
177
  }
178
- const title = starred ? 'Starred posts' : deleted ? 'Deleted posts' : 'Posts';
178
+ const title = starred ? 'Starred notes' : deleted ? 'Deleted notes' : 'Notes';
179
179
  return {
180
180
  ok: true,
181
- message: formatPostCollection(title, posts),
181
+ message: formatNoteCollection(title, notes),
182
182
  data: responseData,
183
183
  };
184
184
  }
@@ -191,13 +191,13 @@ async function handleSearch(config, args) {
191
191
  if (!query) {
192
192
  return error(usage('search'));
193
193
  }
194
- const response = await client.searchPosts(query);
194
+ const response = await client.searchNotes(query);
195
195
  if (!response.ok) {
196
196
  return error(response.error.message);
197
197
  }
198
198
  return {
199
199
  ok: true,
200
- message: formatPostCollection(`Search results for "${query}"`, response.data.map(toCliPost)),
200
+ message: formatNoteCollection(`Search results for "${query}"`, response.data.map(toCliNote)),
201
201
  data: response.data,
202
202
  };
203
203
  }
@@ -206,17 +206,17 @@ async function handleShow(config, args) {
206
206
  if (!client) {
207
207
  return clientError;
208
208
  }
209
- const postId = parsePostId(args, 'show');
210
- if (typeof postId !== 'string') {
211
- return postId;
209
+ const noteId = parseNoteId(args, 'show');
210
+ if (typeof noteId !== 'string') {
211
+ return noteId;
212
212
  }
213
- const response = await client.getPost(postId);
213
+ const response = await client.getNote(noteId);
214
214
  if (!response.ok) {
215
215
  return error(response.error.message);
216
216
  }
217
217
  return {
218
218
  ok: true,
219
- message: formatPostDetail(toCliPost(response.data)),
219
+ message: formatNoteDetail(toCliNote(response.data)),
220
220
  data: response.data,
221
221
  };
222
222
  }
@@ -225,9 +225,9 @@ async function handleUpdate(config, args) {
225
225
  if (!client) {
226
226
  return clientError;
227
227
  }
228
- const postId = parsePostId(args, 'update');
229
- if (typeof postId !== 'string') {
230
- return postId;
228
+ const noteId = parseNoteId(args, 'update');
229
+ if (typeof noteId !== 'string') {
230
+ return noteId;
231
231
  }
232
232
  const content = readFlag(args, '--content')?.trim();
233
233
  if (!content) {
@@ -239,7 +239,7 @@ async function handleUpdate(config, args) {
239
239
  }
240
240
  const title = readFlag(args, '--title');
241
241
  const tags = readFlag(args, '--tags');
242
- const response = await client.updatePost(postId, {
242
+ const response = await client.updateNote(noteId, {
243
243
  rawText: content,
244
244
  ...(title !== undefined ? { title: title || null } : {}),
245
245
  ...(visibility === 'public' || visibility === 'private' ? { visibility } : {}),
@@ -250,7 +250,7 @@ async function handleUpdate(config, args) {
250
250
  }
251
251
  return {
252
252
  ok: true,
253
- message: `Post updated.\n\n${formatPostDetail(toCliPost(response.data))}`,
253
+ message: `Note updated.\n\n${formatNoteDetail(toCliNote(response.data))}`,
254
254
  data: response.data,
255
255
  };
256
256
  }
@@ -259,17 +259,19 @@ async function handleStar(config, args) {
259
259
  if (!client) {
260
260
  return clientError;
261
261
  }
262
- const postId = parsePostId(args, 'star');
263
- if (typeof postId !== 'string') {
264
- return postId;
262
+ const noteId = parseNoteId(args, 'star');
263
+ if (typeof noteId !== 'string') {
264
+ return noteId;
265
265
  }
266
- const response = await client.toggleStar(postId);
266
+ const response = await client.toggleStar(noteId);
267
267
  if (!response.ok) {
268
268
  return error(response.error.message);
269
269
  }
270
270
  return {
271
271
  ok: true,
272
- message: response.data.isStarred ? `Post starred. ${response.data.id}` : `Post unstarred. ${response.data.id}`,
272
+ message: response.data.isStarred
273
+ ? `Note starred. ${response.data.id}`
274
+ : `Note unstarred. ${response.data.id}`,
273
275
  data: response.data,
274
276
  };
275
277
  }
@@ -278,24 +280,26 @@ async function handlePin(config, args) {
278
280
  if (!client) {
279
281
  return clientError;
280
282
  }
281
- const postId = parsePostId(args, 'pin');
282
- if (typeof postId !== 'string') {
283
- return postId;
283
+ const noteId = parseNoteId(args, 'pin');
284
+ if (typeof noteId !== 'string') {
285
+ return noteId;
284
286
  }
285
- const response = await client.togglePin(postId);
287
+ const response = await client.togglePin(noteId);
286
288
  if (!response.ok) {
287
289
  return error(response.error.message);
288
290
  }
289
291
  return {
290
292
  ok: true,
291
- message: response.data.isPinned ? `Post pinned. ${response.data.id}` : `Post unpinned. ${response.data.id}`,
293
+ message: response.data.isPinned
294
+ ? `Note pinned. ${response.data.id}`
295
+ : `Note unpinned. ${response.data.id}`,
292
296
  data: response.data,
293
297
  };
294
298
  }
295
- export async function runPostCommand(config, args) {
299
+ export async function runNoteCommand(config, args) {
296
300
  const action = args[1];
297
301
  if (!action || !actions.has(action)) {
298
- return error('Usage: kiipu post <create|delete|restore|purge|list|search|show|update|star|pin> [options]');
302
+ return error('Usage: kiipu note <create|delete|restore|purge|list|search|show|update|star|pin> [options]');
299
303
  }
300
304
  const actionArgs = args.slice(2);
301
305
  switch (action) {
@@ -317,5 +321,5 @@ export async function runPostCommand(config, args) {
317
321
  case 'pin':
318
322
  return handlePin(config, actionArgs);
319
323
  }
320
- return error('Unsupported post action.');
324
+ return error('Unsupported note action.');
321
325
  }
@@ -13,7 +13,10 @@ function parseEnvFile(content) {
13
13
  if (!key || process.env[key] !== undefined) {
14
14
  continue;
15
15
  }
16
- const value = line.slice(separatorIndex + 1).trim().replace(/^['"]|['"]$/g, '');
16
+ const value = line
17
+ .slice(separatorIndex + 1)
18
+ .trim()
19
+ .replace(/^['"]|['"]$/g, '');
17
20
  process.env[key] = value;
18
21
  }
19
22
  }
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { runAskCommand } from './commands/ask.js';
5
5
  import { runAuthCommand } from './commands/auth.js';
6
6
  import { runDoctorCommand } from './commands/doctor.js';
7
7
  import { getHelpResult } from './commands/help.js';
8
- import { runPostCommand } from './commands/post.js';
8
+ import { runNoteCommand } from './commands/note.js';
9
9
  import { runSkillsCommand } from './commands/skills.js';
10
10
  import { readFlag, hasFlag } from './utils/args.js';
11
11
  import { CLI_VERSION } from './version.js';
@@ -86,8 +86,8 @@ async function main() {
86
86
  result = await runDoctorCommand(await loadKiipuConfig());
87
87
  return printResult(result, asJson);
88
88
  }
89
- if (command === 'post') {
90
- result = await runPostCommand(config, commandArgs);
89
+ if (command === 'note') {
90
+ result = await runNoteCommand(config, commandArgs);
91
91
  return printResult(result, asJson);
92
92
  }
93
93
  if (command === 'ask') {
@@ -45,14 +45,14 @@ function parseSource(input) {
45
45
  if (!isRecord(input)) {
46
46
  return null;
47
47
  }
48
- const postId = typeof input.postId === 'string' ? input.postId : '';
48
+ const noteId = typeof input.noteId === 'string' ? input.noteId : '';
49
49
  const snippet = typeof input.snippet === 'string' ? input.snippet : '';
50
- if (!postId || !snippet) {
50
+ if (!noteId || !snippet) {
51
51
  return null;
52
52
  }
53
53
  return {
54
54
  index: typeof input.index === 'number' ? input.index : 0,
55
- postId,
55
+ noteId,
56
56
  title: typeof input.title === 'string' ? input.title : null,
57
57
  snippet,
58
58
  score: typeof input.score === 'number' ? input.score : 0,
@@ -60,7 +60,9 @@ function parseSource(input) {
60
60
  };
61
61
  }
62
62
  function parseSources(input) {
63
- return Array.isArray(input) ? input.map(parseSource).filter((source) => Boolean(source)) : [];
63
+ return Array.isArray(input)
64
+ ? input.map(parseSource).filter((source) => Boolean(source))
65
+ : [];
64
66
  }
65
67
  function parseAskEvent(input) {
66
68
  if (!isRecord(input) || typeof input.type !== 'string') {
@@ -24,7 +24,7 @@ function truncate(value, maxLength) {
24
24
  function formatSourceLine(source) {
25
25
  const title = source.title?.trim() || '(untitled)';
26
26
  const score = Number.isFinite(source.score) ? ` score ${source.score.toFixed(3)}` : '';
27
- return `[${source.index}] ${title} (${source.postId})${score}`;
27
+ return `[${source.index}] ${title} (${source.noteId})${score}`;
28
28
  }
29
29
  export function formatAskFooter(input) {
30
30
  const lines = ['', 'Sources:'];
@@ -9,40 +9,46 @@ function buildError(requestId, message, code = 'request_failed') {
9
9
  },
10
10
  };
11
11
  }
12
- function parseCreatePostRequest(input) {
12
+ function parseCreateNoteRequest(input) {
13
13
  const requestId = typeof input.requestId === 'string' ? input.requestId : randomUUID();
14
14
  const rawText = typeof input.rawText === 'string' ? input.rawText.trim() : '';
15
15
  if (!rawText) {
16
16
  throw new Error('rawText is required.');
17
17
  }
18
18
  const visibility = input.visibility;
19
- const tags = Array.isArray(input.tags) ? input.tags.filter((tag) => typeof tag === 'string') : [];
19
+ const tags = Array.isArray(input.tags)
20
+ ? input.tags.filter((tag) => typeof tag === 'string')
21
+ : [];
20
22
  return {
21
23
  requestId,
22
24
  requestedAt: typeof input.requestedAt === 'string' ? input.requestedAt : undefined,
23
25
  traceId: typeof input.traceId === 'string' ? input.traceId : undefined,
24
26
  rawText,
25
- sourceType: input.sourceType === 'manual' || input.sourceType === 'imported' || input.sourceType === 'skill_command'
27
+ sourceType: input.sourceType === 'manual' ||
28
+ input.sourceType === 'imported' ||
29
+ input.sourceType === 'skill_command'
26
30
  ? input.sourceType
27
31
  : 'skill_command',
28
32
  finalText: typeof input.finalText === 'string' ? input.finalText : undefined,
29
- visibility: visibility === 'unlisted' || visibility === 'private' || visibility === 'public' ? visibility : 'public',
33
+ visibility: visibility === 'unlisted' || visibility === 'private' || visibility === 'public'
34
+ ? visibility
35
+ : 'public',
30
36
  sourceMessageId: typeof input.sourceMessageId === 'string' ? input.sourceMessageId : undefined,
31
37
  title: typeof input.title === 'string' ? input.title : input.title === null ? null : undefined,
32
38
  tags,
33
39
  };
34
40
  }
35
- function parsePostMutationRequest(input) {
41
+ function parseNoteMutationRequest(input) {
36
42
  const requestId = typeof input.requestId === 'string' ? input.requestId : randomUUID();
37
- const postId = typeof input.postId === 'string' ? input.postId.trim() : '';
38
- if (!postId) {
39
- throw new Error('postId is required.');
43
+ const noteId = typeof input.noteId === 'string' ? input.noteId.trim() : '';
44
+ if (!noteId) {
45
+ throw new Error('noteId is required.');
40
46
  }
41
47
  return {
42
48
  requestId,
43
49
  requestedAt: typeof input.requestedAt === 'string' ? input.requestedAt : undefined,
44
50
  traceId: typeof input.traceId === 'string' ? input.traceId : undefined,
45
- postId,
51
+ noteId,
46
52
  };
47
53
  }
48
54
  export class KiipuIntegrationApiClient {
@@ -87,19 +93,19 @@ export class KiipuIntegrationApiClient {
87
93
  ? payload.code
88
94
  : 'request_failed');
89
95
  }
90
- createPost(input) {
91
- return this.request('/integrations/posts', 'POST', parseCreatePostRequest(input));
96
+ createNote(input) {
97
+ return this.request('/integrations/notes', 'POST', parseCreateNoteRequest(input));
92
98
  }
93
- deletePost(input) {
94
- const body = parsePostMutationRequest(input);
95
- return this.request(`/integrations/posts/${body.postId}/delete`, 'POST', body);
99
+ deleteNote(input) {
100
+ const body = parseNoteMutationRequest(input);
101
+ return this.request(`/integrations/notes/${body.noteId}/delete`, 'POST', body);
96
102
  }
97
- restorePost(input) {
98
- const body = parsePostMutationRequest(input);
99
- return this.request(`/integrations/posts/${body.postId}/restore`, 'POST', body);
103
+ restoreNote(input) {
104
+ const body = parseNoteMutationRequest(input);
105
+ return this.request(`/integrations/notes/${body.noteId}/restore`, 'POST', body);
100
106
  }
101
- permanentDeletePost(input) {
102
- const body = parsePostMutationRequest(input);
103
- return this.request(`/integrations/posts/${body.postId}/permanent-delete`, 'POST', body);
107
+ permanentDeleteNote(input) {
108
+ const body = parseNoteMutationRequest(input);
109
+ return this.request(`/integrations/notes/${body.noteId}/permanent-delete`, 'POST', body);
104
110
  }
105
111
  }
@@ -72,34 +72,34 @@ export class KiipuUserApiClient {
72
72
  body: JSON.stringify(input),
73
73
  });
74
74
  }
75
- listPosts(input) {
76
- return this.request(this.buildPath('/posts/me', input));
75
+ listNotes(input) {
76
+ return this.request(this.buildPath('/notes/me', input));
77
77
  }
78
- searchPosts(query) {
79
- return this.request(this.buildPath('/posts/me/search', { q: query }));
78
+ searchNotes(query) {
79
+ return this.request(this.buildPath('/notes/me/search', { q: query }));
80
80
  }
81
- listStarredPosts(input) {
82
- return this.request(this.buildPath('/posts/me/starred', input));
81
+ listStarredNotes(input) {
82
+ return this.request(this.buildPath('/notes/me/starred', input));
83
83
  }
84
- listDeletedPosts(input) {
85
- return this.request(this.buildPath('/posts/me/deleted', input));
84
+ listDeletedNotes(input) {
85
+ return this.request(this.buildPath('/notes/me/deleted', input));
86
86
  }
87
- getPost(id) {
88
- return this.request(`/posts/${id}`);
87
+ getNote(id) {
88
+ return this.request(`/notes/${id}`);
89
89
  }
90
- updatePost(id, input) {
91
- return this.request(`/posts/${id}/content`, {
90
+ updateNote(id, input) {
91
+ return this.request(`/notes/${id}/content`, {
92
92
  method: 'PATCH',
93
93
  body: JSON.stringify(input),
94
94
  });
95
95
  }
96
96
  toggleStar(id) {
97
- return this.request(`/posts/${id}/star`, {
97
+ return this.request(`/notes/${id}/star`, {
98
98
  method: 'PATCH',
99
99
  });
100
100
  }
101
101
  togglePin(id) {
102
- return this.request(`/posts/${id}/pin`, {
102
+ return this.request(`/notes/${id}/pin`, {
103
103
  method: 'PATCH',
104
104
  });
105
105
  }
@@ -3,7 +3,7 @@ import { KiipuIntegrationApiClient } from './kiipu-integration-client.js';
3
3
  function formatRequestFailed(message, code) {
4
4
  return `Request failed: ${message} (${code}).`;
5
5
  }
6
- function getPostApiClient(config) {
6
+ function getNoteApiClient(config) {
7
7
  const apiKey = config.apiKey ?? process.env.KIIPU_API_KEY ?? '';
8
8
  if (!apiKey) {
9
9
  return {
@@ -20,16 +20,16 @@ function getPostApiClient(config) {
20
20
  }),
21
21
  };
22
22
  }
23
- export async function executePostAction(config, input) {
24
- const { client, error } = getPostApiClient(config);
23
+ export async function executeNoteAction(config, input) {
24
+ const { client, error } = getNoteApiClient(config);
25
25
  if (!client) {
26
26
  return error;
27
27
  }
28
28
  if (input.action === 'create') {
29
- const response = await client.createPost({
29
+ const response = await client.createNote({
30
30
  requestId: randomUUID(),
31
31
  requestedAt: new Date().toISOString(),
32
- traceId: `${input.traceIdPrefix ?? 'post'}-${Date.now()}`,
32
+ traceId: `${input.traceIdPrefix ?? 'note'}-${Date.now()}`,
33
33
  rawText: input.content,
34
34
  sourceType: 'skill_command',
35
35
  sourceMessageId: input.sourceMessageId ?? `local-${Date.now()}`,
@@ -44,18 +44,18 @@ export async function executePostAction(config, input) {
44
44
  }
45
45
  return {
46
46
  ok: true,
47
- message: `Post published. Post id ${String(response.data.id)} is now visible in the feed.`,
47
+ message: `Note created. Note id ${String(response.data.id)} is now visible in the feed.`,
48
48
  data: response.data,
49
49
  requestId: response.requestId,
50
- postId: String(response.data.id),
50
+ noteId: String(response.data.id),
51
51
  };
52
52
  }
53
53
  if (input.action === 'delete') {
54
- const response = await client.deletePost({
54
+ const response = await client.deleteNote({
55
55
  requestId: randomUUID(),
56
56
  requestedAt: new Date().toISOString(),
57
57
  traceId: `${input.traceIdPrefix ?? 'delete'}-${Date.now()}`,
58
- postId: input.postId,
58
+ noteId: input.noteId,
59
59
  });
60
60
  if (!response.ok) {
61
61
  return {
@@ -65,18 +65,18 @@ export async function executePostAction(config, input) {
65
65
  }
66
66
  return {
67
67
  ok: true,
68
- message: 'Post deleted. The current post is no longer visible in the feed.',
68
+ message: 'Note deleted. The current note is no longer visible in the feed.',
69
69
  data: response.data,
70
70
  requestId: response.requestId,
71
- postId: null,
71
+ noteId: null,
72
72
  };
73
73
  }
74
74
  if (input.action === 'restore') {
75
- const response = await client.restorePost({
75
+ const response = await client.restoreNote({
76
76
  requestId: randomUUID(),
77
77
  requestedAt: new Date().toISOString(),
78
78
  traceId: `${input.traceIdPrefix ?? 'restore'}-${Date.now()}`,
79
- postId: input.postId,
79
+ noteId: input.noteId,
80
80
  });
81
81
  if (!response.ok) {
82
82
  return {
@@ -86,17 +86,17 @@ export async function executePostAction(config, input) {
86
86
  }
87
87
  return {
88
88
  ok: true,
89
- message: `Post restored. Post id ${input.postId} is now back in the feed.`,
89
+ message: `Note restored. Note id ${input.noteId} is now back in the feed.`,
90
90
  data: response.data,
91
91
  requestId: response.requestId,
92
- postId: input.postId,
92
+ noteId: input.noteId,
93
93
  };
94
94
  }
95
- const response = await client.permanentDeletePost({
95
+ const response = await client.permanentDeleteNote({
96
96
  requestId: randomUUID(),
97
97
  requestedAt: new Date().toISOString(),
98
98
  traceId: `${input.traceIdPrefix ?? 'purge'}-${Date.now()}`,
99
- postId: input.postId,
99
+ noteId: input.noteId,
100
100
  });
101
101
  if (!response.ok) {
102
102
  return {
@@ -106,9 +106,9 @@ export async function executePostAction(config, input) {
106
106
  }
107
107
  return {
108
108
  ok: true,
109
- message: `Post permanently deleted. Post id ${input.postId} has been removed from the database.`,
109
+ message: `Note permanently deleted. Note id ${input.noteId} has been removed from the database.`,
110
110
  data: response.data,
111
111
  requestId: response.requestId,
112
- postId: null,
112
+ noteId: null,
113
113
  };
114
114
  }
@@ -23,52 +23,55 @@ function formatTags(tags, limit) {
23
23
  : [];
24
24
  return normalized.length > 0 ? normalized.map((tag) => `#${tag}`).join(', ') : 'none';
25
25
  }
26
- function getPostPreview(post) {
27
- const content = (post.title?.trim() || post.finalText?.trim() || post.rawText?.trim() || '').replace(/\s+/g, ' ');
26
+ function getNotePreview(note) {
27
+ const content = (note.title?.trim() ||
28
+ note.finalText?.trim() ||
29
+ note.rawText?.trim() ||
30
+ '').replace(/\s+/g, ' ');
28
31
  if (!content) {
29
32
  return '(empty)';
30
33
  }
31
34
  return content.length > 100 ? `${content.slice(0, 97)}...` : content;
32
35
  }
33
- function getStatusFlags(post) {
36
+ function getStatusFlags(note) {
34
37
  const flags = [];
35
- if (post.isPinned) {
38
+ if (note.isPinned) {
36
39
  flags.push('pinned');
37
40
  }
38
- if (post.isStarred) {
41
+ if (note.isStarred) {
39
42
  flags.push('starred');
40
43
  }
41
44
  return flags.length > 0 ? flags.join(', ') : 'none';
42
45
  }
43
- export function formatPostCollection(title, posts) {
46
+ export function formatNoteCollection(title, notes) {
44
47
  const lines = [title, ''];
45
- if (posts.length === 0) {
46
- lines.push('No posts found.');
48
+ if (notes.length === 0) {
49
+ lines.push('No notes found.');
47
50
  return lines.join('\n');
48
51
  }
49
- for (const post of posts) {
50
- lines.push(`${post.id} ${formatTimestamp(post.updatedAt ?? post.createdAt)}`);
51
- lines.push(` flags: ${getStatusFlags(post)} visibility: ${post.visibility} tags: ${formatTags(post.tags, 3)}`);
52
- lines.push(` ${getPostPreview(post)}`);
52
+ for (const note of notes) {
53
+ lines.push(`${note.id} ${formatTimestamp(note.updatedAt ?? note.createdAt)}`);
54
+ lines.push(` flags: ${getStatusFlags(note)} visibility: ${note.visibility} tags: ${formatTags(note.tags, 3)}`);
55
+ lines.push(` ${getNotePreview(note)}`);
53
56
  lines.push('');
54
57
  }
55
58
  return lines.slice(0, -1).join('\n');
56
59
  }
57
- export function formatPostDetail(post) {
58
- const title = post.title?.trim() || '(untitled)';
59
- const body = post.finalText?.trim() || post.rawText?.trim() || '(empty)';
60
+ export function formatNoteDetail(note) {
61
+ const title = note.title?.trim() || '(untitled)';
62
+ const body = note.finalText?.trim() || note.rawText?.trim() || '(empty)';
60
63
  return [
61
64
  title,
62
65
  '',
63
66
  body,
64
67
  '',
65
- `id: ${post.id}`,
66
- `visibility: ${post.visibility}`,
67
- `created: ${formatTimestamp(post.createdAt)}`,
68
- `updated: ${formatTimestamp(post.updatedAt)}`,
69
- `tags: ${formatTags(post.tags)}`,
70
- `folder: ${post.folder ? `${post.folder.name} (${post.folder.id})` : 'none'}`,
71
- `pinned: ${post.isPinned ? 'yes' : 'no'}`,
72
- `starred: ${post.isStarred ? 'yes' : 'no'}`,
68
+ `id: ${note.id}`,
69
+ `visibility: ${note.visibility}`,
70
+ `created: ${formatTimestamp(note.createdAt)}`,
71
+ `updated: ${formatTimestamp(note.updatedAt)}`,
72
+ `tags: ${formatTags(note.tags)}`,
73
+ `folder: ${note.folder ? `${note.folder.name} (${note.folder.id})` : 'none'}`,
74
+ `pinned: ${note.isPinned ? 'yes' : 'no'}`,
75
+ `starred: ${note.isStarred ? 'yes' : 'no'}`,
73
76
  ].join('\n');
74
77
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kiipu/cli",
3
- "version": "0.0.8",
4
- "description": "Kiipu CLI for local authentication, doctor checks, and direct post actions.",
3
+ "version": "0.0.9",
4
+ "description": "Kiipu CLI for local authentication, doctor checks, and direct note actions.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "repository": {