@nocoo/zhe 1.16.1 → 1.19.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.
Files changed (71) hide show
  1. package/dist/api/client.d.ts +25 -1
  2. package/dist/api/client.d.ts.map +1 -1
  3. package/dist/api/client.js +41 -2
  4. package/dist/api/client.js.map +1 -1
  5. package/dist/api/types.d.ts +32 -2
  6. package/dist/api/types.d.ts.map +1 -1
  7. package/dist/commands/create.js +1 -18
  8. package/dist/commands/create.js.map +1 -1
  9. package/dist/commands/folder.d.ts +7 -0
  10. package/dist/commands/folder.d.ts.map +1 -0
  11. package/dist/commands/folder.js +226 -0
  12. package/dist/commands/folder.js.map +1 -0
  13. package/dist/commands/get.d.ts.map +1 -1
  14. package/dist/commands/get.js +12 -1
  15. package/dist/commands/get.js.map +1 -1
  16. package/dist/commands/idea/add.d.ts +22 -0
  17. package/dist/commands/idea/add.d.ts.map +1 -0
  18. package/dist/commands/idea/add.js +55 -0
  19. package/dist/commands/idea/add.js.map +1 -0
  20. package/dist/commands/idea/delete.d.ts +17 -0
  21. package/dist/commands/idea/delete.d.ts.map +1 -0
  22. package/dist/commands/idea/delete.js +47 -0
  23. package/dist/commands/idea/delete.js.map +1 -0
  24. package/dist/commands/idea/get.d.ts +12 -0
  25. package/dist/commands/idea/get.d.ts.map +1 -0
  26. package/dist/commands/idea/get.js +45 -0
  27. package/dist/commands/idea/get.js.map +1 -0
  28. package/dist/commands/idea/helpers.d.ts +13 -0
  29. package/dist/commands/idea/helpers.d.ts.map +1 -0
  30. package/dist/commands/idea/helpers.js +78 -0
  31. package/dist/commands/idea/helpers.js.map +1 -0
  32. package/dist/commands/idea/list.d.ts +22 -0
  33. package/dist/commands/idea/list.d.ts.map +1 -0
  34. package/dist/commands/idea/list.js +64 -0
  35. package/dist/commands/idea/list.js.map +1 -0
  36. package/dist/commands/idea/update.d.ts +27 -0
  37. package/dist/commands/idea/update.d.ts.map +1 -0
  38. package/dist/commands/idea/update.js +78 -0
  39. package/dist/commands/idea/update.js.map +1 -0
  40. package/dist/commands/idea.d.ts +6 -1
  41. package/dist/commands/idea.d.ts.map +1 -1
  42. package/dist/commands/idea.js +12 -390
  43. package/dist/commands/idea.js.map +1 -1
  44. package/dist/commands/list.d.ts +4 -0
  45. package/dist/commands/list.d.ts.map +1 -1
  46. package/dist/commands/list.js +133 -61
  47. package/dist/commands/list.js.map +1 -1
  48. package/dist/commands/open.js +1 -23
  49. package/dist/commands/open.js.map +1 -1
  50. package/dist/commands/tag.d.ts +8 -0
  51. package/dist/commands/tag.d.ts.map +1 -0
  52. package/dist/commands/tag.js +289 -0
  53. package/dist/commands/tag.js.map +1 -0
  54. package/dist/commands/update.d.ts.map +1 -1
  55. package/dist/commands/update.js +56 -59
  56. package/dist/commands/update.js.map +1 -1
  57. package/dist/index.js +4 -0
  58. package/dist/index.js.map +1 -1
  59. package/dist/utils/format.d.ts +27 -0
  60. package/dist/utils/format.d.ts.map +1 -0
  61. package/dist/utils/format.js +157 -0
  62. package/dist/utils/format.js.map +1 -0
  63. package/dist/utils/resolve.d.ts +41 -0
  64. package/dist/utils/resolve.d.ts.map +1 -0
  65. package/dist/utils/resolve.js +69 -0
  66. package/dist/utils/resolve.js.map +1 -0
  67. package/dist/utils.d.ts +22 -61
  68. package/dist/utils.d.ts.map +1 -1
  69. package/dist/utils.js +66 -187
  70. package/dist/utils.js.map +1 -1
  71. package/package.json +10 -6
