granola-toolkit 0.34.1 → 0.34.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/README.md +22 -427
- package/dist/cli.js +14 -9
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
# granola-toolkit
|
|
2
2
|
|
|
3
|
-
Toolkit for working with Granola meetings, notes, and
|
|
3
|
+
Toolkit for working with Granola meetings, notes, transcripts, folders, and local workspaces.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
From npm:
|
|
8
|
-
|
|
9
7
|
```bash
|
|
10
8
|
npm install -g granola-toolkit
|
|
11
9
|
granola --help
|
|
@@ -15,451 +13,48 @@ Without a global install:
|
|
|
15
13
|
|
|
16
14
|
```bash
|
|
17
15
|
npx granola-toolkit --help
|
|
18
|
-
npx granola-toolkit meeting --help
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
For local development:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
curl -fsSL https://vite.plus | bash
|
|
25
|
-
vp help
|
|
26
|
-
vp install
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Run
|
|
30
|
-
|
|
31
|
-
Installed command:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
granola --help
|
|
35
|
-
granola attach --help
|
|
36
|
-
granola auth login
|
|
37
|
-
granola exports --help
|
|
38
|
-
granola folder --help
|
|
39
|
-
granola meeting --help
|
|
40
|
-
granola notes --help
|
|
41
|
-
granola serve --help
|
|
42
|
-
granola tui --help
|
|
43
|
-
granola transcripts --help
|
|
44
|
-
granola web --help
|
|
45
16
|
```
|
|
46
17
|
|
|
47
18
|
The published package exposes both `granola` and `granola-toolkit` as executable names.
|
|
48
19
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
vp pack
|
|
53
|
-
node dist/cli.js --help
|
|
54
|
-
node dist/cli.js attach --help
|
|
55
|
-
node dist/cli.js exports --help
|
|
56
|
-
node dist/cli.js folder --help
|
|
57
|
-
node dist/cli.js meeting --help
|
|
58
|
-
node dist/cli.js notes --help
|
|
59
|
-
node dist/cli.js serve --help
|
|
60
|
-
node dist/cli.js tui --help
|
|
61
|
-
node dist/cli.js transcripts --help
|
|
62
|
-
node dist/cli.js web --help
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
You can also use the package scripts:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
npm run build
|
|
69
|
-
npm run start -- meeting --help
|
|
70
|
-
npm run notes -- --help
|
|
71
|
-
npm run tui -- --help
|
|
72
|
-
npm run transcripts -- --help
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Examples
|
|
76
|
-
|
|
77
|
-
Export notes:
|
|
20
|
+
## Quick Start
|
|
78
21
|
|
|
79
22
|
```bash
|
|
80
23
|
granola auth login
|
|
81
|
-
granola notes
|
|
82
|
-
granola notes --folder Team
|
|
83
|
-
|
|
84
|
-
node dist/cli.js notes --supabase "$HOME/Library/Application Support/Granola/supabase.json"
|
|
85
|
-
node dist/cli.js notes --format json --output ./notes-json
|
|
86
|
-
granola exports list
|
|
87
|
-
granola exports rerun notes-1234abcd
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Export transcripts:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
node dist/cli.js transcripts --cache "$HOME/Library/Application Support/Granola/cache-v3.json"
|
|
94
|
-
node dist/cli.js transcripts --format yaml --output ./transcripts-yaml
|
|
95
|
-
granola transcripts --folder Team
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Inspect individual meetings:
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
24
|
granola folder list
|
|
102
|
-
granola folder view Team
|
|
103
25
|
granola meeting list --limit 10
|
|
104
|
-
granola
|
|
105
|
-
granola meeting list --folder Team
|
|
106
|
-
granola meeting view 1234abcd
|
|
107
|
-
granola meeting notes 1234abcd
|
|
108
|
-
granola meeting transcript 1234abcd --format json
|
|
109
|
-
granola meeting export 1234abcd --format yaml
|
|
110
|
-
granola meeting open 1234abcd
|
|
111
|
-
granola tui
|
|
112
|
-
granola tui --meeting 1234abcd
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Run the local API server:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
granola serve
|
|
119
|
-
granola serve --port 4096
|
|
120
|
-
granola serve --hostname 0.0.0.0 --port 4096
|
|
121
|
-
granola serve --network lan --password "change-me"
|
|
122
|
-
granola attach http://127.0.0.1:4096
|
|
123
|
-
granola attach http://127.0.0.1:4096 --meeting 1234abcd
|
|
124
|
-
granola attach http://127.0.0.1:4096 --password "change-me"
|
|
125
|
-
|
|
26
|
+
granola notes --folder Team
|
|
126
27
|
granola web
|
|
127
|
-
granola
|
|
128
|
-
granola web --open=false --port 4096
|
|
129
|
-
granola web --network lan --password "change-me" --trusted-origins "https://trusted.example"
|
|
28
|
+
granola tui
|
|
130
29
|
```
|
|
131
30
|
|
|
132
|
-
##
|
|
133
|
-
|
|
134
|
-
### Notes
|
|
135
|
-
|
|
136
|
-
`notes` exports Granola's generated meeting notes, not the raw transcript.
|
|
137
|
-
|
|
138
|
-
The flow is:
|
|
139
|
-
|
|
140
|
-
1. read a stored Granola session, or fall back to your local `supabase.json`
|
|
141
|
-
2. extract the WorkOS access token from it
|
|
142
|
-
3. call Granola's paginated documents API
|
|
143
|
-
4. normalise each document into a structured note export
|
|
144
|
-
5. choose the best available note content for each document
|
|
145
|
-
6. render that export as Markdown, JSON, YAML, or raw JSON
|
|
146
|
-
7. write one file per document into the output directory
|
|
147
|
-
|
|
148
|
-
When you pass `--folder <id|name>`, the export is filtered to that folder and, by default, written into a stable per-folder subdirectory under the notes output root.
|
|
149
|
-
|
|
150
|
-
Content is chosen in this order:
|
|
151
|
-
|
|
152
|
-
1. `notes`
|
|
153
|
-
2. `last_viewed_panel.content`
|
|
154
|
-
3. `last_viewed_panel.original_content`
|
|
155
|
-
4. raw `content`
|
|
156
|
-
|
|
157
|
-
Markdown note files include:
|
|
158
|
-
|
|
159
|
-
- YAML frontmatter with the document id, created timestamp, updated timestamp, and tags
|
|
160
|
-
- a top-level heading from the note title
|
|
161
|
-
- converted note body content
|
|
162
|
-
|
|
163
|
-
### Transcripts
|
|
164
|
-
|
|
165
|
-
`transcripts` exports Granola's locally cached transcript segments.
|
|
166
|
-
|
|
167
|
-
The flow is:
|
|
168
|
-
|
|
169
|
-
1. read Granola's cache JSON from disk
|
|
170
|
-
2. parse the cache payload, whether it is double-encoded or already an object
|
|
171
|
-
3. normalise transcript data into a structured export per document
|
|
172
|
-
4. match transcript segments to documents by document id
|
|
173
|
-
5. render each export as text, JSON, YAML, or raw JSON
|
|
174
|
-
6. write one file per document into the output directory
|
|
175
|
-
|
|
176
|
-
When you pass `--folder <id|name>`, the export is filtered to that folder and, by default, written into a stable per-folder subdirectory under the transcripts output root.
|
|
177
|
-
|
|
178
|
-
Speaker labels are currently normalised to:
|
|
179
|
-
|
|
180
|
-
- `You` for `microphone`
|
|
181
|
-
- `System` for everything else
|
|
182
|
-
|
|
183
|
-
Structured output formats are useful when you want to post-process exports in scripts instead of reading the default human-oriented Markdown or text files.
|
|
184
|
-
|
|
185
|
-
### Meetings
|
|
186
|
-
|
|
187
|
-
`meeting` combines the API-backed notes path with the local transcript cache so you can inspect one meeting at a time.
|
|
188
|
-
|
|
189
|
-
The flow is:
|
|
190
|
-
|
|
191
|
-
1. read a stored Granola session, or fall back to `supabase.json`
|
|
192
|
-
2. fetch documents from Granola's API
|
|
193
|
-
3. optionally load the local cache for transcript data
|
|
194
|
-
4. resolve a meeting by full id or unique id prefix
|
|
195
|
-
5. render either a list, a combined meeting view, focused notes/transcript output, or a machine-readable export bundle
|
|
196
|
-
|
|
197
|
-
The human-readable `view` command shows:
|
|
198
|
-
|
|
199
|
-
- meeting metadata
|
|
200
|
-
- the selected notes content
|
|
201
|
-
- transcript lines when the local cache is available
|
|
202
|
-
|
|
203
|
-
The focused meeting subcommands are:
|
|
204
|
-
|
|
205
|
-
- `meeting notes` for just the selected note output
|
|
206
|
-
- `meeting transcript` for just the selected transcript output
|
|
207
|
-
- `meeting open` to start the web workspace focused on one meeting
|
|
208
|
-
|
|
209
|
-
The machine-readable `export` command includes:
|
|
31
|
+
## Documentation
|
|
210
32
|
|
|
211
|
-
|
|
212
|
-
-
|
|
213
|
-
- structured transcript data plus rendered transcript text when available
|
|
33
|
+
The detailed documentation now lives in the dedicated docs app under
|
|
34
|
+
[`docs/`](https://github.com/kkarimi/granola-toolkit/tree/main/docs).
|
|
214
35
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
`folder` exposes Granola document lists as a first-class concept instead of leaving meetings in one flat global list.
|
|
218
|
-
|
|
219
|
-
The flow is:
|
|
220
|
-
|
|
221
|
-
1. reuse the shared auth path that `notes` and `meeting` already use
|
|
222
|
-
2. call Granola's document-list API, with `v2` first and `v1` fallback
|
|
223
|
-
3. normalise folder metadata and document membership into shared folder records
|
|
224
|
-
4. attach folder membership to meetings in the shared app core
|
|
225
|
-
5. let folder commands and meeting filters resolve folders by id, prefix, or unique name
|
|
226
|
-
|
|
227
|
-
The current CLI surface includes:
|
|
228
|
-
|
|
229
|
-
- `folder list`
|
|
230
|
-
- `folder view <id|name>`
|
|
231
|
-
- `meeting list --folder <id|name>`
|
|
232
|
-
- `notes --folder <id|name>`
|
|
233
|
-
- `transcripts --folder <id|name>`
|
|
234
|
-
|
|
235
|
-
### Server
|
|
236
|
-
|
|
237
|
-
`serve` starts a long-lived local `Granola Toolkit` server on one shared app instance.
|
|
238
|
-
|
|
239
|
-
The initial server API includes:
|
|
240
|
-
|
|
241
|
-
- `GET /health`
|
|
242
|
-
- `GET /server/info`
|
|
243
|
-
- `POST /auth/unlock` for password-protected servers
|
|
244
|
-
- `POST /auth/lock` to clear the browser/API unlock cookie
|
|
245
|
-
- `GET /auth/status`
|
|
246
|
-
- `GET /state`
|
|
247
|
-
- `GET /events` for server-sent state updates
|
|
248
|
-
- `GET /folders`
|
|
249
|
-
- `GET /folders/resolve?q=<query>`
|
|
250
|
-
- `GET /folders/:id`
|
|
251
|
-
- `GET /meetings`
|
|
252
|
-
- `GET /meetings?folderId=<id>` for folder-scoped meeting lists
|
|
253
|
-
- `GET /meetings?refresh=true` to bypass the local meeting index and force a live refresh
|
|
254
|
-
- `GET /meetings/resolve?q=<query>`
|
|
255
|
-
- `GET /meetings/:id`
|
|
256
|
-
- `GET /exports/jobs`
|
|
257
|
-
- `POST /auth/login`
|
|
258
|
-
- `POST /auth/logout`
|
|
259
|
-
- `POST /auth/mode`
|
|
260
|
-
- `POST /auth/refresh`
|
|
261
|
-
- `POST /exports/notes` with optional `folderId`
|
|
262
|
-
- `POST /exports/jobs/:id/rerun`
|
|
263
|
-
- `POST /exports/transcripts` with optional `folderId`
|
|
264
|
-
|
|
265
|
-
This is the shared runtime for `granola web` and `granola attach`.
|
|
266
|
-
|
|
267
|
-
Server hardening now includes:
|
|
268
|
-
|
|
269
|
-
- `local` network mode by default, which binds to `127.0.0.1`
|
|
270
|
-
- `lan` network mode when you explicitly want other devices to connect
|
|
271
|
-
- optional password protection for API routes and the browser client
|
|
272
|
-
- trusted-origin checks for browser requests, with CORS headers only for allowed origins
|
|
273
|
-
- a warning when you expose the server on `lan` without a password
|
|
274
|
-
|
|
275
|
-
### Web
|
|
276
|
-
|
|
277
|
-
`web` starts the same local server as `serve`, enables the browser client at `/`, and opens that workspace in your default browser unless you pass `--open=false`.
|
|
278
|
-
|
|
279
|
-
You can deep-link into a specific meeting with either:
|
|
280
|
-
|
|
281
|
-
- `granola web --meeting <id>`
|
|
282
|
-
- `granola meeting open <id>`
|
|
283
|
-
|
|
284
|
-
The initial browser client includes:
|
|
285
|
-
|
|
286
|
-
- a dedicated folder pane with an explicit All meetings scope
|
|
287
|
-
- a searchable meeting list
|
|
288
|
-
- folder-aware meeting browsing with one-click scope changes
|
|
289
|
-
- a fast local-index warm start for meeting browsing before live documents finish loading
|
|
290
|
-
- sort and updated-date filters
|
|
291
|
-
- quick open by meeting id or title
|
|
292
|
-
- browser URL state that preserves the selected folder, meeting, and tab
|
|
293
|
-
- a focused meeting workspace with notes, transcript, metadata, and raw tabs
|
|
294
|
-
- keyboard-first workspace switching with `1`-`4`, `[` and `]`
|
|
295
|
-
- app-state status from the shared core
|
|
296
|
-
- an auth session panel for login, refresh, source switching, and sign-out
|
|
297
|
-
- note and transcript export actions backed by the same local API
|
|
298
|
-
- folder-scoped export actions that follow the currently selected folder
|
|
299
|
-
- a recent export-jobs panel with rerun actions
|
|
300
|
-
- stronger empty and error states for list/detail failures
|
|
301
|
-
- a server-access panel that can unlock or lock a password-protected local server
|
|
302
|
-
|
|
303
|
-
### Attach
|
|
304
|
-
|
|
305
|
-
`attach` connects the terminal workspace to an already running `granola serve` or `granola web` instance instead of starting a second isolated app.
|
|
306
|
-
|
|
307
|
-
Use it when you want:
|
|
308
|
-
|
|
309
|
-
- two terminal workspaces attached to the same live app state
|
|
310
|
-
- one terminal workspace and one browser workspace sharing auth, meeting index, and export-job history
|
|
311
|
-
- a password-protected local server to remain the single source of truth
|
|
312
|
-
|
|
313
|
-
The attach flow uses the existing local HTTP API plus `GET /events` for live state updates.
|
|
314
|
-
|
|
315
|
-
### Runtime Boundaries
|
|
316
|
-
|
|
317
|
-
The toolkit now keeps its local persistence and transport contracts explicit:
|
|
318
|
-
|
|
319
|
-
- one shared local data directory for export jobs, meeting index data, and any file-backed session state
|
|
320
|
-
- one versioned local HTTP transport contract, exposed by `GET /server/info`
|
|
321
|
-
- one remote client handshake that validates the transport protocol before attaching
|
|
322
|
-
|
|
323
|
-
That keeps the current single-package repo simple, while making a future split into separate server/client packages or remote-hosted clients much less invasive.
|
|
324
|
-
|
|
325
|
-
### TUI
|
|
326
|
-
|
|
327
|
-
`tui` starts a full-screen terminal workspace on the shared app core, without requiring the local server or browser client. Use `attach` when you want the same workspace against an existing shared server instance instead.
|
|
328
|
-
|
|
329
|
-
The initial terminal workspace includes:
|
|
330
|
-
|
|
331
|
-
- a folder scope inside the navigation pane, including an explicit All meetings view
|
|
332
|
-
- a meeting list pane with keyboard navigation
|
|
333
|
-
- a detail pane with notes, transcript, metadata, and raw views
|
|
334
|
-
- an auth session overlay for import, refresh, source switching, and sign-out
|
|
335
|
-
- a footer with app state and key hints
|
|
336
|
-
- a quick-open overlay for jumping by title, id, or tag
|
|
337
|
-
|
|
338
|
-
The main keyboard controls are:
|
|
339
|
-
|
|
340
|
-
- `h` / `l`, left / right, or `Tab` to switch between folders and meetings
|
|
341
|
-
- `j` / `k` or arrow keys to move within the active folder or meeting list
|
|
342
|
-
- `/` or `Ctrl+P` to open quick open
|
|
343
|
-
- `a` to open auth session actions
|
|
344
|
-
- `1`-`4` to switch detail tabs
|
|
345
|
-
- `PageUp` / `PageDown` to scroll the detail pane
|
|
346
|
-
- `r` to refresh from live Granola data
|
|
347
|
-
- `q` to quit
|
|
348
|
-
|
|
349
|
-
### Local Meeting Index
|
|
350
|
-
|
|
351
|
-
Interactive meeting browsing now keeps a local index of meeting summaries and metadata.
|
|
352
|
-
|
|
353
|
-
That index is used to:
|
|
354
|
-
|
|
355
|
-
- make the web meeting list available quickly on startup
|
|
356
|
-
- keep search, sort, and date filtering useful before every live document payload is fetched again
|
|
357
|
-
- refresh itself after successful live loads so the next run starts warm
|
|
358
|
-
|
|
359
|
-
The web client uses the index as a fast path and upgrades to live data automatically when the background refresh completes. The manual Refresh button bypasses the index and forces a live meeting fetch immediately.
|
|
360
|
-
|
|
361
|
-
### Export Jobs
|
|
362
|
-
|
|
363
|
-
Exports are now tracked as jobs with:
|
|
364
|
-
|
|
365
|
-
- persistent local history across CLI and web runs
|
|
366
|
-
- explicit scope metadata for all-meetings and folder-scoped runs
|
|
367
|
-
- running, completed, and failed status
|
|
368
|
-
- per-export progress counters
|
|
369
|
-
- rerun support from `granola exports rerun <job-id>` or the web client
|
|
370
|
-
|
|
371
|
-
Use `granola exports list` to inspect recent jobs from the CLI.
|
|
372
|
-
|
|
373
|
-
## Auth
|
|
374
|
-
|
|
375
|
-
If you do not want to keep passing `--supabase`, import the desktop app session once:
|
|
36
|
+
Local docs development:
|
|
376
37
|
|
|
377
38
|
```bash
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
granola auth refresh
|
|
381
|
-
granola auth use stored
|
|
382
|
-
granola auth use supabase
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
That stores a reusable Granola session locally and lets `granola notes` use it directly.
|
|
386
|
-
|
|
387
|
-
`granola auth` now supports:
|
|
388
|
-
|
|
389
|
-
- `login` to import the desktop app session into the toolkit store
|
|
390
|
-
- `status` to inspect the active source, stored-session availability, refresh support, and any last auth error
|
|
391
|
-
- `refresh` to refresh the stored session explicitly
|
|
392
|
-
- `use stored` or `use supabase` to switch the active auth source
|
|
393
|
-
- `logout` to delete the stored session
|
|
394
|
-
|
|
395
|
-
The same auth actions are also available from the web workspace.
|
|
396
|
-
|
|
397
|
-
### Incremental Writes
|
|
398
|
-
|
|
399
|
-
Both commands keep a small hidden state file in the output directory to track:
|
|
400
|
-
|
|
401
|
-
- document id to filename
|
|
402
|
-
- content hash
|
|
403
|
-
- source timestamp
|
|
404
|
-
- last export time
|
|
405
|
-
|
|
406
|
-
That state is used to:
|
|
407
|
-
|
|
408
|
-
- keep filenames stable even if a meeting title changes later
|
|
409
|
-
- skip rewrites when the rendered content is unchanged
|
|
410
|
-
- migrate old files cleanly when the output format changes
|
|
411
|
-
- delete stale exports when a document disappears from the source data
|
|
412
|
-
|
|
413
|
-
That makes repeated runs cheap and keeps long-lived export directories much cleaner.
|
|
414
|
-
|
|
415
|
-
## Config
|
|
416
|
-
|
|
417
|
-
The CLI reads configuration in this order:
|
|
418
|
-
|
|
419
|
-
1. command-line flags
|
|
420
|
-
2. environment variables
|
|
421
|
-
3. `.granola.toml`
|
|
422
|
-
4. platform defaults
|
|
423
|
-
|
|
424
|
-
Supported config keys:
|
|
425
|
-
|
|
426
|
-
```toml
|
|
427
|
-
debug = true
|
|
428
|
-
supabase = "/Users/yourname/Library/Application Support/Granola/supabase.json"
|
|
429
|
-
output = "./notes"
|
|
430
|
-
timeout = "2m"
|
|
431
|
-
cache-file = "/Users/yourname/Library/Application Support/Granola/cache-v3.json"
|
|
432
|
-
transcript-output = "./transcripts"
|
|
39
|
+
npm run docs:dev
|
|
40
|
+
npm run docs:check
|
|
433
41
|
```
|
|
434
42
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
- `DEBUG_MODE`
|
|
438
|
-
- `SUPABASE_FILE`
|
|
439
|
-
- `OUTPUT`
|
|
440
|
-
- `TIMEOUT`
|
|
441
|
-
- `CACHE_FILE`
|
|
442
|
-
- `TRANSCRIPT_OUTPUT`
|
|
443
|
-
- `GRANOLA_CLIENT_VERSION`
|
|
43
|
+
Key docs entry points:
|
|
444
44
|
|
|
445
|
-
|
|
45
|
+
- [`Overview`](https://github.com/kkarimi/granola-toolkit/blob/main/docs/content/docs/index.mdx)
|
|
46
|
+
- [`Getting Started`](https://github.com/kkarimi/granola-toolkit/blob/main/docs/content/docs/getting-started.mdx)
|
|
47
|
+
- [`Exporting`](https://github.com/kkarimi/granola-toolkit/blob/main/docs/content/docs/exporting.mdx)
|
|
48
|
+
- [`Meetings and Folders`](https://github.com/kkarimi/granola-toolkit/blob/main/docs/content/docs/meetings-and-folders.mdx)
|
|
49
|
+
- [`Server, Web, and TUI`](https://github.com/kkarimi/granola-toolkit/blob/main/docs/content/docs/server-web-and-tui.mdx)
|
|
50
|
+
- [`Auth and Configuration`](https://github.com/kkarimi/granola-toolkit/blob/main/docs/content/docs/auth-and-configuration.mdx)
|
|
51
|
+
- [`Development`](https://github.com/kkarimi/granola-toolkit/blob/main/docs/content/docs/development.mdx)
|
|
446
52
|
|
|
447
|
-
|
|
53
|
+
## Local Development
|
|
448
54
|
|
|
449
55
|
```bash
|
|
450
|
-
|
|
451
|
-
vp
|
|
452
|
-
npm run coverage
|
|
56
|
+
curl -fsSL https://vite.plus | bash
|
|
57
|
+
vp install
|
|
453
58
|
vp pack
|
|
454
|
-
|
|
59
|
+
node dist/cli.js --help
|
|
455
60
|
```
|
|
456
|
-
|
|
457
|
-
What those do:
|
|
458
|
-
|
|
459
|
-
- `vp check`: formatting, linting, and type checks
|
|
460
|
-
- `vp test`: unit tests
|
|
461
|
-
- `npm run coverage`: unit tests plus a local coverage report in `coverage/coverage-summary.json`
|
|
462
|
-
- `vp pack`: builds the CLI bundle into `dist/cli.js`
|
|
463
|
-
- `npm pack --dry-run`: shows the exact npm package contents without publishing
|
|
464
|
-
|
|
465
|
-
`vp build` is for web apps. This repo is a CLI package, so the build step here is `vp pack`.
|
package/dist/cli.js
CHANGED
|
@@ -1755,7 +1755,7 @@ var GranolaTuiWorkspace = class {
|
|
|
1755
1755
|
limit: 100
|
|
1756
1756
|
});
|
|
1757
1757
|
if (token !== this.#folderToken) return;
|
|
1758
|
-
this.#folders = result.folders;
|
|
1758
|
+
this.#folders = [...result.folders];
|
|
1759
1759
|
if (this.#selectedFolderId && !this.#folders.some((folder) => folder.id === this.#selectedFolderId)) this.#selectedFolderId = void 0;
|
|
1760
1760
|
this.#folderError = "";
|
|
1761
1761
|
} catch (error) {
|
|
@@ -1782,9 +1782,13 @@ var GranolaTuiWorkspace = class {
|
|
|
1782
1782
|
preferIndex: true
|
|
1783
1783
|
});
|
|
1784
1784
|
if (token !== this.#listToken) return;
|
|
1785
|
-
this.#meetings = result.meetings;
|
|
1785
|
+
this.#meetings = [...result.meetings];
|
|
1786
1786
|
this.#meetingSource = result.source;
|
|
1787
|
-
|
|
1787
|
+
let nextSelectedMeetingId;
|
|
1788
|
+
if (options.preferredMeetingId && this.#meetings.some((meeting) => meeting.id === options.preferredMeetingId)) nextSelectedMeetingId = options.preferredMeetingId;
|
|
1789
|
+
else if (this.#selectedMeetingId && this.#meetings.some((meeting) => meeting.id === this.#selectedMeetingId)) nextSelectedMeetingId = this.#selectedMeetingId;
|
|
1790
|
+
else nextSelectedMeetingId = this.#meetings[0]?.id;
|
|
1791
|
+
this.#selectedMeetingId = nextSelectedMeetingId;
|
|
1788
1792
|
if (!this.#selectedMeetingId) {
|
|
1789
1793
|
this.#selectedMeeting = void 0;
|
|
1790
1794
|
this.#detailError = "";
|
|
@@ -1863,14 +1867,15 @@ var GranolaTuiWorkspace = class {
|
|
|
1863
1867
|
this.#selectedMeeting = void 0;
|
|
1864
1868
|
this.#detailError = "";
|
|
1865
1869
|
this.#detailScroll = 0;
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
await this.loadMeeting(
|
|
1870
|
+
this.#selectedMeetingId = void 0;
|
|
1871
|
+
await this.loadMeetings({ setStatus: false });
|
|
1872
|
+
const visibleMeetingId = this.#selectedMeetingId && this.#meetings.some((meeting) => meeting.id === this.#selectedMeetingId) ? this.#selectedMeetingId : this.#meetings[0]?.id;
|
|
1873
|
+
if (visibleMeetingId) {
|
|
1874
|
+
this.#selectedMeetingId = visibleMeetingId;
|
|
1875
|
+
await this.loadMeeting(visibleMeetingId, { ensureMeetingVisible: true });
|
|
1872
1876
|
return;
|
|
1873
1877
|
}
|
|
1878
|
+
this.#selectedMeetingId = void 0;
|
|
1874
1879
|
this.tui.requestRender();
|
|
1875
1880
|
}
|
|
1876
1881
|
async moveSelection(delta) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "granola-toolkit",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.3",
|
|
4
4
|
"description": "Toolkit for exporting and working with Granola meetings, notes, and transcripts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
"check": "vp check",
|
|
37
37
|
"coverage": "vp test --coverage",
|
|
38
38
|
"dev": "vp pack --watch",
|
|
39
|
+
"docs:build": "npm --prefix docs run build",
|
|
40
|
+
"docs:check": "npm --prefix docs run types:check && npm --prefix docs run build",
|
|
41
|
+
"docs:dev": "npm --prefix docs run dev",
|
|
42
|
+
"docs:start": "npm --prefix docs run start",
|
|
39
43
|
"fmt": "vp fmt",
|
|
40
44
|
"lint": "vp lint",
|
|
41
45
|
"pack:dry-run": "npm pack --dry-run",
|