@@ -1,395 +1,17 @@
1
1
  /**
2
- * zhe idea — Manage ideas (Markdown notes)
2
+ * zhe idea — Manage ideas (Markdown notes).
3
+ *
4
+ * Subcommand implementations live in ./idea/*.ts to keep this file small.
5
+ * `formatTags` is re-exported here for tests that import from
6
+ * `commands/idea.js`.
3
7
  */
4
- import * as readline from "node:readline";
5
- import { defineCommand, pc } from "@nocoo/cli-base";
6
- import { ApiClient, ApiClientError, EXIT_AUTH_REQUIRED, EXIT_ERROR, EXIT_INVALID_ARGS, EXIT_NOT_FOUND, EXIT_RATE_LIMITED, } from "../api/client.js";
7
- import { getApiKey } from "../config.js";
8
- // ── Helpers ──
9
- function requireAuth() {
10
- const apiKey = getApiKey();
11
- if (!apiKey) {
12
- console.log(pc.red("Not authenticated. Run `zhe login` first."));
13
- process.exit(EXIT_AUTH_REQUIRED);
14
- }
15
- return apiKey;
16
- }
17
- function handleApiError(error) {
18
- if (error instanceof ApiClientError) {
19
- if (error.status === 400) {
20
- console.log(pc.red(`Error: ${error.message}`));
21
- }
22
- else if (error.status === 404) {
23
- console.log(pc.red("Idea not found."));
24
- process.exit(EXIT_NOT_FOUND);
25
- }
26
- else {
27
- console.log(pc.red(`Error: ${error.message}`));
28
- }
29
- if (error.status === 401) {
30
- process.exit(EXIT_AUTH_REQUIRED);
31
- }
32
- if (error.status === 429) {
33
- process.exit(EXIT_RATE_LIMITED);
34
- }
35
- process.exit(EXIT_ERROR);
36
- }
37
- throw error;
38
- }
39
- function formatDate(isoDate) {
40
- const date = new Date(isoDate);
41
- return new Intl.DateTimeFormat("en-US", {
42
- month: "short",
43
- day: "numeric",
44
- year: "numeric",
45
- hour: "numeric",
46
- minute: "2-digit",
47
- }).format(date);
48
- }
49
- function formatTags(tags) {
50
- if (tags.length === 0)
51
- return "";
52
- return tags.map((t) => `[${t.name}]`).join(" ");
53
- }
54
- /**
55
- * Resolve a single tag name to tag ID via API.
56
- * Returns null if tag is not found or if multiple tags match (with error message printed).
57
- */
58
- async function resolveTagName(client, tagName) {
59
- const { tags } = await client.listTags();
60
- const matches = tags.filter((t) => t.name.toLowerCase() === tagName.toLowerCase());
61
- if (matches.length === 0) {
62
- console.log(pc.red(`Tag not found: ${tagName}. Create it first.`));
63
- return null;
64
- }
65
- if (matches.length > 1) {
66
- console.log(pc.red(`Multiple tags match "${tagName}". Tag names must be unique. Please rename or delete duplicates via the web UI.`));
67
- return null;
68
- }
69
- return matches[0].id;
70
- }
71
- async function confirm(message) {
72
- return new Promise((resolve) => {
73
- const rl = readline.createInterface({
74
- input: process.stdin,
75
- output: process.stdout,
76
- });
77
- rl.question(`${message} [y/N] `, (answer) => {
78
- rl.close();
79
- resolve(answer.toLowerCase() === "y");
80
- });
81
- });
82
- }
83
- // ── Subcommands ──
84
- const listSubcommand = defineCommand({
85
- meta: {
86
- name: "list",
87
- description: "List all ideas",
88
- },
89
- args: {
90
- limit: {
91
- type: "string",
92
- alias: "l",
93
- description: "Max results (default: 20)",
94
- },
95
- tag: {
96
- type: "string",
97
- alias: "t",
98
- description: "Filter by tag name",
99
- },
100
- query: {
101
- type: "string",
102
- alias: "q",
103
- description: "Search title and excerpt",
104
- },
105
- json: {
106
- type: "boolean",
107
- description: "Output as JSON",
108
- },
109
- },
110
- async run({ args }) {
111
- const apiKey = requireAuth();
112
- const client = new ApiClient(apiKey);
113
- try {
114
- // Resolve tag name to ID if provided
115
- let tagId;
116
- if (args.tag) {
117
- const resolved = await resolveTagName(client, args.tag);
118
- if (resolved === null) {
119
- process.exit(EXIT_INVALID_ARGS);
120
- }
121
- tagId = resolved;
122
- }
123
- const response = await client.listIdeas({
124
- limit: args.limit ? Number.parseInt(args.limit, 10) : 20,
125
- tagId,
126
- q: args.query,
127
- });
128
- if (args.json) {
129
- console.log(JSON.stringify(response, null, 2));
130
- return;
131
- }
132
- if (response.ideas.length === 0) {
133
- console.log(pc.yellow("No ideas found."));
134
- return;
135
- }
136
- // Table format
137
- console.log(pc.dim("ID TIME TITLE TAGS"));
138
- console.log(pc.dim("─".repeat(56)));
139
- for (const idea of response.ideas) {
140
- const time = formatDate(idea.createdAt);
141
- const title = (idea.title || idea.excerpt || "(no content)").slice(0, 24);
142
- const tags = formatTags(idea.tags);
143
- console.log(`${pc.cyan(String(idea.id).padEnd(6))}${time.padEnd(17)}${title.padEnd(25)}${pc.yellow(tags)}`);
144
- }
145
- }
146
- catch (error) {
147
- handleApiError(error);
148
- }
149
- },
150
- });
151
- const getSubcommand = defineCommand({
152
- meta: {
153
- name: "get",
154
- description: "Get full content of an idea",
155
- },
156
- args: {
157
- id: {
158
- type: "positional",
159
- description: "Idea ID",
160
- required: true,
161
- },
162
- json: {
163
- type: "boolean",
164
- description: "Output as JSON",
165
- },
166
- },
167
- async run({ args }) {
168
- const apiKey = requireAuth();
169
- const client = new ApiClient(apiKey);
170
- const id = Number.parseInt(args.id, 10);
171
- if (Number.isNaN(id)) {
172
- console.log(pc.red("Invalid idea ID."));
173
- process.exit(EXIT_INVALID_ARGS);
174
- }
175
- try {
176
- const response = await client.getIdea(id);
177
- if (args.json) {
178
- console.log(JSON.stringify(response, null, 2));
179
- return;
180
- }
181
- const { idea } = response;
182
- const tags = formatTags(idea.tags);
183
- const title = idea.title || formatDate(idea.createdAt);
184
- console.log(pc.dim("─".repeat(40)));
185
- console.log(`Idea ${pc.cyan(`#${idea.id}`)} — ${pc.bold(title)}`);
186
- if (tags)
187
- console.log(`Tags: ${pc.yellow(tags)}`);
188
- console.log(pc.dim("─".repeat(40)));
189
- console.log();
190
- console.log(idea.content);
191
- }
192
- catch (error) {
193
- handleApiError(error);
194
- }
195
- },
196
- });
197
- const addSubcommand = defineCommand({
198
- meta: {
199
- name: "add",
200
- description: "Create a new idea",
201
- },
202
- args: {
203
- content: {
204
- type: "positional",
205
- description: "Idea content (Markdown)",
206
- required: true,
207
- },
208
- title: {
209
- type: "string",
210
- alias: "t",
211
- description: "Optional title",
212
- },
213
- tag: {
214
- type: "string",
215
- alias: "T",
216
- description: "Add tag by name",
217
- },
218
- json: {
219
- type: "boolean",
220
- description: "Output as JSON",
221
- },
222
- },
223
- async run({ args }) {
224
- const apiKey = requireAuth();
225
- const client = new ApiClient(apiKey);
226
- const content = args.content;
227
- if (!content.trim()) {
228
- console.log(pc.red("Content cannot be empty."));
229
- process.exit(EXIT_INVALID_ARGS);
230
- }
231
- try {
232
- // Resolve tag name to ID if provided
233
- let tagIds;
234
- if (args.tag) {
235
- const tagId = await resolveTagName(client, args.tag);
236
- if (tagId === null) {
237
- process.exit(EXIT_INVALID_ARGS);
238
- }
239
- tagIds = [tagId];
240
- }
241
- const request = {
242
- content,
243
- ...(args.title && { title: args.title }),
244
- ...(tagIds && { tagIds }),
245
- };
246
- const response = await client.createIdea(request);
247
- if (args.json) {
248
- console.log(JSON.stringify(response, null, 2));
249
- return;
250
- }
251
- const { idea } = response;
252
- const title = idea.title || formatDate(idea.createdAt);
253
- console.log(pc.green(`✓ Created idea ${pc.cyan(`#${idea.id}`)} (${title})`));
254
- }
255
- catch (error) {
256
- handleApiError(error);
257
- }
258
- },
259
- });
260
- const updateSubcommand = defineCommand({
261
- meta: {
262
- name: "update",
263
- description: "Update an existing idea",
264
- },
265
- args: {
266
- id: {
267
- type: "positional",
268
- description: "Idea ID",
269
- required: true,
270
- },
271
- content: {
272
- type: "string",
273
- alias: "c",
274
- description: "New content",
275
- },
276
- title: {
277
- type: "string",
278
- alias: "t",
279
- description: "New title (use empty string to clear)",
280
- },
281
- tag: {
282
- type: "string",
283
- alias: "T",
284
- description: "Set tag by name (replaces all existing tags)",
285
- },
286
- json: {
287
- type: "boolean",
288
- description: "Output as JSON",
289
- },
290
- },
291
- async run({ args }) {
292
- const apiKey = requireAuth();
293
- const client = new ApiClient(apiKey);
294
- const id = Number.parseInt(args.id, 10);
295
- if (Number.isNaN(id)) {
296
- console.log(pc.red("Invalid idea ID."));
297
- process.exit(EXIT_INVALID_ARGS);
298
- }
299
- // Build update request
300
- const request = {};
301
- if (args.content !== undefined)
302
- request.content = args.content;
303
- if (args.title !== undefined) {
304
- request.title = args.title === "" ? null : args.title;
305
- }
306
- // Resolve tag name if provided
307
- if (args.tag !== undefined) {
308
- if (args.tag === "") {
309
- // Empty string means clear all tags
310
- request.tagIds = [];
311
- }
312
- else {
313
- const tagId = await resolveTagName(client, args.tag);
314
- if (tagId === null) {
315
- process.exit(EXIT_INVALID_ARGS);
316
- }
317
- request.tagIds = [tagId];
318
- }
319
- }
320
- if (Object.keys(request).length === 0) {
321
- console.log(pc.yellow("No changes specified."));
322
- process.exit(EXIT_INVALID_ARGS);
323
- }
324
- try {
325
- const response = await client.updateIdea(id, request);
326
- if (args.json) {
327
- console.log(JSON.stringify(response, null, 2));
328
- return;
329
- }
330
- const { idea } = response;
331
- const title = idea.title || formatDate(idea.createdAt);
332
- console.log(pc.green(`✓ Updated idea ${pc.cyan(`#${idea.id}`)} (${title})`));
333
- }
334
- catch (error) {
335
- handleApiError(error);
336
- }
337
- },
338
- });
339
- const deleteSubcommand = defineCommand({
340
- meta: {
341
- name: "delete",
342
- description: "Delete an idea",
343
- },
344
- args: {
345
- id: {
346
- type: "positional",
347
- description: "Idea ID",
348
- required: true,
349
- },
350
- yes: {
351
- type: "boolean",
352
- alias: "y",
353
- description: "Skip confirmation",
354
- },
355
- json: {
356
- type: "boolean",
357
- description: "Output as JSON",
358
- },
359
- },
360
- async run({ args }) {
361
- const apiKey = requireAuth();
362
- const client = new ApiClient(apiKey);
363
- const id = Number.parseInt(args.id, 10);
364
- if (Number.isNaN(id)) {
365
- console.log(pc.red("Invalid idea ID."));
366
- process.exit(EXIT_INVALID_ARGS);
367
- }
368
- try {
369
- // Only fetch idea for confirmation prompt (requires ideas:read)
370
- // With --yes flag, skip prefetch to allow write-only keys
371
- if (!args.yes) {
372
- const { idea } = await client.getIdea(id);
373
- const title = idea.title || formatDate(idea.createdAt);
374
- const confirmed = await confirm(`Delete idea #${id} (${title})?`);
375
- if (!confirmed) {
376
- console.log(pc.dim("Cancelled."));
377
- return;
378
- }
379
- }
380
- await client.deleteIdea(id);
381
- if (args.json) {
382
- console.log(JSON.stringify({ success: true, id }, null, 2));
383
- return;
384
- }
385
- console.log(pc.green(`✓ Deleted idea ${pc.cyan(`#${id}`)}`));
386
- }
387
- catch (error) {
388
- handleApiError(error);
389
- }
390
- },
391
- });
392
- // ── Main command ──
8
+ import { defineCommand } from "@nocoo/cli-base";
9
+ import { addSubcommand } from "./idea/add.js";
10
+ import { deleteSubcommand } from "./idea/delete.js";
11
+ import { getSubcommand } from "./idea/get.js";
12
+ import { listSubcommand } from "./idea/list.js";
13
+ import { updateSubcommand } from "./idea/update.js";
14
+ export { formatTags } from "./idea/helpers.js";
393
15
  export const ideaCommand = defineCommand({
394
16
  meta: {
395
17
  name: "idea",
@@ -1 +1 @@
1
- {"version":3,"file":"idea.js","sourceRoot":"","sources":["../../src/commands/idea.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACN,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,gBAAgB;AAEhB,SAAS,WAAW;IACnB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACrC,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,KAAK,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,OAAe;IAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;QACvC,KAAK,EAAE,OAAO;QACd,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;KACjB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,IAAW;IAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,cAAc,CAC5B,MAAiB,EACjB,OAAe;IAEf,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAC1B,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAC1D,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,OAAO,oBAAoB,CAAC,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CACV,EAAE,CAAC,GAAG,CACL,wBAAwB,OAAO,iFAAiF,CAChH,CACD,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YACnC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACtB,CAAC,CAAC;QAEH,EAAE,CAAC,QAAQ,CAAC,GAAG,OAAO,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YAC3C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,oBAAoB;AAEpB,MAAM,cAAc,GAAG,aAAa,CAAC;IACpC,IAAI,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,gBAAgB;KAC7B;IACD,IAAI,EAAE;QACL,KAAK,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,2BAA2B;SACxC;QACD,GAAG,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,oBAAoB;SACjC;QACD,KAAK,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,0BAA0B;SACvC;QACD,IAAI,EAAE;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gBAAgB;SAC7B;KACD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,CAAC;YACJ,qCAAqC;YACrC,IAAI,KAAyB,CAAC;YAC9B,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACd,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;gBACxD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;oBACvB,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBACjC,CAAC;gBACD,KAAK,GAAG,QAAQ,CAAC;YAClB,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC;gBACvC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;gBACxD,KAAK;gBACL,CAAC,EAAE,IAAI,CAAC,KAAK;aACb,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/C,OAAO;YACR,CAAC;YAED,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAC1C,OAAO;YACR,CAAC;YAED,eAAe;YACf,OAAO,CAAC,GAAG,CACV,EAAE,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAC9D,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAEpC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACnC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,CAAC,KAAK,CACjE,CAAC,EACD,EAAE,CACF,CAAC;gBACF,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnC,OAAO,CAAC,GAAG,CACV,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC9F,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,aAAa,CAAC;IACnC,IAAI,EAAE;QACL,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,6BAA6B;KAC1C;IACD,IAAI,EAAE;QACL,EAAE,EAAE;YACH,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,SAAS;YACtB,QAAQ,EAAE,IAAI;SACd;QACD,IAAI,EAAE;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gBAAgB;SAC7B;KACD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAY,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAE1C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/C,OAAO;YACR,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;YAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClE,IAAI,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,aAAa,CAAC;IACnC,IAAI,EAAE;QACL,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,mBAAmB;KAChC;IACD,IAAI,EAAE;QACL,OAAO,EAAE;YACR,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,IAAI;SACd;QACD,KAAK,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,gBAAgB;SAC7B;QACD,GAAG,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,iBAAiB;SAC9B;QACD,IAAI,EAAE;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gBAAgB;SAC7B;KACD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAiB,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACJ,qCAAqC;YACrC,IAAI,MAA4B,CAAC;YACjC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACd,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBACjC,CAAC;gBACD,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,OAAO,GAAsB;gBAClC,OAAO;gBACP,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACxC,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;aACzB,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAElD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/C,OAAO;YACR,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CACV,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,CAC/D,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,aAAa,CAAC;IACtC,IAAI,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,yBAAyB;KACtC;IACD,IAAI,EAAE;QACL,EAAE,EAAE;YACH,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,SAAS;YACtB,QAAQ,EAAE,IAAI;SACd;QACD,OAAO,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,aAAa;SAC1B;QACD,KAAK,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,uCAAuC;SACpD;QACD,GAAG,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,8CAA8C;SAC3D;QACD,IAAI,EAAE;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gBAAgB;SAC7B;KACD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAY,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,uBAAuB;QACvB,MAAM,OAAO,GAAsB,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC/D,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACvD,CAAC;QAED,+BAA+B;QAC/B,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC;gBACrB,oCAAoC;gBACpC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACP,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBACjC,CAAC;gBACD,OAAO,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;QACF,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAEtD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/C,OAAO;YACR,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CACV,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,CAC/D,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,aAAa,CAAC;IACtC,IAAI,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,gBAAgB;KAC7B;IACD,IAAI,EAAE;QACL,EAAE,EAAE;YACH,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,SAAS;YACtB,QAAQ,EAAE,IAAI;SACd;QACD,GAAG,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,mBAAmB;SAChC;QACD,IAAI,EAAE;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gBAAgB;SAC7B;KACD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAY,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACJ,gEAAgE;YAChE,0DAA0D;YAC1D,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACf,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEvD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,gBAAgB,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC;gBAClE,IAAI,CAAC,SAAS,EAAE,CAAC;oBAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;oBAClC,OAAO;gBACR,CAAC;YACF,CAAC;YAED,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAE5B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5D,OAAO;YACR,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC;AAEH,qBAAqB;AAErB,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;IACxC,IAAI,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,+BAA+B;KAC5C;IACD,WAAW,EAAE;QACZ,IAAI,EAAE,cAAc;QACpB,GAAG,EAAE,aAAa;QAClB,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,gBAAgB;KACxB;CACD,CAAC,CAAC"}
1
+ {"version":3,"file":"idea.js","sourceRoot":"","sources":["../../src/commands/idea.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;IACxC,IAAI,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,+BAA+B;KAC5C;IACD,WAAW,EAAE;QACZ,IAAI,EAAE,cAAc;QACpB,GAAG,EAAE,aAAa;QAClB,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,gBAAgB;KACxB;CACD,CAAC,CAAC"}
@@ -59,5 +59,9 @@ export declare const listCommand: import("citty").CommandDef<{
59
59
  readonly alias: "c";
60
60
  readonly description: "Show only the count of matching links";
61
61
  };
62
+ readonly "show-tags": {
63
+ readonly type: "boolean";
64
+ readonly description: "Show TAGS column in table output (auto-enabled with --tag)";
65
+ };
62
66
  }>;
63
67
  //# sourceMappingURL=list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkKtB,CAAC"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkJH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6HtB,CAAC"}
@@ -4,7 +4,101 @@
4
4
  import { defineCommand, pc } from "@nocoo/cli-base";
5
5
  import { ApiClient, ApiClientError, EXIT_AUTH_REQUIRED, EXIT_ERROR, EXIT_INVALID_ARGS, EXIT_RATE_LIMITED, } from "../api/client.js";
6
6
  import { getApiKey, getOutputFormat } from "../config.js";
7
- import { formatLinksMinimal, formatLinksTable, resolveFolderName, resolveTagName, } from "../utils.js";
7
+ import { formatLinksMinimal, formatLinksTable, resolveTagName, } from "../utils.js";
8
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9
+ /** Reject mutually-exclusive flags + invalid sort/order. Exits on error. */
10
+ function validateListArgs(args) {
11
+ if (args.inbox && args.folder) {
12
+ console.log(pc.red("Cannot use --inbox and --folder together."));
13
+ process.exit(EXIT_INVALID_ARGS);
14
+ }
15
+ if (args.sort && args.sort !== "created" && args.sort !== "clicks") {
16
+ console.log(pc.red("Invalid --sort value. Use 'created' or 'clicks'."));
17
+ process.exit(EXIT_INVALID_ARGS);
18
+ }
19
+ if (args.order && args.order !== "asc" && args.order !== "desc") {
20
+ console.log(pc.red("Invalid --order value. Use 'asc' or 'desc'."));
21
+ process.exit(EXIT_INVALID_ARGS);
22
+ }
23
+ }
24
+ /**
25
+ * Build ListLinksParams from CLI args, resolving folder/tag names where
26
+ * needed. Returns the params plus any folder list already fetched for reuse.
27
+ * Exits on invalid folder/tag.
28
+ */
29
+ async function buildListParams(client, args) {
30
+ // Pre-fetch folders only when --folder is a non-UUID name that must be
31
+ // resolved (a UUID can be used directly without folders:read scope).
32
+ const folderArg = args.folder;
33
+ const needsFolderResolution = !!folderArg && !UUID_PATTERN.test(folderArg);
34
+ let cachedFolders;
35
+ if (needsFolderResolution) {
36
+ const foldersResponse = await client.listFolders();
37
+ cachedFolders = foldersResponse.folders;
38
+ }
39
+ const params = {};
40
+ if (args.limit)
41
+ params.limit = Number.parseInt(args.limit, 10);
42
+ if (args.offset)
43
+ params.offset = Number.parseInt(args.offset, 10);
44
+ if (args.query)
45
+ params.query = args.query;
46
+ if (args.inbox)
47
+ params.inbox = true;
48
+ if (args.sort)
49
+ params.sort = args.sort;
50
+ if (args.order)
51
+ params.order = args.order;
52
+ if (folderArg) {
53
+ if (UUID_PATTERN.test(folderArg)) {
54
+ params.folderId = folderArg;
55
+ }
56
+ else if (cachedFolders) {
57
+ const folderId = resolveFolderNameFromCache(folderArg, cachedFolders);
58
+ if (folderId === null)
59
+ process.exit(EXIT_INVALID_ARGS);
60
+ params.folderId = folderId;
61
+ }
62
+ }
63
+ if (args.tag) {
64
+ const tagId = await resolveTagName(client, args.tag);
65
+ if (tagId === null)
66
+ process.exit(EXIT_INVALID_ARGS);
67
+ params.tagId = tagId;
68
+ }
69
+ return cachedFolders ? { params, cachedFolders } : { params };
70
+ }
71
+ /** Build folder + tag name maps for table output, with graceful fallback. */
72
+ async function loadDisplayMaps(client, links, cachedFolders, showTags) {
73
+ const result = {};
74
+ const hasFolders = links.some((l) => l.folderId);
75
+ if (hasFolders) {
76
+ try {
77
+ const folders = cachedFolders ?? (await client.listFolders()).folders;
78
+ result.folderMap = new Map(folders.map((f) => [f.id, f.name]));
79
+ }
80
+ catch {
81
+ // continue without folder names
82
+ }
83
+ }
84
+ // Build tag name map only when we will render tags AND the response is
85
+ // missing embedded tag details. The /links endpoint already includes
86
+ // `tags: Tag[]` per link, so a successful response makes listTags()
87
+ // unnecessary; we only fall back when some tagged link is missing its
88
+ // tags array (older server, or partial response).
89
+ const needsTagFallback = showTags &&
90
+ links.some((l) => (l.tagIds ?? []).length > 0 && (!l.tags || l.tags.length === 0));
91
+ if (needsTagFallback) {
92
+ try {
93
+ const tagsResponse = await client.listTags();
94
+ result.tagMap = new Map(tagsResponse.tags.map((t) => [t.id, t.name]));
95
+ }
96
+ catch {
97
+ // continue without tag names
98
+ }
99
+ }
100
+ return result;
101
+ }
8
102
  export const listCommand = defineCommand({
9
103
  meta: {
10
104
  name: "list",
@@ -68,6 +162,10 @@ export const listCommand = defineCommand({
68
162
  alias: "c",
69
163
  description: "Show only the count of matching links",
70
164
  },
165
+ "show-tags": {
166
+ type: "boolean",
167
+ description: "Show TAGS column in table output (auto-enabled with --tag)",
168
+ },
71
169
  },
72
170
  async run({ args }) {
73
171
  const apiKey = getApiKey();
@@ -75,72 +173,17 @@ export const listCommand = defineCommand({
75
173
  console.log(pc.red("Not authenticated. Run `zhe login` first."));
76
174
  process.exit(EXIT_AUTH_REQUIRED);
77
175
  }
78
- // Validate mutually exclusive options
79
- if (args.inbox && args.folder) {
80
- console.log(pc.red("Cannot use --inbox and --folder together."));
81
- process.exit(EXIT_INVALID_ARGS);
82
- }
83
- // Validate sort option
84
- if (args.sort && args.sort !== "created" && args.sort !== "clicks") {
85
- console.log(pc.red("Invalid --sort value. Use 'created' or 'clicks'."));
86
- process.exit(EXIT_INVALID_ARGS);
87
- }
88
- // Validate order option
89
- if (args.order && args.order !== "asc" && args.order !== "desc") {
90
- console.log(pc.red("Invalid --order value. Use 'asc' or 'desc'."));
91
- process.exit(EXIT_INVALID_ARGS);
92
- }
176
+ validateListArgs(args);
93
177
  const client = new ApiClient(apiKey);
94
178
  try {
95
- // Build params object, only including defined fields
96
- const params = {};
97
- if (args.limit)
98
- params.limit = Number.parseInt(args.limit, 10);
99
- if (args.offset)
100
- params.offset = Number.parseInt(args.offset, 10);
101
- if (args.query)
102
- params.query = args.query;
103
- if (args.inbox)
104
- params.inbox = true;
105
- if (args.sort)
106
- params.sort = args.sort;
107
- if (args.order)
108
- params.order = args.order;
109
- // Resolve folder name to ID
110
- if (args.folder) {
111
- const folderId = await resolveFolderName(client, args.folder);
112
- if (folderId === null) {
113
- process.exit(EXIT_INVALID_ARGS);
114
- }
115
- params.folderId = folderId;
116
- }
117
- // Resolve tag name to ID
118
- if (args.tag) {
119
- const tagId = await resolveTagName(client, args.tag);
120
- if (tagId === null) {
121
- process.exit(EXIT_INVALID_ARGS);
122
- }
123
- params.tagId = tagId;
124
- }
179
+ const { params, cachedFolders } = await buildListParams(client, args);
125
180
  const response = await client.listLinks(params);
126
- // Count-only mode: use total from API response
127
181
  if (args.count) {
128
182
  console.log(response.total);
129
183
  return;
130
184
  }
131
- // Build folder name map for table output
132
- let folderMap;
133
- const hasFolders = response.links.some((l) => l.folderId);
134
- if (hasFolders) {
135
- try {
136
- const foldersResponse = await client.listFolders();
137
- folderMap = new Map(foldersResponse.folders.map((f) => [f.id, f.name]));
138
- }
139
- catch {
140
- // If folder fetch fails, continue without folder names
141
- }
142
- }
143
- // Determine output format
185
+ const showTags = !!(args["show-tags"] || args.tag);
186
+ const { folderMap, tagMap } = await loadDisplayMaps(client, response.links, cachedFolders, showTags);
144
187
  let format = getOutputFormat();
145
188
  if (args.json)
146
189
  format = "json";
@@ -154,7 +197,12 @@ export const listCommand = defineCommand({
154
197
  console.log(formatLinksMinimal(response.links));
155
198
  break;
156
199
  default:
157
- console.log(formatLinksTable(response.links, { wide: args.wide, folderMap }));
200
+ console.log(formatLinksTable(response.links, {
201
+ wide: args.wide,
202
+ folderMap,
203
+ tagMap,
204
+ showTags,
205
+ }));
158
206
  }
159
207
  }
160
208
  catch (error) {
@@ -175,4 +223,28 @@ function handleApiError(error) {
175
223
  }
176
224
  throw error;
177
225
  }
226
+ /**
227
+ * Resolve folder name to ID from cached folders list.
228
+ * If input looks like a UUID, use it directly.
229
+ * Returns null if folder is not found (with error message printed).
230
+ */
231
+ function resolveFolderNameFromCache(input, folders) {
232
+ // Check if input looks like a UUID (36 chars with dashes)
233
+ const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
234
+ if (uuidPattern.test(input)) {
235
+ return input; // Assume it's already an ID
236
+ }
237
+ // Otherwise, resolve by name
238
+ const matches = folders.filter((f) => f.name.toLowerCase() === input.toLowerCase());
239
+ if (matches.length === 0) {
240
+ console.log(pc.red(`Folder not found: ${input}`));
241
+ return null;
242
+ }
243
+ if (matches.length > 1) {
244
+ console.log(pc.red(`Multiple folders match "${input}". Please use the folder ID instead.`));
245
+ console.log(pc.dim("Use `zhe folders` to see all folder IDs."));
246
+ return null;
247
+ }
248
+ return matches[0].id;
249
+ }
178
250
  //# sourceMappingURL=list.js.map