pnote 0.1.0 → 0.1.2

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
@@ -47,6 +47,8 @@ pnote notes --archived # Show archived
47
47
  pnote notes --pinned # Show pinned only
48
48
  pnote notes get <id> # Get note details
49
49
  pnote notes create "Title" # Create new note
50
+ pnote notes update <id> --title "New Title" # Update title
51
+ pnote notes update <id> --tags a b c # Replace tags
50
52
  pnote notes archive <id> # Archive note
51
53
  pnote notes pin <id> # Toggle pin
52
54
  pnote notes delete <id> # Delete note
@@ -59,7 +61,8 @@ pnote snippet <note-id> # Show latest snippet
59
61
  pnote snippet <note-id> --all # Show all versions
60
62
  pnote snippet copy <note-id> # Copy to clipboard
61
63
  echo "content" | pnote snippet add <note-id> # Add new version
62
- pnote snippet favorite <id> # Toggle favorite
64
+ echo "updated" | pnote snippet update <snippet-id> # Update existing
65
+ pnote snippet favorite <snippet-id> # Toggle favorite
63
66
  ```
64
67
 
65
68
  ### Tags
@@ -70,6 +73,15 @@ pnote tags rename "old" "new" # Rename tag
70
73
  pnote tags merge "a" "b" --into "c" # Merge tags
71
74
  ```
72
75
 
76
+ ### Sharing
77
+
78
+ ```bash
79
+ pnote share tags # List shared tags
80
+ pnote share tags <id> # View notes in shared tag
81
+ pnote share notes # List public share links
82
+ pnote share notes --include-revoked # Include revoked links
83
+ ```
84
+
73
85
  ### Search
74
86
 
75
87
  ```bash
@@ -92,9 +104,9 @@ pnote search "query" --limit 50 # Limit results
92
104
 
93
105
  | Variable | Description |
94
106
  |----------|-------------|
95
- | `PROMTIE_TOKEN` | PAT token (overrides stored credentials) |
107
+ | `PNOTE_TOKEN` | PAT token (overrides stored credentials) |
96
108
  | `NO_COLOR` | Disable colors |
97
- | `PROMTIE_API_ENDPOINT` | Custom API endpoint |
109
+ | `PNOTE_API_ENDPOINT` | Custom API endpoint |
98
110
 
99
111
  ## Unix Philosophy
100
112
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command6 } from "commander";
4
+ import { Command as Command7 } from "commander";
5
5
 
6
6
  // src/lib/errors.ts
7
7
  import pc from "picocolors";
@@ -178,7 +178,7 @@ async function loginAction() {
178
178
  console.log(" 3. Generate a new token");
179
179
  console.log(" 4. Run: " + pc2.cyan("pnote auth token <your-token>"));
180
180
  console.log("");
181
- console.log(pc2.dim("Or set the PROMTIE_TOKEN environment variable."));
181
+ console.log(pc2.dim("Or set the PNOTE_TOKEN environment variable."));
182
182
  }
183
183
 
184
184
  // src/commands/auth/token.ts
@@ -284,6 +284,9 @@ async function listSnippets(params, options = {}) {
284
284
  async function createSnippet(data, options = {}) {
285
285
  return callRestApi("POST", "/snippets", data, options);
286
286
  }
287
+ async function updateSnippet(id, data, options = {}) {
288
+ return callRestApi("PATCH", `/snippets/${id}`, data, options);
289
+ }
287
290
  async function toggleFavorite(id, options = {}) {
288
291
  return callRestApi("POST", `/snippets/${id}/favorite`, {}, options);
289
292
  }
@@ -307,93 +310,20 @@ async function search(params, options = {}) {
307
310
  if (params.limit) query.set("limit", String(params.limit));
308
311
  return callRestApi("GET", `/search?${query.toString()}`, void 0, options);
309
312
  }
310
- var requestId = 0;
311
- function getNextId() {
312
- return ++requestId;
313
+ async function listSharedTags(options = {}) {
314
+ return callRestApi("GET", "/share/tags", void 0, options);
313
315
  }
314
- async function callMCP(toolName, args = {}) {
315
- const token = getToken();
316
- if (!token) {
317
- throw new AuthError(
318
- "Not logged in",
319
- "Run 'pnote auth login' or 'pnote auth token <token>' to authenticate"
320
- );
321
- }
322
- const endpoint = getApiEndpoint();
323
- const request = {
324
- jsonrpc: "2.0",
325
- id: getNextId(),
326
- method: "tools/call",
327
- params: {
328
- name: toolName,
329
- arguments: args
330
- }
331
- };
332
- let response;
333
- try {
334
- response = await fetch(endpoint, {
335
- method: "POST",
336
- headers: {
337
- "Content-Type": "application/json",
338
- Authorization: `Bearer ${token}`
339
- },
340
- body: JSON.stringify(request),
341
- signal: AbortSignal.timeout(3e4)
342
- });
343
- } catch (error) {
344
- if (error instanceof Error) {
345
- if (error.name === "TimeoutError" || error.name === "AbortError") {
346
- throw new NetworkError("Request timed out. Please try again.");
347
- }
348
- if (error.message.includes("fetch")) {
349
- throw new NetworkError("Unable to connect to PromptNote API. Check your internet connection.");
350
- }
351
- }
352
- throw new NetworkError();
353
- }
354
- if (!response.ok) {
355
- const body = await response.text();
356
- if (response.status === 401) {
357
- throw new AuthError(
358
- "Invalid or expired token",
359
- "Run 'pnote auth login' to re-authenticate"
360
- );
361
- }
362
- if (response.status === 403) {
363
- throw new CLIError("Permission denied", ExitCode.AUTH_ERROR);
364
- }
365
- throw new CLIError(`API error (${response.status}): ${body}`);
366
- }
367
- const mcpResponse = await response.json();
368
- if (mcpResponse.error) {
369
- throw new CLIError(`MCP error: ${mcpResponse.error.message}`);
370
- }
371
- if (!mcpResponse.result) {
372
- throw new CLIError("Invalid response from API");
373
- }
374
- const content = mcpResponse.result.content;
375
- if (!content || content.length === 0) {
376
- throw new CLIError("Empty response from API");
377
- }
378
- if (mcpResponse.result.isError) {
379
- const errorText = content[0]?.text || "Unknown error";
380
- if (errorText.includes("not found") || errorText.includes("PGRST116")) {
381
- throw new CLIError("Resource not found", ExitCode.NOT_FOUND);
382
- }
383
- if (errorText.includes("Unauthorized")) {
384
- throw new AuthError(errorText);
385
- }
386
- throw new CLIError(errorText);
387
- }
388
- const textContent = content[0]?.text;
389
- if (!textContent) {
390
- throw new CLIError("No content in response");
391
- }
392
- try {
393
- return JSON.parse(textContent);
394
- } catch {
395
- return textContent;
396
- }
316
+ async function getSharedTagNotes(id, params = {}, options = {}) {
317
+ const query = new URLSearchParams();
318
+ if (params.limit) query.set("limit", String(params.limit));
319
+ const queryString = query.toString();
320
+ return callRestApi("GET", `/share/tags/${id}/notes${queryString ? `?${queryString}` : ""}`, void 0, options);
321
+ }
322
+ async function listSharedNotes(params = {}, options = {}) {
323
+ const query = new URLSearchParams();
324
+ if (params.include_revoked !== void 0) query.set("include_revoked", String(params.include_revoked));
325
+ const queryString = query.toString();
326
+ return callRestApi("GET", `/share/notes${queryString ? `?${queryString}` : ""}`, void 0, options);
397
327
  }
398
328
  async function verifyToken(token) {
399
329
  const baseUrl = getApiEndpoint().replace(/\/mcp$/, "/v1");
@@ -464,12 +394,12 @@ async function logoutAction() {
464
394
  } else {
465
395
  console.log(pc4.dim("No credentials to remove."));
466
396
  }
467
- if (process.env.PROMTIE_TOKEN) {
397
+ if (process.env.PNOTE_TOKEN) {
468
398
  console.log("");
469
399
  console.log(
470
- pc4.yellow("Note:") + " PROMTIE_TOKEN environment variable is still set."
400
+ pc4.yellow("Note:") + " PNOTE_TOKEN environment variable is still set."
471
401
  );
472
- console.log(pc4.dim("Unset it with: unset PROMTIE_TOKEN"));
402
+ console.log(pc4.dim("Unset it with: unset PNOTE_TOKEN"));
473
403
  }
474
404
  }
475
405
 
@@ -487,9 +417,7 @@ async function whoamiAction() {
487
417
  throw new AuthError("No credentials found");
488
418
  }
489
419
  try {
490
- const result = await callMCP("promptnote_list_notes", {
491
- limit: 1
492
- });
420
+ const result = await listNotes({ limit: 1 });
493
421
  console.log(pc5.green("\u2713") + " Authenticated");
494
422
  console.log("");
495
423
  if (creds.email) {
@@ -497,8 +425,8 @@ async function whoamiAction() {
497
425
  }
498
426
  console.log(pc5.dim("Token: ") + creds.token.slice(0, 7) + "..." + creds.token.slice(-4));
499
427
  console.log(pc5.dim("Stored: ") + getCredentialsPath());
500
- if (process.env.PROMTIE_TOKEN) {
501
- console.log(pc5.dim("Source: ") + "PROMTIE_TOKEN environment variable");
428
+ if (process.env.PNOTE_TOKEN) {
429
+ console.log(pc5.dim("Source: ") + "PNOTE_TOKEN environment variable");
502
430
  } else {
503
431
  console.log(pc5.dim("Source: ") + "credentials file");
504
432
  }
@@ -779,6 +707,103 @@ function outputSearchResults(query, notes, snippets, ctx) {
779
707
  }
780
708
  }
781
709
  }
710
+ function outputSharedTags(data, ctx) {
711
+ if (ctx.json) {
712
+ outputJson(data);
713
+ return;
714
+ }
715
+ const c = getColors(ctx);
716
+ const totalCount = data.owned.count + data.shared_with_me.count;
717
+ if (totalCount === 0) {
718
+ console.log(c.dim("No shared tags."));
719
+ return;
720
+ }
721
+ if (isHumanOutput(ctx)) {
722
+ if (data.owned.count > 0) {
723
+ console.log(c.bold(`Owned (${data.owned.count})`));
724
+ console.log("");
725
+ for (const tag of data.owned.tags) {
726
+ console.log(
727
+ " " + c.cyan(tag.id.slice(0, 8)) + " " + pad(tag.tag_path, 24) + " " + c.dim(formatRelativeTime(tag.created_at))
728
+ );
729
+ }
730
+ console.log("");
731
+ }
732
+ if (data.shared_with_me.count > 0) {
733
+ console.log(c.bold(`Shared with me (${data.shared_with_me.count})`));
734
+ console.log("");
735
+ for (const tag of data.shared_with_me.tags) {
736
+ console.log(
737
+ " " + c.cyan(tag.id.slice(0, 8)) + " " + pad(tag.tag_path, 24) + " " + c.dim("joined " + formatRelativeTime(tag.joined_at))
738
+ );
739
+ }
740
+ }
741
+ } else {
742
+ for (const tag of data.owned.tags) {
743
+ console.log(["owned", tag.id, tag.tag_path, tag.created_at].join(" "));
744
+ }
745
+ for (const tag of data.shared_with_me.tags) {
746
+ console.log(["shared", tag.id, tag.tag_path, tag.joined_at].join(" "));
747
+ }
748
+ }
749
+ }
750
+ function outputSharedTagNotes(data, ctx) {
751
+ if (ctx.json) {
752
+ outputJson(data);
753
+ return;
754
+ }
755
+ const c = getColors(ctx);
756
+ if (isHumanOutput(ctx)) {
757
+ const role = data.shared_tag.is_owner ? "owner" : "member";
758
+ console.log(c.bold(data.shared_tag.tag_path) + c.dim(` (${role}, ${data.members_count} members)`));
759
+ console.log("");
760
+ if (data.notes.length === 0) {
761
+ console.log(c.dim(" No notes in this shared tag."));
762
+ return;
763
+ }
764
+ console.log(
765
+ " " + c.dim(pad("ID", 10)) + " " + c.dim(pad("TITLE", 24)) + " " + c.dim(pad("AUTHOR", 20)) + " " + c.dim("UPDATED")
766
+ );
767
+ for (const note of data.notes) {
768
+ const author = note.is_own ? "you" : note.author.email || "unknown";
769
+ console.log(
770
+ " " + pad(note.id.slice(0, 8), 10) + " " + pad(truncate(note.title, 24), 24) + " " + pad(truncate(author, 20), 20) + " " + formatRelativeTime(note.updated_at)
771
+ );
772
+ }
773
+ } else {
774
+ for (const note of data.notes) {
775
+ const author = note.is_own ? "you" : note.author.email || "unknown";
776
+ console.log([note.id, note.title, author, note.updated_at].join(" "));
777
+ }
778
+ }
779
+ }
780
+ function outputSharedNotes(data, ctx) {
781
+ if (ctx.json) {
782
+ outputJson(data);
783
+ return;
784
+ }
785
+ const c = getColors(ctx);
786
+ if (data.count === 0) {
787
+ console.log(c.dim("No shared notes."));
788
+ return;
789
+ }
790
+ if (isHumanOutput(ctx)) {
791
+ console.log(c.bold(`Shared Notes (${data.count})`));
792
+ console.log("");
793
+ for (const share of data.shares) {
794
+ const revoked = share.is_revoked ? c.red(" [R]") : "";
795
+ console.log(
796
+ " " + truncate(share.note_title, 20) + " " + c.cyan(share.share_url) + " " + c.dim(`${share.view_count} views`) + " " + c.dim(formatRelativeTime(share.created_at)) + revoked
797
+ );
798
+ }
799
+ } else {
800
+ for (const share of data.shares) {
801
+ console.log(
802
+ [share.note_title, share.share_url, share.view_count, share.is_revoked, share.created_at].join(" ")
803
+ );
804
+ }
805
+ }
806
+ }
782
807
  function outputMessage(message, ctx) {
783
808
  if (ctx.json) {
784
809
  outputJson({ message });
@@ -851,7 +876,7 @@ async function createNoteAction(title, options, ctx) {
851
876
  const result = await createNote(
852
877
  {
853
878
  title,
854
- tags: options.tag && options.tag.length > 0 ? options.tag : void 0,
879
+ tags: options.tags && options.tags.length > 0 ? options.tags : void 0,
855
880
  content
856
881
  },
857
882
  { pin: ctx.pin }
@@ -911,9 +936,6 @@ async function pinNoteAction(id, ctx) {
911
936
  import pc7 from "picocolors";
912
937
  import { createInterface } from "readline";
913
938
  async function confirm(message) {
914
- if (!process.stdin.isTTY) {
915
- return false;
916
- }
917
939
  const rl = createInterface({
918
940
  input: process.stdin,
919
941
  output: process.stdout
@@ -929,6 +951,13 @@ async function deleteNoteAction(id, options, ctx) {
929
951
  try {
930
952
  const note = await getNote(id, { pin: ctx.pin });
931
953
  if (!options.force && !ctx.json) {
954
+ if (!process.stdin.isTTY) {
955
+ throw new CLIError(
956
+ "Cannot confirm deletion in non-interactive mode",
957
+ ExitCode.GENERAL_ERROR,
958
+ "Use --force for non-interactive deletion"
959
+ );
960
+ }
932
961
  console.log(`About to delete: ${pc7.bold(note.title)}`);
933
962
  const confirmed = await confirm("Are you sure?");
934
963
  if (!confirmed) {
@@ -947,6 +976,30 @@ async function deleteNoteAction(id, options, ctx) {
947
976
  }
948
977
  }
949
978
 
979
+ // src/commands/notes/update.ts
980
+ async function updateNoteAction(id, options, ctx) {
981
+ try {
982
+ if (!options.title && !options.tags) {
983
+ throw new CLIError(
984
+ "No changes provided",
985
+ 1,
986
+ "Use --title or --tags to specify what to update"
987
+ );
988
+ }
989
+ const data = {};
990
+ if (options.title) data.title = options.title;
991
+ if (options.tags) data.tags = options.tags;
992
+ const result = await updateNote(id, data, { pin: ctx.pin });
993
+ if (ctx.json) {
994
+ outputJson(result);
995
+ } else {
996
+ outputMessage(`Updated note: ${result.note.title}`, ctx);
997
+ }
998
+ } catch (error) {
999
+ handleError(error, ctx.noColor);
1000
+ }
1001
+ }
1002
+
950
1003
  // src/lib/pin.ts
951
1004
  import { createInterface as createInterface2 } from "readline";
952
1005
  import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, statSync } from "fs";
@@ -1129,6 +1182,7 @@ Examples:
1129
1182
  $ pnote notes --pinned Show only pinned notes
1130
1183
  $ pnote notes get abc123 Get note details
1131
1184
  $ pnote notes create "My Note" Create a new note
1185
+ $ pnote notes update abc123 --title "New Title"
1132
1186
  `
1133
1187
  );
1134
1188
  notesCommand.command("get").description("Get a note with its latest snippet").argument("<id>", "Note ID").action(async (id, _options, cmd) => {
@@ -1136,7 +1190,7 @@ notesCommand.command("get").description("Get a note with its latest snippet").ar
1136
1190
  const ctx = await buildContext(globalOpts);
1137
1191
  await getNoteAction(id, ctx);
1138
1192
  });
1139
- notesCommand.command("create").description("Create a new note").argument("<title>", "Note title").option("--tag <tags...>", "Tags for the note").option("--content <content>", "Initial snippet content").action(async (title, options, cmd) => {
1193
+ notesCommand.command("create").description("Create a new note").argument("<title>", "Note title").option("--tags <tags...>", "Tags for the note").option("--content <content>", "Initial snippet content").action(async (title, options, cmd) => {
1140
1194
  const globalOpts = cmd.parent?.parent?.opts() || {};
1141
1195
  const ctx = await buildContext(globalOpts);
1142
1196
  await createNoteAction(title, options, ctx);
@@ -1151,6 +1205,11 @@ notesCommand.command("pin").description("Pin or unpin a note").argument("<id>",
1151
1205
  const ctx = await buildContext(globalOpts);
1152
1206
  await pinNoteAction(id, ctx);
1153
1207
  });
1208
+ notesCommand.command("update").description("Update a note title or tags").argument("<id>", "Note ID").option("--title <title>", "New title").option("--tags <tags...>", "New tags (replaces existing)").action(async (id, options, cmd) => {
1209
+ const globalOpts = cmd.parent?.parent?.opts() || {};
1210
+ const ctx = await buildContext(globalOpts);
1211
+ await updateNoteAction(id, options, ctx);
1212
+ });
1154
1213
  notesCommand.command("delete").description("Delete a note (soft delete)").argument("<id>", "Note ID").option("--force", "Skip confirmation").action(async (id, options, cmd) => {
1155
1214
  const globalOpts = cmd.parent?.parent?.opts() || {};
1156
1215
  const ctx = await buildContext(globalOpts);
@@ -1287,6 +1346,48 @@ async function addSnippetAction(noteId, options, ctx) {
1287
1346
  }
1288
1347
  }
1289
1348
 
1349
+ // src/commands/snippet/update.ts
1350
+ async function updateSnippetAction(snippetId, options, ctx) {
1351
+ try {
1352
+ let content;
1353
+ if (!process.stdin.isTTY) {
1354
+ const chunks = [];
1355
+ for await (const chunk of process.stdin) {
1356
+ chunks.push(chunk);
1357
+ }
1358
+ content = Buffer.concat(chunks).toString("utf-8");
1359
+ if (content.endsWith("\n")) {
1360
+ content = content.slice(0, -1);
1361
+ }
1362
+ if (!content) {
1363
+ content = void 0;
1364
+ }
1365
+ }
1366
+ if (!content && !options.title) {
1367
+ throw new CLIError(
1368
+ "No content or title provided",
1369
+ 1,
1370
+ "Pipe content to this command: echo 'content' | pnote snippet update <snippet-id>"
1371
+ );
1372
+ }
1373
+ const data = {};
1374
+ if (content) data.content = content;
1375
+ if (options.title) data.title = options.title;
1376
+ const result = await updateSnippet(
1377
+ snippetId,
1378
+ data,
1379
+ { pin: ctx.pin }
1380
+ );
1381
+ if (ctx.json) {
1382
+ outputJson(result);
1383
+ } else {
1384
+ outputMessage("Updated snippet", ctx);
1385
+ }
1386
+ } catch (error) {
1387
+ handleError(error, ctx.noColor);
1388
+ }
1389
+ }
1390
+
1290
1391
  // src/commands/snippet/favorite.ts
1291
1392
  async function favoriteSnippetAction(snippetId, ctx) {
1292
1393
  try {
@@ -1344,6 +1445,11 @@ snippetCommand.command("add").description("Add a new snippet version (from stdin
1344
1445
  const ctx = await buildContext2(globalOpts);
1345
1446
  await addSnippetAction(noteId, options, ctx);
1346
1447
  });
1448
+ snippetCommand.command("update").description("Update an existing snippet (from stdin)").argument("<snippet-id>", "Snippet ID").option("--title <title>", "New snippet title").action(async (snippetId, options, cmd) => {
1449
+ const globalOpts = cmd.parent?.parent?.opts() || {};
1450
+ const ctx = await buildContext2(globalOpts);
1451
+ await updateSnippetAction(snippetId, options, ctx);
1452
+ });
1347
1453
  snippetCommand.command("favorite").description("Toggle favorite status on a snippet").argument("<snippet-id>", "Snippet ID").action(async (snippetId, _options, cmd) => {
1348
1454
  const globalOpts = cmd.parent?.parent?.opts() || {};
1349
1455
  const ctx = await buildContext2(globalOpts);
@@ -1480,11 +1586,16 @@ async function searchAction(query, options, ctx) {
1480
1586
  }
1481
1587
  var searchCommand = new Command5("search").description("Search notes and snippets").argument("<query>", "Search query").option("--notes-only", "Only search note titles and tags").option("--snippets-only", "Only search snippet content").option("--limit <n>", "Limit results", "20").action(async (query, options, cmd) => {
1482
1588
  const globalOpts = cmd.parent?.opts() || {};
1589
+ const pin = await resolvePin({
1590
+ pinArg: globalOpts.pin,
1591
+ pinFromStdin: globalOpts.pinStdin,
1592
+ skipPrompt: true
1593
+ });
1483
1594
  const ctx = {
1484
1595
  json: globalOpts.json ?? false,
1485
1596
  noColor: globalOpts.noColor ?? false,
1486
1597
  plain: globalOpts.plain ?? false,
1487
- pin: globalOpts.pin
1598
+ pin: pin ?? void 0
1488
1599
  };
1489
1600
  await searchAction(query, options, ctx);
1490
1601
  }).addHelpText(
@@ -1497,8 +1608,85 @@ Examples:
1497
1608
  `
1498
1609
  );
1499
1610
 
1611
+ // src/commands/share/index.ts
1612
+ import { Command as Command6 } from "commander";
1613
+
1614
+ // src/commands/share/tags.ts
1615
+ async function listSharedTagsAction(ctx) {
1616
+ try {
1617
+ const result = await listSharedTags({ pin: ctx.pin });
1618
+ outputSharedTags(result, ctx);
1619
+ } catch (error) {
1620
+ handleError(error, ctx.noColor);
1621
+ }
1622
+ }
1623
+ async function getSharedTagNotesAction(id, options, ctx) {
1624
+ try {
1625
+ const result = await getSharedTagNotes(
1626
+ id,
1627
+ { limit: options.limit ? parseInt(options.limit, 10) : void 0 },
1628
+ { pin: ctx.pin }
1629
+ );
1630
+ outputSharedTagNotes(result, ctx);
1631
+ } catch (error) {
1632
+ handleError(error, ctx.noColor);
1633
+ }
1634
+ }
1635
+
1636
+ // src/commands/share/notes.ts
1637
+ async function listSharedNotesAction(options, ctx) {
1638
+ try {
1639
+ const result = await listSharedNotes(
1640
+ { include_revoked: options.includeRevoked },
1641
+ { pin: ctx.pin }
1642
+ );
1643
+ outputSharedNotes(result, ctx);
1644
+ } catch (error) {
1645
+ handleError(error, ctx.noColor);
1646
+ }
1647
+ }
1648
+
1649
+ // src/commands/share/index.ts
1650
+ async function buildContext4(globalOpts) {
1651
+ const pin = await resolvePin({
1652
+ pinArg: globalOpts.pin,
1653
+ pinFromStdin: globalOpts.pinStdin,
1654
+ skipPrompt: true
1655
+ });
1656
+ return {
1657
+ json: globalOpts.json ?? false,
1658
+ noColor: globalOpts.noColor ?? false,
1659
+ plain: globalOpts.plain ?? false,
1660
+ pin: pin ?? void 0
1661
+ };
1662
+ }
1663
+ var shareCommand = new Command6("share").description("View shared tags and shared note links").addHelpText(
1664
+ "after",
1665
+ `
1666
+ Examples:
1667
+ $ pnote share tags List shared tags
1668
+ $ pnote share tags abc123 View notes in shared tag
1669
+ $ pnote share notes List public share links
1670
+ $ pnote share notes --include-revoked
1671
+ `
1672
+ );
1673
+ shareCommand.command("tags").description("List shared tags or view notes in a shared tag").argument("[id]", "Shared tag ID to view notes").option("--limit <n>", "Limit notes returned").action(async (id, options, cmd) => {
1674
+ const globalOpts = cmd.parent?.parent?.opts() || {};
1675
+ const ctx = await buildContext4(globalOpts);
1676
+ if (id) {
1677
+ await getSharedTagNotesAction(id, options, ctx);
1678
+ } else {
1679
+ await listSharedTagsAction(ctx);
1680
+ }
1681
+ });
1682
+ shareCommand.command("notes").description("List public share links for your notes").option("--include-revoked", "Include revoked share links").action(async (options, cmd) => {
1683
+ const globalOpts = cmd.parent?.parent?.opts() || {};
1684
+ const ctx = await buildContext4(globalOpts);
1685
+ await listSharedNotesAction(options, ctx);
1686
+ });
1687
+
1500
1688
  // src/index.ts
1501
- var program = new Command6();
1689
+ var program = new Command7();
1502
1690
  program.name("pnote").description("pnote - The PromptNote CLI").version("0.1.0", "-V, --version", "Show version number").option("--json", "Output as JSON (for scripting)").option("--no-color", "Disable colored output").option("--plain", "Force plain text output (no formatting)").option("-p, --pin <pin>", "PIN for accessing protected notes").option("--pin-stdin", "Read PIN from stdin (first line only)").configureHelp({
1503
1691
  sortSubcommands: true,
1504
1692
  sortOptions: true
@@ -1528,6 +1716,7 @@ program.addCommand(notesCommand);
1528
1716
  program.addCommand(snippetCommand);
1529
1717
  program.addCommand(tagsCommand);
1530
1718
  program.addCommand(searchCommand);
1719
+ program.addCommand(shareCommand);
1531
1720
  process.on("SIGINT", () => {
1532
1721
  console.error("\nInterrupted");
1533
1722
  process.exit(130);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/errors.ts","../src/commands/auth/index.ts","../src/commands/auth/login.ts","../src/lib/config.ts","../src/commands/auth/token.ts","../src/lib/api.ts","../src/commands/auth/logout.ts","../src/commands/auth/whoami.ts","../src/commands/notes/index.ts","../src/lib/output.ts","../src/commands/notes/list.ts","../src/commands/notes/get.ts","../src/commands/notes/create.ts","../src/commands/notes/archive.ts","../src/commands/notes/pin.ts","../src/commands/notes/delete.ts","../src/lib/pin.ts","../src/commands/snippet/index.ts","../src/commands/snippet/show.ts","../src/commands/snippet/copy.ts","../src/lib/clipboard.ts","../src/commands/snippet/add.ts","../src/commands/snippet/favorite.ts","../src/commands/tags/index.ts","../src/commands/tags/list.ts","../src/commands/tags/rename.ts","../src/commands/tags/merge.ts","../src/commands/search.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { handleError } from './lib/errors.js';\nimport { authCommand } from './commands/auth/index.js';\nimport { notesCommand } from './commands/notes/index.js';\nimport { snippetCommand } from './commands/snippet/index.js';\nimport { tagsCommand } from './commands/tags/index.js';\nimport { searchCommand } from './commands/search.js';\n\nconst program = new Command();\n\nprogram\n .name('pnote')\n .description('pnote - The PromptNote CLI')\n .version('0.1.0', '-V, --version', 'Show version number')\n .option('--json', 'Output as JSON (for scripting)')\n .option('--no-color', 'Disable colored output')\n .option('--plain', 'Force plain text output (no formatting)')\n .option('-p, --pin <pin>', 'PIN for accessing protected notes')\n .option('--pin-stdin', 'Read PIN from stdin (first line only)')\n .configureHelp({\n sortSubcommands: true,\n sortOptions: true,\n })\n .addHelpText(\n 'after',\n `\nPIN Protection:\n Protected notes require a PIN to access their content.\n You can provide the PIN in several ways:\n -p, --pin <pin> Pass PIN directly (visible in history)\n --pin-stdin Read PIN from stdin\n PNOTE_PIN Set as environment variable (recommended)\n\nExamples:\n $ pnote notes List all notes\n $ pnote notes --tag \"AI/art\" Filter notes by tag\n $ pnote notes get abc123 -p 1234 Get protected note with PIN\n $ export PNOTE_PIN=1234 && pnote notes\n $ pnote snippet copy abc123 Copy snippet to clipboard\n $ pnote search \"portrait\" Search notes and snippets\n\nDocumentation: https://promptnoteapp.com/docs\n`\n );\n\n// Add commands\nprogram.addCommand(authCommand);\nprogram.addCommand(notesCommand);\nprogram.addCommand(snippetCommand);\nprogram.addCommand(tagsCommand);\nprogram.addCommand(searchCommand);\n\n// Handle signals\nprocess.on('SIGINT', () => {\n console.error('\\nInterrupted');\n process.exit(130);\n});\n\nprocess.on('SIGTERM', () => {\n process.exit(0);\n});\n\n// Suppress broken pipe errors (when piping to head, etc.)\nprocess.stdout.on('error', (err) => {\n if (err.code === 'EPIPE') {\n process.exit(0);\n }\n throw err;\n});\n\n// Parse and run\nprogram.parseAsync(process.argv).catch((error) => {\n const noColor = program.opts().noColor ?? process.env.NO_COLOR !== undefined;\n handleError(error, noColor);\n});\n","import pc from 'picocolors';\n\n// Exit codes following Unix conventions\nexport const ExitCode = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n AUTH_ERROR: 2,\n NOT_FOUND: 3,\n NETWORK_ERROR: 4,\n} as const;\n\nexport type ExitCodeType = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport class CLIError extends Error {\n constructor(\n message: string,\n public exitCode: ExitCodeType = ExitCode.GENERAL_ERROR,\n public hint?: string\n ) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\nexport class AuthError extends CLIError {\n constructor(message: string, hint?: string) {\n super(message, ExitCode.AUTH_ERROR, hint);\n this.name = 'AuthError';\n }\n}\n\nexport class NotFoundError extends CLIError {\n constructor(resource: string, id: string) {\n super(`${resource} not found (id: ${id})`, ExitCode.NOT_FOUND);\n this.name = 'NotFoundError';\n }\n}\n\nexport class NetworkError extends CLIError {\n constructor(message: string = 'Network error. Check your connection.') {\n super(message, ExitCode.NETWORK_ERROR);\n this.name = 'NetworkError';\n }\n}\n\n// Error formatting for stderr\n\nexport function formatError(error: unknown, noColor: boolean = false): string {\n const red = noColor ? (s: string) => s : pc.red;\n const dim = noColor ? (s: string) => s : pc.dim;\n\n if (error instanceof CLIError) {\n let message = `${red('Error:')} ${error.message}`;\n if (error.hint) {\n message += `\\n${dim('Hint:')} ${error.hint}`;\n }\n return message;\n }\n\n if (error instanceof Error) {\n return `${red('Error:')} ${error.message}`;\n }\n\n return `${red('Error:')} ${String(error)}`;\n}\n\n// Handle errors and exit\n\nexport function handleError(error: unknown, noColor: boolean = false): never {\n console.error(formatError(error, noColor));\n\n if (error instanceof CLIError) {\n process.exit(error.exitCode);\n }\n\n process.exit(ExitCode.GENERAL_ERROR);\n}\n\n// Parse API errors\n\nexport function parseApiError(statusCode: number, body: string): CLIError {\n try {\n const parsed = JSON.parse(body);\n const message = parsed.error?.message || parsed.message || body;\n\n switch (statusCode) {\n case 401:\n return new AuthError(\n message.includes('Unauthorized') ? 'Not logged in or invalid token' : message,\n \"Run 'pnote auth login' to authenticate\"\n );\n case 403:\n return new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n case 404:\n return new CLIError('Resource not found', ExitCode.NOT_FOUND);\n default:\n return new CLIError(message);\n }\n } catch {\n return new CLIError(`HTTP ${statusCode}: ${body}`);\n }\n}\n","import { Command } from 'commander';\nimport { loginAction } from './login.js';\nimport { tokenAction } from './token.js';\nimport { logoutAction } from './logout.js';\nimport { whoamiAction } from './whoami.js';\n\nexport const authCommand = new Command('auth')\n .description('Manage authentication')\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote auth login Open browser to login\n $ pnote auth token pn_xxx Set token directly\n $ pnote auth whoami Show current user\n $ pnote auth logout Remove credentials\n`\n );\n\nauthCommand\n .command('login')\n .description('Login to PromptNote (opens browser)')\n .action(loginAction);\n\nauthCommand\n .command('token')\n .description('Set API token directly')\n .argument('<token>', 'Personal Access Token (pn_xxx)')\n .action(tokenAction);\n\nauthCommand\n .command('logout')\n .description('Remove stored credentials')\n .action(logoutAction);\n\nauthCommand\n .command('whoami')\n .description('Show current authenticated user')\n .action(whoamiAction);\n","import pc from 'picocolors';\nimport { isLoggedIn, getCredentialsPath } from '../../lib/config.js';\n\nexport async function loginAction(): Promise<void> {\n if (isLoggedIn()) {\n console.log(pc.yellow('Already logged in.'));\n console.log(pc.dim(`Credentials stored at: ${getCredentialsPath()}`));\n console.log('');\n console.log(`Run ${pc.cyan(\"'pnote auth logout'\")} to logout first.`);\n return;\n }\n\n console.log(pc.bold('Login to PromptNote'));\n console.log('');\n console.log('To authenticate, you need a Personal Access Token (PAT).');\n console.log('');\n console.log(pc.dim('Steps:'));\n console.log(' 1. Open ' + pc.cyan('https://app.promptnoteapp.com'));\n console.log(' 2. Go to Settings > API Tokens');\n console.log(' 3. Generate a new token');\n console.log(' 4. Run: ' + pc.cyan(\"pnote auth token <your-token>\"));\n console.log('');\n console.log(pc.dim('Or set the PROMTIE_TOKEN environment variable.'));\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { Credentials, Config } from '../types/index.js';\n\n// XDG Base Directory paths\nfunction getConfigDir(): string {\n const xdgConfig = process.env.XDG_CONFIG_HOME;\n if (xdgConfig) {\n return join(xdgConfig, 'pnote');\n }\n\n // macOS: also check ~/Library/Application Support\n const platform = process.platform;\n if (platform === 'darwin') {\n const macPath = join(homedir(), 'Library', 'Application Support', 'pnote');\n if (existsSync(macPath)) {\n return macPath;\n }\n }\n\n // Default to ~/.config/pnote\n return join(homedir(), '.config', 'pnote');\n}\n\nfunction ensureConfigDir(): string {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n return dir;\n}\n\n// Credentials management\n\nconst CREDENTIALS_FILE = 'credentials.json';\n\nexport function getCredentialsPath(): string {\n return join(getConfigDir(), CREDENTIALS_FILE);\n}\n\nexport function loadCredentials(): Credentials | null {\n // Priority 1: Environment variable\n const envToken = process.env.PNOTE_TOKEN;\n if (envToken) {\n return {\n token: envToken,\n created_at: new Date().toISOString(),\n };\n }\n\n // Priority 2: Credentials file\n const path = getCredentialsPath();\n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as Credentials;\n } catch {\n return null;\n }\n}\n\nexport function saveCredentials(credentials: Credentials): void {\n const dir = ensureConfigDir();\n const path = join(dir, CREDENTIALS_FILE);\n\n writeFileSync(path, JSON.stringify(credentials, null, 2), 'utf-8');\n\n // Set file permissions to 600 (owner read/write only)\n chmodSync(path, 0o600);\n}\n\nexport function deleteCredentials(): boolean {\n const path = getCredentialsPath();\n if (existsSync(path)) {\n unlinkSync(path);\n return true;\n }\n return false;\n}\n\n// Token utilities\n\nexport function getToken(): string | null {\n const creds = loadCredentials();\n return creds?.token ?? null;\n}\n\nexport function isLoggedIn(): boolean {\n return getToken() !== null;\n}\n\nexport function validateTokenFormat(token: string): boolean {\n // PAT format: pn_ + 32 characters\n return /^pn_[A-Za-z0-9_-]{20,50}$/.test(token);\n}\n\n// Config management (optional, for future use)\n\nconst CONFIG_FILE = 'config.json';\n\nexport function loadConfig(): Config {\n const path = join(getConfigDir(), CONFIG_FILE);\n if (!existsSync(path)) {\n return {};\n }\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as Config;\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(config: Config): void {\n const dir = ensureConfigDir();\n const path = join(dir, CONFIG_FILE);\n writeFileSync(path, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n// API Endpoint\n\nconst DEFAULT_API_ENDPOINT = 'https://tafnybfhwybgijozwfyq.supabase.co/functions/v1/promptnote-mcp/mcp';\n\nexport function getApiEndpoint(): string {\n const config = loadConfig();\n return config.api_endpoint ?? process.env.PNOTE_API_ENDPOINT ?? DEFAULT_API_ENDPOINT;\n}\n\n// PIN utilities\n\n/**\n * Get PIN from environment variable\n * Note: This is for display/status purposes only.\n * The MCP server reads PROMPTNOTE_PIN from its own environment configuration,\n * not from CLI requests. To access protected notes via MCP, users must configure\n * PROMPTNOTE_PIN in their MCP server config (e.g., claude_desktop_config.json).\n *\n * For CLI-specific operations, we use PNOTE_PIN to maintain consistency.\n */\nexport function getEnvPin(): string | null {\n return process.env.PNOTE_PIN ?? process.env.PROMPTNOTE_PIN ?? null;\n}\n","import pc from 'picocolors';\nimport { validateTokenFormat, saveCredentials, getCredentialsPath } from '../../lib/config.js';\nimport { verifyToken } from '../../lib/api.js';\nimport { CLIError, handleError } from '../../lib/errors.js';\n\nexport async function tokenAction(token: string): Promise<void> {\n // Validate token format\n if (!validateTokenFormat(token)) {\n throw new CLIError(\n 'Invalid token format',\n 1,\n \"Token should start with 'pn_' followed by 20-50 characters\"\n );\n }\n\n console.log(pc.dim('Verifying token...'));\n\n try {\n const result = await verifyToken(token);\n\n if (!result.valid) {\n throw new CLIError(\n 'Invalid token',\n 2,\n 'The token was rejected by the server. Please generate a new one.'\n );\n }\n\n // Save credentials\n saveCredentials({\n token,\n email: result.email,\n created_at: new Date().toISOString(),\n });\n\n console.log(pc.green('✓') + ' Token saved successfully!');\n console.log(pc.dim(`Credentials stored at: ${getCredentialsPath()}`));\n console.log('');\n console.log(`You can now use ${pc.cyan('pnote')} commands.`);\n } catch (error) {\n handleError(error);\n }\n}\n","import { getToken, getApiEndpoint } from './config.js';\nimport { AuthError, NetworkError, CLIError, ExitCode } from './errors.js';\n\n// REST API base URL (replace /mcp with /v1)\nfunction getRestApiBase(): string {\n const mcpEndpoint = getApiEndpoint();\n return mcpEndpoint.replace(/\\/mcp$/, '/v1');\n}\n\nexport interface RequestOptions {\n pin?: string;\n timeout?: number;\n}\n\n// Generic REST API call\nasync function callRestApi<T>(\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body?: Record<string, unknown>,\n options: RequestOptions = {}\n): Promise<T> {\n const token = getToken();\n if (!token) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' or 'pnote auth token <token>' to authenticate\"\n );\n }\n\n const baseUrl = getRestApiBase();\n const url = `${baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n };\n\n // Add PIN header if provided\n if (options.pin) {\n headers['X-PromptNote-PIN'] = options.pin;\n }\n\n let response: Response;\n try {\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(options.timeout ?? 30000),\n };\n\n if (body && (method === 'POST' || method === 'PATCH')) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n response = await fetch(url, fetchOptions);\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'TimeoutError' || error.name === 'AbortError') {\n throw new NetworkError('Request timed out. Please try again.');\n }\n if (error.message.includes('fetch')) {\n throw new NetworkError('Unable to connect to PromptNote API. Check your internet connection.');\n }\n }\n throw new NetworkError();\n }\n\n // Handle HTTP errors\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({})) as { message?: string };\n\n if (response.status === 401) {\n throw new AuthError(\n errorBody.message || 'Invalid or expired token',\n \"Run 'pnote auth login' to re-authenticate\"\n );\n }\n\n if (response.status === 403) {\n throw new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n }\n\n if (response.status === 404) {\n throw new CLIError(errorBody.message || 'Resource not found', ExitCode.NOT_FOUND);\n }\n\n if (response.status === 400) {\n throw new CLIError(errorBody.message || 'Invalid request', ExitCode.GENERAL_ERROR);\n }\n\n throw new CLIError(`API error (${response.status}): ${errorBody.message || 'Unknown error'}`);\n }\n\n return response.json() as Promise<T>;\n}\n\n// ============================================================\n// Notes API\n// ============================================================\n\nexport interface ListNotesParams {\n tag?: string;\n archived?: boolean;\n pinned?: boolean;\n deleted?: boolean;\n protected?: boolean;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport async function listNotes<T>(params: ListNotesParams = {}, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n if (params.tag) query.set('tag', params.tag);\n if (params.archived !== undefined) query.set('archived', String(params.archived));\n if (params.pinned !== undefined) query.set('pinned', String(params.pinned));\n if (params.deleted !== undefined) query.set('deleted', String(params.deleted));\n if (params.protected !== undefined) query.set('protected', String(params.protected));\n if (params.search) query.set('search', params.search);\n if (params.limit) query.set('limit', String(params.limit));\n if (params.offset) query.set('offset', String(params.offset));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function getNote<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', `/notes/${id}`, undefined, options);\n}\n\nexport async function createNote<T>(\n data: { title: string; tags?: string[]; content?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/notes', data, options);\n}\n\nexport async function updateNote<T>(\n id: string,\n data: { title?: string; tags?: string[]; archived?: boolean; pinned?: boolean },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('PATCH', `/notes/${id}`, data, options);\n}\n\nexport async function deleteNote<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('DELETE', `/notes/${id}`, undefined, options);\n}\n\n// ============================================================\n// Snippets API\n// ============================================================\n\nexport interface ListSnippetsParams {\n note_id: string;\n include_deleted?: boolean;\n limit?: number;\n}\n\nexport async function listSnippets<T>(params: ListSnippetsParams, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n query.set('note_id', params.note_id);\n if (params.include_deleted !== undefined) query.set('include_deleted', String(params.include_deleted));\n if (params.limit) query.set('limit', String(params.limit));\n\n return callRestApi<T>('GET', `/snippets?${query.toString()}`, undefined, options);\n}\n\nexport async function getSnippet<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', `/snippets/${id}`, undefined, options);\n}\n\nexport async function createSnippet<T>(\n data: { note_id: string; content: string; title?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/snippets', data, options);\n}\n\nexport async function updateSnippet<T>(\n id: string,\n data: { content?: string; title?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('PATCH', `/snippets/${id}`, data, options);\n}\n\nexport async function toggleFavorite<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('POST', `/snippets/${id}/favorite`, {}, options);\n}\n\n// ============================================================\n// Tags API\n// ============================================================\n\nexport interface ListTagsParams {\n include_archived?: boolean;\n}\n\nexport async function listTags<T>(params: ListTagsParams = {}, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n if (params.include_archived !== undefined) query.set('include_archived', String(params.include_archived));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/tags${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function renameTag<T>(\n data: { old_tag: string; new_tag: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/tags/rename', data, options);\n}\n\nexport async function mergeTags<T>(\n data: { source_tags: string[]; target_tag: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/tags/merge', data, options);\n}\n\n// ============================================================\n// Search API\n// ============================================================\n\nexport interface SearchParams {\n query: string;\n search_notes?: boolean;\n search_snippets?: boolean;\n limit?: number;\n}\n\nexport async function search<T>(params: SearchParams, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n query.set('q', params.query);\n if (params.search_notes !== undefined) query.set('search_notes', String(params.search_notes));\n if (params.search_snippets !== undefined) query.set('search_snippets', String(params.search_snippets));\n if (params.limit) query.set('limit', String(params.limit));\n\n return callRestApi<T>('GET', `/search?${query.toString()}`, undefined, options);\n}\n\n// ============================================================\n// PIN API\n// ============================================================\n\nexport async function checkPinStatus<T>(options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', '/pin/status', undefined, options);\n}\n\nexport async function listProtectedNotes<T>(\n params: { limit?: number; offset?: number } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.limit) query.set('limit', String(params.limit));\n if (params.offset) query.set('offset', String(params.offset));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/pin/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function verifyPin<T>(pin: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('POST', '/pin/verify', { pin }, options);\n}\n\n// ============================================================\n// Sharing API\n// ============================================================\n\nexport async function listSharedTags<T>(options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', '/sharing/tags', undefined, options);\n}\n\nexport async function getSharedTagNotes<T>(\n id: string,\n params: { limit?: number } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.limit) query.set('limit', String(params.limit));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/sharing/tags/${id}/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function listSharedNotes<T>(\n params: { include_revoked?: boolean } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.include_revoked !== undefined) query.set('include_revoked', String(params.include_revoked));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/sharing/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\n// ============================================================\n// Legacy MCP API (for backward compatibility and token verification)\n// ============================================================\n\nimport type { MCPRequest, MCPResponse } from '../types/index.js';\n\nlet requestId = 0;\n\nfunction getNextId(): number {\n return ++requestId;\n}\n\n/**\n * @deprecated Use REST API functions instead (listNotes, getNote, etc.)\n */\nexport async function callMCP<T>(\n toolName: string,\n args: Record<string, unknown> = {}\n): Promise<T> {\n const token = getToken();\n if (!token) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' or 'pnote auth token <token>' to authenticate\"\n );\n }\n\n const endpoint = getApiEndpoint();\n\n const request: MCPRequest = {\n jsonrpc: '2.0',\n id: getNextId(),\n method: 'tools/call',\n params: {\n name: toolName,\n arguments: args,\n },\n };\n\n let response: Response;\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(30000),\n });\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'TimeoutError' || error.name === 'AbortError') {\n throw new NetworkError('Request timed out. Please try again.');\n }\n if (error.message.includes('fetch')) {\n throw new NetworkError('Unable to connect to PromptNote API. Check your internet connection.');\n }\n }\n throw new NetworkError();\n }\n\n if (!response.ok) {\n const body = await response.text();\n\n if (response.status === 401) {\n throw new AuthError(\n 'Invalid or expired token',\n \"Run 'pnote auth login' to re-authenticate\"\n );\n }\n\n if (response.status === 403) {\n throw new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n }\n\n throw new CLIError(`API error (${response.status}): ${body}`);\n }\n\n const mcpResponse = (await response.json()) as MCPResponse;\n\n if (mcpResponse.error) {\n throw new CLIError(`MCP error: ${mcpResponse.error.message}`);\n }\n\n if (!mcpResponse.result) {\n throw new CLIError('Invalid response from API');\n }\n\n const content = mcpResponse.result.content;\n if (!content || content.length === 0) {\n throw new CLIError('Empty response from API');\n }\n\n if (mcpResponse.result.isError) {\n const errorText = content[0]?.text || 'Unknown error';\n\n if (errorText.includes('not found') || errorText.includes('PGRST116')) {\n throw new CLIError('Resource not found', ExitCode.NOT_FOUND);\n }\n if (errorText.includes('Unauthorized')) {\n throw new AuthError(errorText);\n }\n\n throw new CLIError(errorText);\n }\n\n const textContent = content[0]?.text;\n if (!textContent) {\n throw new CLIError('No content in response');\n }\n\n try {\n return JSON.parse(textContent) as T;\n } catch {\n return textContent as T;\n }\n}\n\n// Verify token is valid by making a simple API call (using REST API)\nexport async function verifyToken(token: string): Promise<{ valid: boolean; email?: string }> {\n const baseUrl = getApiEndpoint().replace(/\\/mcp$/, '/v1');\n\n try {\n const response = await fetch(`${baseUrl}/notes?limit=1`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n signal: AbortSignal.timeout(10000),\n });\n\n if (response.status === 401) {\n return { valid: false };\n }\n\n if (!response.ok) {\n return { valid: false };\n }\n\n return { valid: true };\n } catch {\n throw new NetworkError('Unable to verify token. Check your internet connection.');\n }\n}\n","import pc from 'picocolors';\nimport { deleteCredentials, isLoggedIn } from '../../lib/config.js';\n\nexport async function logoutAction(): Promise<void> {\n if (!isLoggedIn()) {\n console.log(pc.dim('Not logged in.'));\n return;\n }\n\n const deleted = deleteCredentials();\n\n if (deleted) {\n console.log(pc.green('✓') + ' Logged out successfully.');\n } else {\n console.log(pc.dim('No credentials to remove.'));\n }\n\n // Remind about environment variable\n if (process.env.PROMTIE_TOKEN) {\n console.log('');\n console.log(\n pc.yellow('Note:') +\n ' PROMTIE_TOKEN environment variable is still set.'\n );\n console.log(pc.dim('Unset it with: unset PROMTIE_TOKEN'));\n }\n}\n","import pc from 'picocolors';\nimport { loadCredentials, isLoggedIn, getCredentialsPath } from '../../lib/config.js';\nimport { callMCP } from '../../lib/api.js';\nimport { handleError, AuthError } from '../../lib/errors.js';\nimport type { ListNotesResponse } from '../../types/index.js';\n\nexport async function whoamiAction(): Promise<void> {\n if (!isLoggedIn()) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' to authenticate\"\n );\n }\n\n const creds = loadCredentials();\n if (!creds) {\n throw new AuthError('No credentials found');\n }\n\n try {\n // Verify token is still valid by making a simple API call\n const result = await callMCP<ListNotesResponse>('promptnote_list_notes', {\n limit: 1,\n });\n\n console.log(pc.green('✓') + ' Authenticated');\n console.log('');\n\n if (creds.email) {\n console.log(pc.dim('Email: ') + creds.email);\n }\n\n console.log(pc.dim('Token: ') + creds.token.slice(0, 7) + '...' + creds.token.slice(-4));\n console.log(pc.dim('Stored: ') + getCredentialsPath());\n\n if (process.env.PROMTIE_TOKEN) {\n console.log(pc.dim('Source: ') + 'PROMTIE_TOKEN environment variable');\n } else {\n console.log(pc.dim('Source: ') + 'credentials file');\n }\n\n console.log('');\n console.log(pc.dim(`Total notes: ${result.count}`));\n } catch (error) {\n handleError(error);\n }\n}\n","import { Command } from 'commander';\nimport { listNotesAction } from './list.js';\nimport { getNoteAction } from './get.js';\nimport { createNoteAction } from './create.js';\nimport { archiveNoteAction } from './archive.js';\nimport { pinNoteAction } from './pin.js';\nimport { deleteNoteAction } from './delete.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n // Resolve PIN from various sources\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true, // Don't prompt interactively for list/search operations\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const notesCommand = new Command('notes')\n .description('List and manage notes')\n .option('--tag <tag>', 'Filter by tag (e.g., \"AI/art\")')\n .option('--archived', 'Show archived notes')\n .option('--pinned', 'Show only pinned notes')\n .option('--deleted', 'Show deleted notes')\n .option('--search <query>', 'Search notes by title')\n .option('--limit <n>', 'Limit number of results', '50')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listNotesAction(options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote notes List all active notes\n $ pnote notes --tag \"AI/art\" Filter by tag\n $ pnote notes --archived Show archived notes\n $ pnote notes --pinned Show only pinned notes\n $ pnote notes get abc123 Get note details\n $ pnote notes create \"My Note\" Create a new note\n`\n );\n\nnotesCommand\n .command('get')\n .description('Get a note with its latest snippet')\n .argument('<id>', 'Note ID')\n .action(async (id: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await getNoteAction(id, ctx);\n });\n\nnotesCommand\n .command('create')\n .description('Create a new note')\n .argument('<title>', 'Note title')\n .option('--tag <tags...>', 'Tags for the note')\n .option('--content <content>', 'Initial snippet content')\n .action(async (title: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await createNoteAction(title, options, ctx);\n });\n\nnotesCommand\n .command('archive')\n .description('Archive or unarchive a note')\n .argument('<id>', 'Note ID')\n .option('--undo', 'Unarchive the note')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await archiveNoteAction(id, options, ctx);\n });\n\nnotesCommand\n .command('pin')\n .description('Pin or unpin a note')\n .argument('<id>', 'Note ID')\n .action(async (id: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await pinNoteAction(id, ctx);\n });\n\nnotesCommand\n .command('delete')\n .description('Delete a note (soft delete)')\n .argument('<id>', 'Note ID')\n .option('--force', 'Skip confirmation')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await deleteNoteAction(id, options, ctx);\n });\n","import pc from 'picocolors';\nimport type { CLIContext, Note, Snippet, Tag, TagHierarchy } from '../types/index.js';\n\n// Check if output should use colors\nfunction shouldUseColor(ctx: CLIContext): boolean {\n if (ctx.noColor) return false;\n if (process.env.NO_COLOR) return false;\n if (process.env.TERM === 'dumb') return false;\n return process.stdout.isTTY ?? false;\n}\n\n// Check if output should be formatted for humans\nfunction isHumanOutput(ctx: CLIContext): boolean {\n if (ctx.json) return false;\n if (ctx.plain) return false;\n return process.stdout.isTTY ?? false;\n}\n\n// Color helpers\nfunction getColors(ctx: CLIContext) {\n const useColor = shouldUseColor(ctx);\n return {\n dim: useColor ? pc.dim : (s: string) => s,\n bold: useColor ? pc.bold : (s: string) => s,\n green: useColor ? pc.green : (s: string) => s,\n yellow: useColor ? pc.yellow : (s: string) => s,\n blue: useColor ? pc.blue : (s: string) => s,\n cyan: useColor ? pc.cyan : (s: string) => s,\n red: useColor ? pc.red : (s: string) => s,\n magenta: useColor ? pc.magenta : (s: string) => s,\n };\n}\n\n// Format relative time\nfunction formatRelativeTime(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffSecs = Math.floor(diffMs / 1000);\n const diffMins = Math.floor(diffSecs / 60);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffDays > 30) {\n return date.toLocaleDateString();\n }\n if (diffDays > 0) {\n return `${diffDays}d ago`;\n }\n if (diffHours > 0) {\n return `${diffHours}h ago`;\n }\n if (diffMins > 0) {\n return `${diffMins}m ago`;\n }\n return 'just now';\n}\n\n// Truncate string with ellipsis\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen - 1) + '…';\n}\n\n// Pad string to fixed width\nfunction pad(str: string, width: number): string {\n if (str.length >= width) return str.slice(0, width);\n return str + ' '.repeat(width - str.length);\n}\n\n// Output JSON to stdout\nexport function outputJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\n// Output notes list\nexport function outputNotes(notes: Note[], ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(notes);\n return;\n }\n\n if (notes.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No notes found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n // Table header\n console.log(\n c.dim(pad('ID', 12)) +\n ' ' +\n c.dim(pad('TITLE', 30)) +\n ' ' +\n c.dim(pad('TAGS', 20)) +\n ' ' +\n c.dim('UPDATED')\n );\n\n for (const note of notes) {\n const id = truncate(note.id.slice(0, 8), 12);\n const title = truncate(note.title || '(untitled)', 30);\n const tags = truncate(note.tags.join(', ') || '-', 20);\n const updated = formatRelativeTime(note.updated_at);\n\n let line = pad(id, 12) + ' ' + pad(title, 30) + ' ' + pad(tags, 20) + ' ' + updated;\n\n // Add indicators\n const indicators: string[] = [];\n if (note.pinned) indicators.push(c.yellow('*'));\n if (note.archived) indicators.push(c.dim('[A]'));\n if (note.is_protected) indicators.push(c.magenta('[P]'));\n\n if (indicators.length > 0) {\n line = indicators.join('') + ' ' + line;\n }\n\n console.log(line);\n }\n } else {\n // Plain output - one note per line, tab-separated\n for (const note of notes) {\n console.log(\n [note.id, note.title, note.tags.join(','), note.updated_at].join('\\t')\n );\n }\n }\n}\n\n// Output single note\nexport function outputNote(note: Note, snippet: Snippet | null, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ ...note, latest_snippet: snippet });\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n console.log(c.bold(note.title || '(untitled)'));\n console.log(c.dim('ID: ') + note.id);\n console.log(c.dim('Tags: ') + (note.tags.length > 0 ? note.tags.join(', ') : '-'));\n console.log(c.dim('Created: ') + new Date(note.created_at).toLocaleString());\n console.log(c.dim('Updated: ') + new Date(note.updated_at).toLocaleString());\n\n const status: string[] = [];\n if (note.pinned) status.push(c.yellow('pinned'));\n if (note.archived) status.push(c.dim('archived'));\n if (note.is_protected) status.push(c.magenta('protected'));\n if (status.length > 0) {\n console.log(c.dim('Status: ') + status.join(', '));\n }\n\n if (snippet) {\n console.log('');\n console.log(c.dim(`--- Snippet v${snippet.version} ---`));\n console.log(snippet.content);\n } else {\n console.log('');\n console.log(c.dim('(no content)'));\n }\n } else {\n // Plain output\n console.log(`Title: ${note.title}`);\n console.log(`ID: ${note.id}`);\n console.log(`Tags: ${note.tags.join(', ')}`);\n if (snippet) {\n console.log('');\n console.log(snippet.content);\n }\n }\n}\n\n// Output snippet content\nexport function outputSnippet(snippet: Snippet, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(snippet);\n return;\n }\n\n // For snippet, just output the content directly (useful for piping)\n console.log(snippet.content);\n}\n\n// Output snippets list\nexport function outputSnippets(snippets: Snippet[], ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(snippets);\n return;\n }\n\n if (snippets.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No snippets found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n for (const snippet of snippets) {\n const header = `v${snippet.version}` +\n (snippet.favorite ? c.yellow(' ★') : '') +\n c.dim(` (${formatRelativeTime(snippet.created_at)})`);\n\n console.log(c.bold(header));\n console.log(snippet.content);\n console.log('');\n }\n } else {\n for (const snippet of snippets) {\n console.log(`v${snippet.version}\\t${snippet.id}\\t${snippet.content.slice(0, 100)}`);\n }\n }\n}\n\n// Output tags tree\nexport function outputTags(tags: Tag[], hierarchy: TagHierarchy, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ tags, hierarchy });\n return;\n }\n\n if (tags.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No tags found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n // Build tree structure\n const roots: string[] = [];\n const childrenMap: Map<string, string[]> = new Map();\n\n for (const tag of tags) {\n const parts = tag.tag.split('/');\n if (parts.length === 1) {\n roots.push(tag.tag);\n } else {\n const parent = parts.slice(0, -1).join('/');\n const children = childrenMap.get(parent) || [];\n children.push(tag.tag);\n childrenMap.set(parent, children);\n }\n }\n\n // Sort roots\n roots.sort();\n\n const tagCountMap = new Map(tags.map((t) => [t.tag, t.count]));\n\n function printTree(tagPath: string, prefix: string, isLast: boolean): void {\n const count = tagCountMap.get(tagPath) || 0;\n const name = tagPath.split('/').pop() || tagPath;\n const connector = isLast ? '└── ' : '├── ';\n\n console.log(prefix + connector + c.cyan(name) + c.dim(` (${count})`));\n\n const children = childrenMap.get(tagPath) || [];\n children.sort();\n\n const newPrefix = prefix + (isLast ? ' ' : '│ ');\n children.forEach((child, i) => {\n printTree(child, newPrefix, i === children.length - 1);\n });\n }\n\n roots.forEach((root, i) => {\n const count = tagCountMap.get(root) || 0;\n console.log(c.cyan(root) + c.dim(` (${count})`));\n\n const children = childrenMap.get(root) || [];\n children.sort();\n children.forEach((child, j) => {\n printTree(child, '', j === children.length - 1);\n });\n });\n } else {\n // Plain output\n for (const tag of tags) {\n console.log(`${tag.tag}\\t${tag.count}`);\n }\n }\n}\n\n// Output search results\nexport function outputSearchResults(\n query: string,\n notes: Note[],\n snippets: Array<{\n id: string;\n note_id: string;\n note_title: string;\n version: number;\n content_preview: string;\n favorite: boolean;\n }>,\n ctx: CLIContext\n): void {\n if (ctx.json) {\n outputJson({ query, notes, snippets });\n return;\n }\n\n const c = getColors(ctx);\n\n if (notes.length === 0 && snippets.length === 0) {\n console.log(c.dim(`No results for \"${query}\"`));\n return;\n }\n\n if (notes.length > 0) {\n console.log(c.bold(`Notes (${notes.length})`));\n console.log('');\n for (const note of notes) {\n console.log(\n ' ' + c.cyan(note.id.slice(0, 8)) + ' ' + note.title + ' ' + c.dim(note.tags.join(', '))\n );\n }\n console.log('');\n }\n\n if (snippets.length > 0) {\n console.log(c.bold(`Snippets (${snippets.length})`));\n console.log('');\n for (const snippet of snippets) {\n console.log(\n ' ' +\n c.cyan(snippet.note_id.slice(0, 8)) +\n ' ' +\n snippet.note_title +\n c.dim(` v${snippet.version}`)\n );\n console.log(' ' + c.dim(truncate(snippet.content_preview, 60)));\n }\n }\n}\n\n// Output simple message\nexport function outputMessage(message: string, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ message });\n return;\n }\n\n const c = getColors(ctx);\n console.log(c.green('✓') + ' ' + message);\n}\n\n// Output to stderr (for status messages when piping)\nexport function logStatus(message: string): void {\n if (process.stderr.isTTY) {\n console.error(pc.dim(message));\n }\n}\n","import { listNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputNotes } from '../../lib/output.js';\nimport type { ListNotesResponse, CLIContext } from '../../types/index.js';\n\ninterface ListNotesOptions {\n tag?: string;\n archived?: boolean;\n pinned?: boolean;\n deleted?: boolean;\n search?: string;\n limit?: string;\n}\n\nexport async function listNotesAction(\n options: ListNotesOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listNotes<ListNotesResponse>(\n {\n tag: options.tag,\n archived: options.archived ?? false,\n pinned: options.pinned,\n deleted: options.deleted ?? false,\n search: options.search,\n limit: options.limit ? parseInt(options.limit, 10) : 50,\n },\n { pin: ctx.pin }\n );\n\n outputNotes(result.notes, ctx);\n\n // Show warning for protected notes if any\n if (result.warning && !ctx.json) {\n console.error('');\n console.error(result.warning);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { getNote } from '../../lib/api.js';\nimport { handleError, NotFoundError } from '../../lib/errors.js';\nimport { outputNote } from '../../lib/output.js';\nimport type { GetNoteResponse, CLIContext } from '../../types/index.js';\n\nexport async function getNoteAction(id: string, ctx: CLIContext): Promise<void> {\n try {\n const result = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n\n if (!result) {\n throw new NotFoundError('Note', id);\n }\n\n outputNote(result, result.latest_snippet, ctx);\n\n // Show protection status warning if applicable\n if (result.protection_status?.error && !ctx.json) {\n console.error('');\n console.error('Warning: ' + result.protection_status.error);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { createNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CreateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface CreateNoteOptions {\n tag?: string[];\n content?: string;\n}\n\nexport async function createNoteAction(\n title: string,\n options: CreateNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let content = options.content;\n\n // If stdin has content and no --content flag, read from stdin\n if (!content && !process.stdin.isTTY) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinContent = Buffer.concat(chunks).toString('utf-8').trim();\n if (stdinContent) {\n content = stdinContent;\n }\n }\n\n const result = await createNote<CreateNoteResponse>(\n {\n title,\n tags: options.tag && options.tag.length > 0 ? options.tag : undefined,\n content,\n },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Created note: ${result.note.title} (${result.note.id})`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { updateNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface ArchiveNoteOptions {\n undo?: boolean;\n}\n\nexport async function archiveNoteAction(\n id: string,\n options: ArchiveNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const archived = !options.undo;\n\n const result = await updateNote<UpdateNoteResponse>(\n id,\n { archived },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const action = archived ? 'Archived' : 'Unarchived';\n outputMessage(`${action} note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { getNote, updateNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { GetNoteResponse, UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\nexport async function pinNoteAction(id: string, ctx: CLIContext): Promise<void> {\n try {\n // First get current pin status\n const note = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n const newPinned = !note.pinned;\n\n const result = await updateNote<UpdateNoteResponse>(\n id,\n { pinned: newPinned },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const action = newPinned ? 'Pinned' : 'Unpinned';\n outputMessage(`${action} note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import pc from 'picocolors';\nimport { createInterface } from 'node:readline';\nimport { getNote, deleteNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { GetNoteResponse, DeleteNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface DeleteNoteOptions {\n force?: boolean;\n}\n\nasync function confirm(message: string): Promise<boolean> {\n if (!process.stdin.isTTY) {\n return false;\n }\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(message + ' [y/N] ', (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');\n });\n });\n}\n\nexport async function deleteNoteAction(\n id: string,\n options: DeleteNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Get note details first\n const note = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n\n // Confirm deletion unless --force\n if (!options.force && !ctx.json) {\n console.log(`About to delete: ${pc.bold(note.title)}`);\n const confirmed = await confirm('Are you sure?');\n\n if (!confirmed) {\n console.log(pc.dim('Cancelled.'));\n return;\n }\n }\n\n const result = await deleteNote<DeleteNoteResponse>(id, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Deleted note: ${note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { createInterface } from 'node:readline';\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport pc from 'picocolors';\n\n// PIN session cache settings\nconst PIN_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst PIN_MAX_ATTEMPTS = 3;\n\nfunction getPinCachePath(): string {\n const uid = process.getuid?.() ?? 'unknown';\n return join(tmpdir(), `pnote-pin-${uid}`);\n}\n\n// Session cache management\n\nexport function getCachedPin(): string | null {\n const cachePath = getPinCachePath();\n\n if (!existsSync(cachePath)) {\n return null;\n }\n\n try {\n const stat = statSync(cachePath);\n const age = Date.now() - stat.mtimeMs;\n\n if (age > PIN_CACHE_TTL_MS) {\n // Cache expired, remove it\n unlinkSync(cachePath);\n return null;\n }\n\n const content = readFileSync(cachePath, 'utf-8').trim();\n return content || null;\n } catch {\n return null;\n }\n}\n\nexport function setCachedPin(pin: string): void {\n const cachePath = getPinCachePath();\n\n try {\n writeFileSync(cachePath, pin, { mode: 0o600 });\n } catch {\n // Silently fail - cache is optional\n }\n}\n\nexport function clearCachedPin(): boolean {\n const cachePath = getPinCachePath();\n\n if (existsSync(cachePath)) {\n try {\n unlinkSync(cachePath);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\n// PIN input methods\n\n/**\n * Read PIN from stdin (for --pin-stdin option)\n * Only reads the first line\n */\nexport async function readPinFromStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n // Only read first line\n const content = Buffer.concat(chunks).toString('utf-8');\n if (content.includes('\\n')) {\n break;\n }\n }\n\n const content = Buffer.concat(chunks).toString('utf-8');\n const firstLine = content.split('\\n')[0]?.trim() || '';\n\n if (!firstLine) {\n throw new Error('No PIN provided via stdin');\n }\n\n return firstLine;\n}\n\n/**\n * Prompt user for PIN interactively\n * Hides input and supports retry\n */\nexport async function promptForPin(\n noteTitle?: string,\n hint?: string,\n maxAttempts: number = PIN_MAX_ATTEMPTS\n): Promise<string | null> {\n if (!process.stdin.isTTY) {\n return null;\n }\n\n // Show context\n if (noteTitle) {\n console.error(pc.yellow('🔒') + ` Note \"${noteTitle}\" is PIN-protected.`);\n } else {\n console.error(pc.yellow('🔒') + ' This action requires your PIN.');\n }\n\n if (hint) {\n console.error(pc.dim(`Hint: ${hint}`));\n }\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const pin = await readPinHidden(\n attempt > 1 ? `Enter PIN (${attempt}/${maxAttempts}): ` : 'Enter PIN: '\n );\n\n if (pin) {\n return pin;\n }\n\n if (attempt < maxAttempts) {\n console.error(pc.red('Invalid or empty PIN. Try again.'));\n }\n }\n\n console.error(pc.red('Too many attempts.'));\n return null;\n}\n\n/**\n * Read a line with hidden input (for PIN entry)\n */\nasync function readPinHidden(prompt: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n terminal: true,\n });\n\n // Disable echo\n if (process.stdin.isTTY) {\n process.stdin.setRawMode?.(true);\n }\n\n process.stderr.write(prompt);\n\n let pin = '';\n\n const onKeypress = (key: Buffer) => {\n const char = key.toString();\n\n if (char === '\\r' || char === '\\n') {\n // Enter pressed\n process.stderr.write('\\n');\n cleanup();\n resolve(pin);\n } else if (char === '\\u0003') {\n // Ctrl+C\n process.stderr.write('\\n');\n cleanup();\n process.exit(130);\n } else if (char === '\\u007F' || char === '\\b') {\n // Backspace\n if (pin.length > 0) {\n pin = pin.slice(0, -1);\n // Move cursor back and clear\n process.stderr.write('\\b \\b');\n }\n } else if (char.length === 1 && char >= ' ') {\n // Regular character\n pin += char;\n process.stderr.write('*');\n }\n };\n\n const cleanup = () => {\n process.stdin.removeListener('data', onKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode?.(false);\n }\n rl.close();\n };\n\n process.stdin.on('data', onKeypress);\n });\n}\n\n/**\n * Get PIN from all sources in priority order\n *\n * Priority:\n * 1. --pin argument (passed in ctx.pin)\n * 2. --pin-stdin (if pinFromStdin is true)\n * 3. PNOTE_PIN environment variable\n * 4. Session cache\n * 5. Interactive prompt (if TTY)\n * 6. null (not available)\n */\nexport async function resolvePin(options: {\n pinArg?: string;\n pinFromStdin?: boolean;\n noteTitle?: string;\n hint?: string;\n skipCache?: boolean;\n skipPrompt?: boolean;\n}): Promise<string | null> {\n const { pinArg, pinFromStdin, noteTitle, hint, skipCache, skipPrompt } = options;\n\n // 1. Command line argument (highest priority)\n if (pinArg) {\n return pinArg;\n }\n\n // 2. stdin\n if (pinFromStdin) {\n try {\n return await readPinFromStdin();\n } catch {\n return null;\n }\n }\n\n // 3. Environment variable\n const envPin = process.env.PNOTE_PIN;\n if (envPin) {\n return envPin;\n }\n\n // 4. Session cache\n if (!skipCache) {\n const cached = getCachedPin();\n if (cached) {\n return cached;\n }\n }\n\n // 5. Interactive prompt\n if (!skipPrompt && process.stdin.isTTY) {\n const pin = await promptForPin(noteTitle, hint);\n if (pin) {\n // Cache for future use\n setCachedPin(pin);\n return pin;\n }\n }\n\n // 6. Not available\n return null;\n}\n\n/**\n * Check if PIN is required but not available\n * Returns error message if PIN is needed but missing\n */\nexport function checkPinRequired(\n isProtected: boolean,\n pin: string | null | undefined\n): string | null {\n if (!isProtected) {\n return null;\n }\n\n if (pin) {\n return null;\n }\n\n if (!process.stdin.isTTY) {\n return 'PIN required but not provided. Use -p <pin> or set PNOTE_PIN environment variable.';\n }\n\n return null;\n}\n","import { Command } from 'commander';\nimport { showSnippetAction } from './show.js';\nimport { copySnippetAction } from './copy.js';\nimport { addSnippetAction } from './add.js';\nimport { favoriteSnippetAction } from './favorite.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const snippetCommand = new Command('snippet')\n .description('Read and manage snippets (note versions)')\n .argument('[note-id]', 'Note ID to show snippet for')\n .option('--all', 'Show all snippet versions')\n .action(async (noteId: string | undefined, options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n\n if (noteId) {\n await showSnippetAction(noteId, options, ctx);\n } else {\n cmd.help();\n }\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote snippet abc123 Show latest snippet\n $ pnote snippet abc123 --all Show all versions\n $ pnote snippet copy abc123 Copy to clipboard\n $ cat file.txt | pnote snippet add abc123\n`\n );\n\nsnippetCommand\n .command('copy')\n .description('Copy snippet content to clipboard')\n .argument('<note-id>', 'Note ID')\n .option('--version <n>', 'Specific version number')\n .action(async (noteId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await copySnippetAction(noteId, options, ctx);\n });\n\nsnippetCommand\n .command('add')\n .description('Add a new snippet version (from stdin)')\n .argument('<note-id>', 'Note ID')\n .option('--title <title>', 'Snippet title')\n .action(async (noteId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await addSnippetAction(noteId, options, ctx);\n });\n\nsnippetCommand\n .command('favorite')\n .description('Toggle favorite status on a snippet')\n .argument('<snippet-id>', 'Snippet ID')\n .action(async (snippetId: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await favoriteSnippetAction(snippetId, ctx);\n });\n","import { getNote, listSnippets } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputSnippet, outputSnippets } from '../../lib/output.js';\nimport type { GetNoteResponse, ListSnippetsResponse, CLIContext } from '../../types/index.js';\n\ninterface ShowSnippetOptions {\n all?: boolean;\n}\n\nexport async function showSnippetAction(\n noteId: string,\n options: ShowSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n if (options.all) {\n // Show all versions\n const result = await listSnippets<ListSnippetsResponse>(\n { note_id: noteId, limit: 100 },\n { pin: ctx.pin }\n );\n\n outputSnippets(result.snippets, ctx);\n } else {\n // Show latest snippet only\n const result = await getNote<GetNoteResponse>(noteId, { pin: ctx.pin });\n\n if (result.latest_snippet) {\n outputSnippet(result.latest_snippet, ctx);\n } else {\n if (!ctx.json) {\n console.error('No snippet content found.');\n }\n process.exit(3);\n }\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import pc from 'picocolors';\nimport { getNote, listSnippets } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { copyToClipboard } from '../../lib/clipboard.js';\nimport { logStatus } from '../../lib/output.js';\nimport type { GetNoteResponse, ListSnippetsResponse, Snippet, CLIContext } from '../../types/index.js';\n\ninterface CopySnippetOptions {\n version?: string;\n}\n\nexport async function copySnippetAction(\n noteId: string,\n options: CopySnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let snippet: Snippet | null = null;\n\n if (options.version) {\n // Get specific version\n const versionNum = parseInt(options.version, 10);\n if (isNaN(versionNum)) {\n throw new CLIError('Invalid version number');\n }\n\n const result = await listSnippets<ListSnippetsResponse>(\n { note_id: noteId, limit: 100 },\n { pin: ctx.pin }\n );\n\n snippet = result.snippets.find((s) => s.version === versionNum) || null;\n\n if (!snippet) {\n throw new CLIError(`Version ${versionNum} not found`);\n }\n } else {\n // Get latest\n const result = await getNote<GetNoteResponse>(noteId, { pin: ctx.pin });\n snippet = result.latest_snippet;\n }\n\n if (!snippet) {\n throw new CLIError('No snippet content found');\n }\n\n try {\n await copyToClipboard(snippet.content);\n logStatus('Copied to clipboard');\n\n // If JSON mode, output the snippet data\n if (ctx.json) {\n console.log(JSON.stringify({ copied: true, content: snippet.content }));\n }\n } catch (clipboardError) {\n // Fallback: print to stdout\n if (!ctx.json) {\n console.error(pc.yellow('Clipboard not available, printing to stdout:'));\n console.error('');\n }\n console.log(snippet.content);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { default as clipboardy } from 'clipboardy';\nimport { CLIError } from './errors.js';\n\nexport async function copyToClipboard(text: string): Promise<void> {\n try {\n await clipboardy.write(text);\n } catch (error) {\n // Fallback: output to stdout with a warning\n if (error instanceof Error && error.message.includes('xsel')) {\n throw new CLIError(\n 'Clipboard not available. Install xsel or xclip on Linux.',\n 1,\n 'Content will be printed to stdout instead.'\n );\n }\n throw new CLIError('Failed to copy to clipboard');\n }\n}\n\nexport async function readFromClipboard(): Promise<string> {\n try {\n return await clipboardy.read();\n } catch {\n throw new CLIError('Failed to read from clipboard');\n }\n}\n","import { createSnippet } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CreateSnippetResponse, CLIContext } from '../../types/index.js';\n\ninterface AddSnippetOptions {\n title?: string;\n}\n\nexport async function addSnippetAction(\n noteId: string,\n options: AddSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let content: string;\n\n // Read content from stdin\n if (process.stdin.isTTY) {\n throw new CLIError(\n 'No content provided',\n 1,\n \"Pipe content to this command: echo 'content' | pnote snippet add <note-id>\"\n );\n }\n\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n content = Buffer.concat(chunks).toString('utf-8');\n\n // Trim trailing newline but preserve internal formatting\n if (content.endsWith('\\n')) {\n content = content.slice(0, -1);\n }\n\n if (!content) {\n throw new CLIError('Empty content provided');\n }\n\n const result = await createSnippet<CreateSnippetResponse>(\n {\n note_id: noteId,\n content,\n title: options.title,\n },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Created snippet v${result.snippet.version}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { toggleFavorite } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { ToggleFavoriteResponse, CLIContext } from '../../types/index.js';\n\nexport async function favoriteSnippetAction(\n snippetId: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await toggleFavorite<ToggleFavoriteResponse>(snippetId, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const status = result.snippet.favorite ? 'favorited' : 'unfavorited';\n outputMessage(`Snippet ${status}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { Command } from 'commander';\nimport { listTagsAction } from './list.js';\nimport { renameTagAction } from './rename.js';\nimport { mergeTagsAction } from './merge.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const tagsCommand = new Command('tags')\n .description('List and manage tags')\n .option('--include-archived', 'Include tags from archived notes')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listTagsAction(options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote tags List all tags\n $ pnote tags rename \"old\" \"new\" Rename a tag\n $ pnote tags merge \"tag1\" \"tag2\" --into \"target\"\n`\n );\n\ntagsCommand\n .command('rename')\n .description('Rename a tag across all notes')\n .argument('<old-tag>', 'Current tag name')\n .argument('<new-tag>', 'New tag name')\n .action(async (oldTag: string, newTag: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await renameTagAction(oldTag, newTag, ctx);\n });\n\ntagsCommand\n .command('merge')\n .description('Merge multiple tags into one')\n .argument('<source-tags...>', 'Tags to merge (space-separated)')\n .requiredOption('--into <target>', 'Target tag to merge into')\n .action(async (sourceTags: string[], options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await mergeTagsAction(sourceTags, options.into, ctx);\n });\n","import { listTags } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputTags } from '../../lib/output.js';\nimport type { ListTagsResponse, CLIContext } from '../../types/index.js';\n\ninterface ListTagsOptions {\n includeArchived?: boolean;\n}\n\nexport async function listTagsAction(\n options: ListTagsOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listTags<ListTagsResponse>(\n { include_archived: options.includeArchived ?? false },\n { pin: ctx.pin }\n );\n\n outputTags(result.tags, result.hierarchy, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { renameTag } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { RenameTagResponse, CLIContext } from '../../types/index.js';\n\nexport async function renameTagAction(\n oldTag: string,\n newTag: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await renameTag<RenameTagResponse>(\n { old_tag: oldTag, new_tag: newTag },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(\n `Renamed \"${oldTag}\" to \"${newTag}\" (${result.notes_updated} notes updated)`,\n ctx\n );\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { mergeTags } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { MergeTagsResponse, CLIContext } from '../../types/index.js';\n\nexport async function mergeTagsAction(\n sourceTags: string[],\n targetTag: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Validate that source doesn't include target\n if (sourceTags.includes(targetTag)) {\n throw new CLIError('Source tags cannot include the target tag');\n }\n\n if (sourceTags.length === 0) {\n throw new CLIError('At least one source tag is required');\n }\n\n const result = await mergeTags<MergeTagsResponse>(\n { source_tags: sourceTags, target_tag: targetTag },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const sourceList = sourceTags.map((t) => `\"${t}\"`).join(', ');\n outputMessage(\n `Merged ${sourceList} into \"${targetTag}\" (${result.notes_updated} notes updated)`,\n ctx\n );\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { Command } from 'commander';\nimport { search } from '../lib/api.js';\nimport { handleError } from '../lib/errors.js';\nimport { outputSearchResults } from '../lib/output.js';\nimport type { SearchResponse, CLIContext } from '../types/index.js';\n\ninterface SearchOptions {\n notesOnly?: boolean;\n snippetsOnly?: boolean;\n limit?: string;\n}\n\nasync function searchAction(\n query: string,\n options: SearchOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let search_notes = true;\n let search_snippets = true;\n\n if (options.notesOnly) {\n search_notes = true;\n search_snippets = false;\n } else if (options.snippetsOnly) {\n search_notes = false;\n search_snippets = true;\n }\n\n const result = await search<SearchResponse>(\n {\n query,\n search_notes,\n search_snippets,\n limit: options.limit ? parseInt(options.limit, 10) : 20,\n },\n { pin: ctx.pin }\n );\n\n outputSearchResults(query, result.notes, result.snippets, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n\nexport const searchCommand = new Command('search')\n .description('Search notes and snippets')\n .argument('<query>', 'Search query')\n .option('--notes-only', 'Only search note titles and tags')\n .option('--snippets-only', 'Only search snippet content')\n .option('--limit <n>', 'Limit results', '20')\n .action(async (query: string, options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx: CLIContext = {\n json: globalOpts.json ?? false,\n noColor: globalOpts.noColor ?? false,\n plain: globalOpts.plain ?? false,\n pin: globalOpts.pin,\n };\n await searchAction(query, options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote search \"portrait\" Search all\n $ pnote search \"AI\" --notes-only Search note titles only\n $ pnote search \"code\" --limit 50 Limit results\n`\n );\n"],"mappings":"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","names":["Command","pc","pc","pc","pc","pc","pc","pc","pc","Command","pc","c","printTree","pc","pc","createInterface","existsSync","readFileSync","writeFileSync","unlinkSync","join","pc","content","pc","createInterface","Command","Command","pc","pc","buildContext","Command","Command","buildContext","Command","Command","Command","Command"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/errors.ts","../src/commands/auth/index.ts","../src/commands/auth/login.ts","../src/lib/config.ts","../src/commands/auth/token.ts","../src/lib/api.ts","../src/commands/auth/logout.ts","../src/commands/auth/whoami.ts","../src/commands/notes/index.ts","../src/lib/output.ts","../src/commands/notes/list.ts","../src/commands/notes/get.ts","../src/commands/notes/create.ts","../src/commands/notes/archive.ts","../src/commands/notes/pin.ts","../src/commands/notes/delete.ts","../src/commands/notes/update.ts","../src/lib/pin.ts","../src/commands/snippet/index.ts","../src/commands/snippet/show.ts","../src/commands/snippet/copy.ts","../src/lib/clipboard.ts","../src/commands/snippet/add.ts","../src/commands/snippet/update.ts","../src/commands/snippet/favorite.ts","../src/commands/tags/index.ts","../src/commands/tags/list.ts","../src/commands/tags/rename.ts","../src/commands/tags/merge.ts","../src/commands/search.ts","../src/commands/share/index.ts","../src/commands/share/tags.ts","../src/commands/share/notes.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { handleError } from './lib/errors.js';\nimport { authCommand } from './commands/auth/index.js';\nimport { notesCommand } from './commands/notes/index.js';\nimport { snippetCommand } from './commands/snippet/index.js';\nimport { tagsCommand } from './commands/tags/index.js';\nimport { searchCommand } from './commands/search.js';\nimport { shareCommand } from './commands/share/index.js';\n\nconst program = new Command();\n\nprogram\n .name('pnote')\n .description('pnote - The PromptNote CLI')\n .version('0.1.0', '-V, --version', 'Show version number')\n .option('--json', 'Output as JSON (for scripting)')\n .option('--no-color', 'Disable colored output')\n .option('--plain', 'Force plain text output (no formatting)')\n .option('-p, --pin <pin>', 'PIN for accessing protected notes')\n .option('--pin-stdin', 'Read PIN from stdin (first line only)')\n .configureHelp({\n sortSubcommands: true,\n sortOptions: true,\n })\n .addHelpText(\n 'after',\n `\nPIN Protection:\n Protected notes require a PIN to access their content.\n You can provide the PIN in several ways:\n -p, --pin <pin> Pass PIN directly (visible in history)\n --pin-stdin Read PIN from stdin\n PNOTE_PIN Set as environment variable (recommended)\n\nExamples:\n $ pnote notes List all notes\n $ pnote notes --tag \"AI/art\" Filter notes by tag\n $ pnote notes get abc123 -p 1234 Get protected note with PIN\n $ export PNOTE_PIN=1234 && pnote notes\n $ pnote snippet copy abc123 Copy snippet to clipboard\n $ pnote search \"portrait\" Search notes and snippets\n\nDocumentation: https://promptnoteapp.com/docs\n`\n );\n\n// Add commands\nprogram.addCommand(authCommand);\nprogram.addCommand(notesCommand);\nprogram.addCommand(snippetCommand);\nprogram.addCommand(tagsCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(shareCommand);\n\n// Handle signals\nprocess.on('SIGINT', () => {\n console.error('\\nInterrupted');\n process.exit(130);\n});\n\nprocess.on('SIGTERM', () => {\n process.exit(0);\n});\n\n// Suppress broken pipe errors (when piping to head, etc.)\nprocess.stdout.on('error', (err) => {\n if (err.code === 'EPIPE') {\n process.exit(0);\n }\n throw err;\n});\n\n// Parse and run\nprogram.parseAsync(process.argv).catch((error) => {\n const noColor = program.opts().noColor ?? process.env.NO_COLOR !== undefined;\n handleError(error, noColor);\n});\n","import pc from 'picocolors';\n\n// Exit codes following Unix conventions\nexport const ExitCode = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n AUTH_ERROR: 2,\n NOT_FOUND: 3,\n NETWORK_ERROR: 4,\n} as const;\n\nexport type ExitCodeType = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport class CLIError extends Error {\n constructor(\n message: string,\n public exitCode: ExitCodeType = ExitCode.GENERAL_ERROR,\n public hint?: string\n ) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\nexport class AuthError extends CLIError {\n constructor(message: string, hint?: string) {\n super(message, ExitCode.AUTH_ERROR, hint);\n this.name = 'AuthError';\n }\n}\n\nexport class NotFoundError extends CLIError {\n constructor(resource: string, id: string) {\n super(`${resource} not found (id: ${id})`, ExitCode.NOT_FOUND);\n this.name = 'NotFoundError';\n }\n}\n\nexport class NetworkError extends CLIError {\n constructor(message: string = 'Network error. Check your connection.') {\n super(message, ExitCode.NETWORK_ERROR);\n this.name = 'NetworkError';\n }\n}\n\n// Error formatting for stderr\n\nexport function formatError(error: unknown, noColor: boolean = false): string {\n const red = noColor ? (s: string) => s : pc.red;\n const dim = noColor ? (s: string) => s : pc.dim;\n\n if (error instanceof CLIError) {\n let message = `${red('Error:')} ${error.message}`;\n if (error.hint) {\n message += `\\n${dim('Hint:')} ${error.hint}`;\n }\n return message;\n }\n\n if (error instanceof Error) {\n return `${red('Error:')} ${error.message}`;\n }\n\n return `${red('Error:')} ${String(error)}`;\n}\n\n// Handle errors and exit\n\nexport function handleError(error: unknown, noColor: boolean = false): never {\n console.error(formatError(error, noColor));\n\n if (error instanceof CLIError) {\n process.exit(error.exitCode);\n }\n\n process.exit(ExitCode.GENERAL_ERROR);\n}\n\n// Parse API errors\n\nexport function parseApiError(statusCode: number, body: string): CLIError {\n try {\n const parsed = JSON.parse(body);\n const message = parsed.error?.message || parsed.message || body;\n\n switch (statusCode) {\n case 401:\n return new AuthError(\n message.includes('Unauthorized') ? 'Not logged in or invalid token' : message,\n \"Run 'pnote auth login' to authenticate\"\n );\n case 403:\n return new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n case 404:\n return new CLIError('Resource not found', ExitCode.NOT_FOUND);\n default:\n return new CLIError(message);\n }\n } catch {\n return new CLIError(`HTTP ${statusCode}: ${body}`);\n }\n}\n","import { Command } from 'commander';\nimport { loginAction } from './login.js';\nimport { tokenAction } from './token.js';\nimport { logoutAction } from './logout.js';\nimport { whoamiAction } from './whoami.js';\n\nexport const authCommand = new Command('auth')\n .description('Manage authentication')\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote auth login Open browser to login\n $ pnote auth token pn_xxx Set token directly\n $ pnote auth whoami Show current user\n $ pnote auth logout Remove credentials\n`\n );\n\nauthCommand\n .command('login')\n .description('Login to PromptNote (opens browser)')\n .action(loginAction);\n\nauthCommand\n .command('token')\n .description('Set API token directly')\n .argument('<token>', 'Personal Access Token (pn_xxx)')\n .action(tokenAction);\n\nauthCommand\n .command('logout')\n .description('Remove stored credentials')\n .action(logoutAction);\n\nauthCommand\n .command('whoami')\n .description('Show current authenticated user')\n .action(whoamiAction);\n","import pc from 'picocolors';\nimport { isLoggedIn, getCredentialsPath } from '../../lib/config.js';\n\nexport async function loginAction(): Promise<void> {\n if (isLoggedIn()) {\n console.log(pc.yellow('Already logged in.'));\n console.log(pc.dim(`Credentials stored at: ${getCredentialsPath()}`));\n console.log('');\n console.log(`Run ${pc.cyan(\"'pnote auth logout'\")} to logout first.`);\n return;\n }\n\n console.log(pc.bold('Login to PromptNote'));\n console.log('');\n console.log('To authenticate, you need a Personal Access Token (PAT).');\n console.log('');\n console.log(pc.dim('Steps:'));\n console.log(' 1. Open ' + pc.cyan('https://app.promptnoteapp.com'));\n console.log(' 2. Go to Settings > API Tokens');\n console.log(' 3. Generate a new token');\n console.log(' 4. Run: ' + pc.cyan(\"pnote auth token <your-token>\"));\n console.log('');\n console.log(pc.dim('Or set the PNOTE_TOKEN environment variable.'));\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { Credentials, Config } from '../types/index.js';\n\n// XDG Base Directory paths\nfunction getConfigDir(): string {\n const xdgConfig = process.env.XDG_CONFIG_HOME;\n if (xdgConfig) {\n return join(xdgConfig, 'pnote');\n }\n\n // macOS: also check ~/Library/Application Support\n const platform = process.platform;\n if (platform === 'darwin') {\n const macPath = join(homedir(), 'Library', 'Application Support', 'pnote');\n if (existsSync(macPath)) {\n return macPath;\n }\n }\n\n // Default to ~/.config/pnote\n return join(homedir(), '.config', 'pnote');\n}\n\nfunction ensureConfigDir(): string {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n return dir;\n}\n\n// Credentials management\n\nconst CREDENTIALS_FILE = 'credentials.json';\n\nexport function getCredentialsPath(): string {\n return join(getConfigDir(), CREDENTIALS_FILE);\n}\n\nexport function loadCredentials(): Credentials | null {\n // Priority 1: Environment variable\n const envToken = process.env.PNOTE_TOKEN;\n if (envToken) {\n return {\n token: envToken,\n created_at: new Date().toISOString(),\n };\n }\n\n // Priority 2: Credentials file\n const path = getCredentialsPath();\n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as Credentials;\n } catch {\n return null;\n }\n}\n\nexport function saveCredentials(credentials: Credentials): void {\n const dir = ensureConfigDir();\n const path = join(dir, CREDENTIALS_FILE);\n\n writeFileSync(path, JSON.stringify(credentials, null, 2), 'utf-8');\n\n // Set file permissions to 600 (owner read/write only)\n chmodSync(path, 0o600);\n}\n\nexport function deleteCredentials(): boolean {\n const path = getCredentialsPath();\n if (existsSync(path)) {\n unlinkSync(path);\n return true;\n }\n return false;\n}\n\n// Token utilities\n\nexport function getToken(): string | null {\n const creds = loadCredentials();\n return creds?.token ?? null;\n}\n\nexport function isLoggedIn(): boolean {\n return getToken() !== null;\n}\n\nexport function validateTokenFormat(token: string): boolean {\n // PAT format: pn_ + 32 characters\n return /^pn_[A-Za-z0-9_-]{20,50}$/.test(token);\n}\n\n// Config management (optional, for future use)\n\nconst CONFIG_FILE = 'config.json';\n\nexport function loadConfig(): Config {\n const path = join(getConfigDir(), CONFIG_FILE);\n if (!existsSync(path)) {\n return {};\n }\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as Config;\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(config: Config): void {\n const dir = ensureConfigDir();\n const path = join(dir, CONFIG_FILE);\n writeFileSync(path, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n// API Endpoint\n\nconst DEFAULT_API_ENDPOINT = 'https://tafnybfhwybgijozwfyq.supabase.co/functions/v1/promptnote-mcp/mcp';\n\nexport function getApiEndpoint(): string {\n const config = loadConfig();\n return config.api_endpoint ?? process.env.PNOTE_API_ENDPOINT ?? DEFAULT_API_ENDPOINT;\n}\n\n// PIN utilities\n\n/**\n * Get PIN from environment variable\n * Note: This is for display/status purposes only.\n * The MCP server reads PROMPTNOTE_PIN from its own environment configuration,\n * not from CLI requests. To access protected notes via MCP, users must configure\n * PROMPTNOTE_PIN in their MCP server config (e.g., claude_desktop_config.json).\n *\n * For CLI-specific operations, we use PNOTE_PIN to maintain consistency.\n */\nexport function getEnvPin(): string | null {\n return process.env.PNOTE_PIN ?? process.env.PROMPTNOTE_PIN ?? null;\n}\n","import pc from 'picocolors';\nimport { validateTokenFormat, saveCredentials, getCredentialsPath } from '../../lib/config.js';\nimport { verifyToken } from '../../lib/api.js';\nimport { CLIError, handleError } from '../../lib/errors.js';\n\nexport async function tokenAction(token: string): Promise<void> {\n // Validate token format\n if (!validateTokenFormat(token)) {\n throw new CLIError(\n 'Invalid token format',\n 1,\n \"Token should start with 'pn_' followed by 20-50 characters\"\n );\n }\n\n console.log(pc.dim('Verifying token...'));\n\n try {\n const result = await verifyToken(token);\n\n if (!result.valid) {\n throw new CLIError(\n 'Invalid token',\n 2,\n 'The token was rejected by the server. Please generate a new one.'\n );\n }\n\n // Save credentials\n saveCredentials({\n token,\n email: result.email,\n created_at: new Date().toISOString(),\n });\n\n console.log(pc.green('✓') + ' Token saved successfully!');\n console.log(pc.dim(`Credentials stored at: ${getCredentialsPath()}`));\n console.log('');\n console.log(`You can now use ${pc.cyan('pnote')} commands.`);\n } catch (error) {\n handleError(error);\n }\n}\n","import { getToken, getApiEndpoint } from './config.js';\nimport { AuthError, NetworkError, CLIError, ExitCode } from './errors.js';\n\n// REST API base URL (replace /mcp with /v1)\nfunction getRestApiBase(): string {\n const mcpEndpoint = getApiEndpoint();\n return mcpEndpoint.replace(/\\/mcp$/, '/v1');\n}\n\nexport interface RequestOptions {\n pin?: string;\n timeout?: number;\n}\n\n// Generic REST API call\nasync function callRestApi<T>(\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body?: Record<string, unknown>,\n options: RequestOptions = {}\n): Promise<T> {\n const token = getToken();\n if (!token) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' or 'pnote auth token <token>' to authenticate\"\n );\n }\n\n const baseUrl = getRestApiBase();\n const url = `${baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n };\n\n // Add PIN header if provided\n if (options.pin) {\n headers['X-PromptNote-PIN'] = options.pin;\n }\n\n let response: Response;\n try {\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(options.timeout ?? 30000),\n };\n\n if (body && (method === 'POST' || method === 'PATCH')) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n response = await fetch(url, fetchOptions);\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'TimeoutError' || error.name === 'AbortError') {\n throw new NetworkError('Request timed out. Please try again.');\n }\n if (error.message.includes('fetch')) {\n throw new NetworkError('Unable to connect to PromptNote API. Check your internet connection.');\n }\n }\n throw new NetworkError();\n }\n\n // Handle HTTP errors\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({})) as { message?: string };\n\n if (response.status === 401) {\n throw new AuthError(\n errorBody.message || 'Invalid or expired token',\n \"Run 'pnote auth login' to re-authenticate\"\n );\n }\n\n if (response.status === 403) {\n throw new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n }\n\n if (response.status === 404) {\n throw new CLIError(errorBody.message || 'Resource not found', ExitCode.NOT_FOUND);\n }\n\n if (response.status === 400) {\n throw new CLIError(errorBody.message || 'Invalid request', ExitCode.GENERAL_ERROR);\n }\n\n throw new CLIError(`API error (${response.status}): ${errorBody.message || 'Unknown error'}`);\n }\n\n return response.json() as Promise<T>;\n}\n\n// ============================================================\n// Notes API\n// ============================================================\n\nexport interface ListNotesParams {\n tag?: string;\n archived?: boolean;\n pinned?: boolean;\n deleted?: boolean;\n protected?: boolean;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport async function listNotes<T>(params: ListNotesParams = {}, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n if (params.tag) query.set('tag', params.tag);\n if (params.archived !== undefined) query.set('archived', String(params.archived));\n if (params.pinned !== undefined) query.set('pinned', String(params.pinned));\n if (params.deleted !== undefined) query.set('deleted', String(params.deleted));\n if (params.protected !== undefined) query.set('protected', String(params.protected));\n if (params.search) query.set('search', params.search);\n if (params.limit) query.set('limit', String(params.limit));\n if (params.offset) query.set('offset', String(params.offset));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function getNote<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', `/notes/${id}`, undefined, options);\n}\n\nexport async function createNote<T>(\n data: { title: string; tags?: string[]; content?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/notes', data, options);\n}\n\nexport async function updateNote<T>(\n id: string,\n data: { title?: string; tags?: string[]; archived?: boolean; pinned?: boolean },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('PATCH', `/notes/${id}`, data, options);\n}\n\nexport async function deleteNote<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('DELETE', `/notes/${id}`, undefined, options);\n}\n\n// ============================================================\n// Snippets API\n// ============================================================\n\nexport interface ListSnippetsParams {\n note_id: string;\n include_deleted?: boolean;\n limit?: number;\n}\n\nexport async function listSnippets<T>(params: ListSnippetsParams, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n query.set('note_id', params.note_id);\n if (params.include_deleted !== undefined) query.set('include_deleted', String(params.include_deleted));\n if (params.limit) query.set('limit', String(params.limit));\n\n return callRestApi<T>('GET', `/snippets?${query.toString()}`, undefined, options);\n}\n\nexport async function getSnippet<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', `/snippets/${id}`, undefined, options);\n}\n\nexport async function createSnippet<T>(\n data: { note_id: string; content: string; title?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/snippets', data, options);\n}\n\nexport async function updateSnippet<T>(\n id: string,\n data: { content?: string; title?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('PATCH', `/snippets/${id}`, data, options);\n}\n\nexport async function toggleFavorite<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('POST', `/snippets/${id}/favorite`, {}, options);\n}\n\n// ============================================================\n// Tags API\n// ============================================================\n\nexport interface ListTagsParams {\n include_archived?: boolean;\n}\n\nexport async function listTags<T>(params: ListTagsParams = {}, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n if (params.include_archived !== undefined) query.set('include_archived', String(params.include_archived));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/tags${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function renameTag<T>(\n data: { old_tag: string; new_tag: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/tags/rename', data, options);\n}\n\nexport async function mergeTags<T>(\n data: { source_tags: string[]; target_tag: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/tags/merge', data, options);\n}\n\n// ============================================================\n// Search API\n// ============================================================\n\nexport interface SearchParams {\n query: string;\n search_notes?: boolean;\n search_snippets?: boolean;\n limit?: number;\n}\n\nexport async function search<T>(params: SearchParams, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n query.set('q', params.query);\n if (params.search_notes !== undefined) query.set('search_notes', String(params.search_notes));\n if (params.search_snippets !== undefined) query.set('search_snippets', String(params.search_snippets));\n if (params.limit) query.set('limit', String(params.limit));\n\n return callRestApi<T>('GET', `/search?${query.toString()}`, undefined, options);\n}\n\n// ============================================================\n// PIN API\n// ============================================================\n\nexport async function checkPinStatus<T>(options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', '/pin/status', undefined, options);\n}\n\nexport async function listProtectedNotes<T>(\n params: { limit?: number; offset?: number } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.limit) query.set('limit', String(params.limit));\n if (params.offset) query.set('offset', String(params.offset));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/pin/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function verifyPin<T>(pin: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('POST', '/pin/verify', { pin }, options);\n}\n\n// ============================================================\n// Sharing API\n// ============================================================\n\nexport async function listSharedTags<T>(options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', '/share/tags', undefined, options);\n}\n\nexport async function getSharedTagNotes<T>(\n id: string,\n params: { limit?: number } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.limit) query.set('limit', String(params.limit));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/share/tags/${id}/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function listSharedNotes<T>(\n params: { include_revoked?: boolean } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.include_revoked !== undefined) query.set('include_revoked', String(params.include_revoked));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/share/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\n// ============================================================\n// Legacy MCP API (for backward compatibility and token verification)\n// ============================================================\n\nimport type { MCPRequest, MCPResponse } from '../types/index.js';\n\nlet requestId = 0;\n\nfunction getNextId(): number {\n return ++requestId;\n}\n\n/**\n * @deprecated Use REST API functions instead (listNotes, getNote, etc.)\n */\nexport async function callMCP<T>(\n toolName: string,\n args: Record<string, unknown> = {}\n): Promise<T> {\n const token = getToken();\n if (!token) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' or 'pnote auth token <token>' to authenticate\"\n );\n }\n\n const endpoint = getApiEndpoint();\n\n const request: MCPRequest = {\n jsonrpc: '2.0',\n id: getNextId(),\n method: 'tools/call',\n params: {\n name: toolName,\n arguments: args,\n },\n };\n\n let response: Response;\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(30000),\n });\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'TimeoutError' || error.name === 'AbortError') {\n throw new NetworkError('Request timed out. Please try again.');\n }\n if (error.message.includes('fetch')) {\n throw new NetworkError('Unable to connect to PromptNote API. Check your internet connection.');\n }\n }\n throw new NetworkError();\n }\n\n if (!response.ok) {\n const body = await response.text();\n\n if (response.status === 401) {\n throw new AuthError(\n 'Invalid or expired token',\n \"Run 'pnote auth login' to re-authenticate\"\n );\n }\n\n if (response.status === 403) {\n throw new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n }\n\n throw new CLIError(`API error (${response.status}): ${body}`);\n }\n\n const mcpResponse = (await response.json()) as MCPResponse;\n\n if (mcpResponse.error) {\n throw new CLIError(`MCP error: ${mcpResponse.error.message}`);\n }\n\n if (!mcpResponse.result) {\n throw new CLIError('Invalid response from API');\n }\n\n const content = mcpResponse.result.content;\n if (!content || content.length === 0) {\n throw new CLIError('Empty response from API');\n }\n\n if (mcpResponse.result.isError) {\n const errorText = content[0]?.text || 'Unknown error';\n\n if (errorText.includes('not found') || errorText.includes('PGRST116')) {\n throw new CLIError('Resource not found', ExitCode.NOT_FOUND);\n }\n if (errorText.includes('Unauthorized')) {\n throw new AuthError(errorText);\n }\n\n throw new CLIError(errorText);\n }\n\n const textContent = content[0]?.text;\n if (!textContent) {\n throw new CLIError('No content in response');\n }\n\n try {\n return JSON.parse(textContent) as T;\n } catch {\n return textContent as T;\n }\n}\n\n// Verify token is valid by making a simple API call (using REST API)\nexport async function verifyToken(token: string): Promise<{ valid: boolean; email?: string }> {\n const baseUrl = getApiEndpoint().replace(/\\/mcp$/, '/v1');\n\n try {\n const response = await fetch(`${baseUrl}/notes?limit=1`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n signal: AbortSignal.timeout(10000),\n });\n\n if (response.status === 401) {\n return { valid: false };\n }\n\n if (!response.ok) {\n return { valid: false };\n }\n\n return { valid: true };\n } catch {\n throw new NetworkError('Unable to verify token. Check your internet connection.');\n }\n}\n","import pc from 'picocolors';\nimport { deleteCredentials, isLoggedIn } from '../../lib/config.js';\n\nexport async function logoutAction(): Promise<void> {\n if (!isLoggedIn()) {\n console.log(pc.dim('Not logged in.'));\n return;\n }\n\n const deleted = deleteCredentials();\n\n if (deleted) {\n console.log(pc.green('✓') + ' Logged out successfully.');\n } else {\n console.log(pc.dim('No credentials to remove.'));\n }\n\n // Remind about environment variable\n if (process.env.PNOTE_TOKEN) {\n console.log('');\n console.log(\n pc.yellow('Note:') +\n ' PNOTE_TOKEN environment variable is still set.'\n );\n console.log(pc.dim('Unset it with: unset PNOTE_TOKEN'));\n }\n}\n","import pc from 'picocolors';\nimport { loadCredentials, isLoggedIn, getCredentialsPath } from '../../lib/config.js';\nimport { listNotes } from '../../lib/api.js';\nimport { handleError, AuthError } from '../../lib/errors.js';\nimport type { ListNotesResponse } from '../../types/index.js';\n\nexport async function whoamiAction(): Promise<void> {\n if (!isLoggedIn()) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' to authenticate\"\n );\n }\n\n const creds = loadCredentials();\n if (!creds) {\n throw new AuthError('No credentials found');\n }\n\n try {\n // Verify token is still valid by making a simple API call\n const result = await listNotes<ListNotesResponse>({ limit: 1 });\n\n console.log(pc.green('✓') + ' Authenticated');\n console.log('');\n\n if (creds.email) {\n console.log(pc.dim('Email: ') + creds.email);\n }\n\n console.log(pc.dim('Token: ') + creds.token.slice(0, 7) + '...' + creds.token.slice(-4));\n console.log(pc.dim('Stored: ') + getCredentialsPath());\n\n if (process.env.PNOTE_TOKEN) {\n console.log(pc.dim('Source: ') + 'PNOTE_TOKEN environment variable');\n } else {\n console.log(pc.dim('Source: ') + 'credentials file');\n }\n\n console.log('');\n console.log(pc.dim(`Total notes: ${result.count}`));\n } catch (error) {\n handleError(error);\n }\n}\n","import { Command } from 'commander';\nimport { listNotesAction } from './list.js';\nimport { getNoteAction } from './get.js';\nimport { createNoteAction } from './create.js';\nimport { archiveNoteAction } from './archive.js';\nimport { pinNoteAction } from './pin.js';\nimport { deleteNoteAction } from './delete.js';\nimport { updateNoteAction } from './update.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n // Resolve PIN from various sources\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true, // Don't prompt interactively for list/search operations\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const notesCommand = new Command('notes')\n .description('List and manage notes')\n .option('--tag <tag>', 'Filter by tag (e.g., \"AI/art\")')\n .option('--archived', 'Show archived notes')\n .option('--pinned', 'Show only pinned notes')\n .option('--deleted', 'Show deleted notes')\n .option('--search <query>', 'Search notes by title')\n .option('--limit <n>', 'Limit number of results', '50')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listNotesAction(options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote notes List all active notes\n $ pnote notes --tag \"AI/art\" Filter by tag\n $ pnote notes --archived Show archived notes\n $ pnote notes --pinned Show only pinned notes\n $ pnote notes get abc123 Get note details\n $ pnote notes create \"My Note\" Create a new note\n $ pnote notes update abc123 --title \"New Title\"\n`\n );\n\nnotesCommand\n .command('get')\n .description('Get a note with its latest snippet')\n .argument('<id>', 'Note ID')\n .action(async (id: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await getNoteAction(id, ctx);\n });\n\nnotesCommand\n .command('create')\n .description('Create a new note')\n .argument('<title>', 'Note title')\n .option('--tags <tags...>', 'Tags for the note')\n .option('--content <content>', 'Initial snippet content')\n .action(async (title: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await createNoteAction(title, options, ctx);\n });\n\nnotesCommand\n .command('archive')\n .description('Archive or unarchive a note')\n .argument('<id>', 'Note ID')\n .option('--undo', 'Unarchive the note')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await archiveNoteAction(id, options, ctx);\n });\n\nnotesCommand\n .command('pin')\n .description('Pin or unpin a note')\n .argument('<id>', 'Note ID')\n .action(async (id: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await pinNoteAction(id, ctx);\n });\n\nnotesCommand\n .command('update')\n .description('Update a note title or tags')\n .argument('<id>', 'Note ID')\n .option('--title <title>', 'New title')\n .option('--tags <tags...>', 'New tags (replaces existing)')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await updateNoteAction(id, options, ctx);\n });\n\nnotesCommand\n .command('delete')\n .description('Delete a note (soft delete)')\n .argument('<id>', 'Note ID')\n .option('--force', 'Skip confirmation')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await deleteNoteAction(id, options, ctx);\n });\n","import pc from 'picocolors';\nimport type {\n CLIContext, Note, Snippet, Tag, TagHierarchy,\n ListSharedTagsResponse, GetSharedTagNotesResponse, ListSharedNotesResponse,\n} from '../types/index.js';\n\n// Check if output should use colors\nfunction shouldUseColor(ctx: CLIContext): boolean {\n if (ctx.noColor) return false;\n if (process.env.NO_COLOR) return false;\n if (process.env.TERM === 'dumb') return false;\n return process.stdout.isTTY ?? false;\n}\n\n// Check if output should be formatted for humans\nfunction isHumanOutput(ctx: CLIContext): boolean {\n if (ctx.json) return false;\n if (ctx.plain) return false;\n return process.stdout.isTTY ?? false;\n}\n\n// Color helpers\nfunction getColors(ctx: CLIContext) {\n const useColor = shouldUseColor(ctx);\n return {\n dim: useColor ? pc.dim : (s: string) => s,\n bold: useColor ? pc.bold : (s: string) => s,\n green: useColor ? pc.green : (s: string) => s,\n yellow: useColor ? pc.yellow : (s: string) => s,\n blue: useColor ? pc.blue : (s: string) => s,\n cyan: useColor ? pc.cyan : (s: string) => s,\n red: useColor ? pc.red : (s: string) => s,\n magenta: useColor ? pc.magenta : (s: string) => s,\n };\n}\n\n// Format relative time\nfunction formatRelativeTime(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffSecs = Math.floor(diffMs / 1000);\n const diffMins = Math.floor(diffSecs / 60);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffDays > 30) {\n return date.toLocaleDateString();\n }\n if (diffDays > 0) {\n return `${diffDays}d ago`;\n }\n if (diffHours > 0) {\n return `${diffHours}h ago`;\n }\n if (diffMins > 0) {\n return `${diffMins}m ago`;\n }\n return 'just now';\n}\n\n// Truncate string with ellipsis\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen - 1) + '…';\n}\n\n// Pad string to fixed width\nfunction pad(str: string, width: number): string {\n if (str.length >= width) return str.slice(0, width);\n return str + ' '.repeat(width - str.length);\n}\n\n// Output JSON to stdout\nexport function outputJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\n// Output notes list\nexport function outputNotes(notes: Note[], ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(notes);\n return;\n }\n\n if (notes.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No notes found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n // Table header\n console.log(\n c.dim(pad('ID', 12)) +\n ' ' +\n c.dim(pad('TITLE', 30)) +\n ' ' +\n c.dim(pad('TAGS', 20)) +\n ' ' +\n c.dim('UPDATED')\n );\n\n for (const note of notes) {\n const id = truncate(note.id.slice(0, 8), 12);\n const title = truncate(note.title || '(untitled)', 30);\n const tags = truncate(note.tags.join(', ') || '-', 20);\n const updated = formatRelativeTime(note.updated_at);\n\n let line = pad(id, 12) + ' ' + pad(title, 30) + ' ' + pad(tags, 20) + ' ' + updated;\n\n // Add indicators\n const indicators: string[] = [];\n if (note.pinned) indicators.push(c.yellow('*'));\n if (note.archived) indicators.push(c.dim('[A]'));\n if (note.is_protected) indicators.push(c.magenta('[P]'));\n\n if (indicators.length > 0) {\n line = indicators.join('') + ' ' + line;\n }\n\n console.log(line);\n }\n } else {\n // Plain output - one note per line, tab-separated\n for (const note of notes) {\n console.log(\n [note.id, note.title, note.tags.join(','), note.updated_at].join('\\t')\n );\n }\n }\n}\n\n// Output single note\nexport function outputNote(note: Note, snippet: Snippet | null, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ ...note, latest_snippet: snippet });\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n console.log(c.bold(note.title || '(untitled)'));\n console.log(c.dim('ID: ') + note.id);\n console.log(c.dim('Tags: ') + (note.tags.length > 0 ? note.tags.join(', ') : '-'));\n console.log(c.dim('Created: ') + new Date(note.created_at).toLocaleString());\n console.log(c.dim('Updated: ') + new Date(note.updated_at).toLocaleString());\n\n const status: string[] = [];\n if (note.pinned) status.push(c.yellow('pinned'));\n if (note.archived) status.push(c.dim('archived'));\n if (note.is_protected) status.push(c.magenta('protected'));\n if (status.length > 0) {\n console.log(c.dim('Status: ') + status.join(', '));\n }\n\n if (snippet) {\n console.log('');\n console.log(c.dim(`--- Snippet v${snippet.version} ---`));\n console.log(snippet.content);\n } else {\n console.log('');\n console.log(c.dim('(no content)'));\n }\n } else {\n // Plain output\n console.log(`Title: ${note.title}`);\n console.log(`ID: ${note.id}`);\n console.log(`Tags: ${note.tags.join(', ')}`);\n if (snippet) {\n console.log('');\n console.log(snippet.content);\n }\n }\n}\n\n// Output snippet content\nexport function outputSnippet(snippet: Snippet, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(snippet);\n return;\n }\n\n // For snippet, just output the content directly (useful for piping)\n console.log(snippet.content);\n}\n\n// Output snippets list\nexport function outputSnippets(snippets: Snippet[], ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(snippets);\n return;\n }\n\n if (snippets.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No snippets found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n for (const snippet of snippets) {\n const header = `v${snippet.version}` +\n (snippet.favorite ? c.yellow(' ★') : '') +\n c.dim(` (${formatRelativeTime(snippet.created_at)})`);\n\n console.log(c.bold(header));\n console.log(snippet.content);\n console.log('');\n }\n } else {\n for (const snippet of snippets) {\n console.log(`v${snippet.version}\\t${snippet.id}\\t${snippet.content.slice(0, 100)}`);\n }\n }\n}\n\n// Output tags tree\nexport function outputTags(tags: Tag[], hierarchy: TagHierarchy, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ tags, hierarchy });\n return;\n }\n\n if (tags.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No tags found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n // Build tree structure\n const roots: string[] = [];\n const childrenMap: Map<string, string[]> = new Map();\n\n for (const tag of tags) {\n const parts = tag.tag.split('/');\n if (parts.length === 1) {\n roots.push(tag.tag);\n } else {\n const parent = parts.slice(0, -1).join('/');\n const children = childrenMap.get(parent) || [];\n children.push(tag.tag);\n childrenMap.set(parent, children);\n }\n }\n\n // Sort roots\n roots.sort();\n\n const tagCountMap = new Map(tags.map((t) => [t.tag, t.count]));\n\n function printTree(tagPath: string, prefix: string, isLast: boolean): void {\n const count = tagCountMap.get(tagPath) || 0;\n const name = tagPath.split('/').pop() || tagPath;\n const connector = isLast ? '└── ' : '├── ';\n\n console.log(prefix + connector + c.cyan(name) + c.dim(` (${count})`));\n\n const children = childrenMap.get(tagPath) || [];\n children.sort();\n\n const newPrefix = prefix + (isLast ? ' ' : '│ ');\n children.forEach((child, i) => {\n printTree(child, newPrefix, i === children.length - 1);\n });\n }\n\n roots.forEach((root, i) => {\n const count = tagCountMap.get(root) || 0;\n console.log(c.cyan(root) + c.dim(` (${count})`));\n\n const children = childrenMap.get(root) || [];\n children.sort();\n children.forEach((child, j) => {\n printTree(child, '', j === children.length - 1);\n });\n });\n } else {\n // Plain output\n for (const tag of tags) {\n console.log(`${tag.tag}\\t${tag.count}`);\n }\n }\n}\n\n// Output search results\nexport function outputSearchResults(\n query: string,\n notes: Note[],\n snippets: Array<{\n id: string;\n note_id: string;\n note_title: string;\n version: number;\n content_preview: string;\n favorite: boolean;\n }>,\n ctx: CLIContext\n): void {\n if (ctx.json) {\n outputJson({ query, notes, snippets });\n return;\n }\n\n const c = getColors(ctx);\n\n if (notes.length === 0 && snippets.length === 0) {\n console.log(c.dim(`No results for \"${query}\"`));\n return;\n }\n\n if (notes.length > 0) {\n console.log(c.bold(`Notes (${notes.length})`));\n console.log('');\n for (const note of notes) {\n console.log(\n ' ' + c.cyan(note.id.slice(0, 8)) + ' ' + note.title + ' ' + c.dim(note.tags.join(', '))\n );\n }\n console.log('');\n }\n\n if (snippets.length > 0) {\n console.log(c.bold(`Snippets (${snippets.length})`));\n console.log('');\n for (const snippet of snippets) {\n console.log(\n ' ' +\n c.cyan(snippet.note_id.slice(0, 8)) +\n ' ' +\n snippet.note_title +\n c.dim(` v${snippet.version}`)\n );\n console.log(' ' + c.dim(truncate(snippet.content_preview, 60)));\n }\n }\n}\n\n// Output shared tags list\nexport function outputSharedTags(data: ListSharedTagsResponse, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(data);\n return;\n }\n\n const c = getColors(ctx);\n const totalCount = data.owned.count + data.shared_with_me.count;\n\n if (totalCount === 0) {\n console.log(c.dim('No shared tags.'));\n return;\n }\n\n if (isHumanOutput(ctx)) {\n if (data.owned.count > 0) {\n console.log(c.bold(`Owned (${data.owned.count})`));\n console.log('');\n for (const tag of data.owned.tags) {\n console.log(\n ' ' + c.cyan(tag.id.slice(0, 8)) + ' ' +\n pad(tag.tag_path, 24) + ' ' +\n c.dim(formatRelativeTime(tag.created_at))\n );\n }\n console.log('');\n }\n\n if (data.shared_with_me.count > 0) {\n console.log(c.bold(`Shared with me (${data.shared_with_me.count})`));\n console.log('');\n for (const tag of data.shared_with_me.tags) {\n console.log(\n ' ' + c.cyan(tag.id.slice(0, 8)) + ' ' +\n pad(tag.tag_path, 24) + ' ' +\n c.dim('joined ' + formatRelativeTime(tag.joined_at))\n );\n }\n }\n } else {\n for (const tag of data.owned.tags) {\n console.log(['owned', tag.id, tag.tag_path, tag.created_at].join('\\t'));\n }\n for (const tag of data.shared_with_me.tags) {\n console.log(['shared', tag.id, tag.tag_path, tag.joined_at].join('\\t'));\n }\n }\n}\n\n// Output shared tag notes\nexport function outputSharedTagNotes(data: GetSharedTagNotesResponse, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(data);\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n const role = data.shared_tag.is_owner ? 'owner' : 'member';\n console.log(c.bold(data.shared_tag.tag_path) + c.dim(` (${role}, ${data.members_count} members)`));\n console.log('');\n\n if (data.notes.length === 0) {\n console.log(c.dim(' No notes in this shared tag.'));\n return;\n }\n\n console.log(\n ' ' + c.dim(pad('ID', 10)) +\n ' ' + c.dim(pad('TITLE', 24)) +\n ' ' + c.dim(pad('AUTHOR', 20)) +\n ' ' + c.dim('UPDATED')\n );\n\n for (const note of data.notes) {\n const author = note.is_own ? 'you' : (note.author.email || 'unknown');\n console.log(\n ' ' + pad(note.id.slice(0, 8), 10) +\n ' ' + pad(truncate(note.title, 24), 24) +\n ' ' + pad(truncate(author, 20), 20) +\n ' ' + formatRelativeTime(note.updated_at)\n );\n }\n } else {\n for (const note of data.notes) {\n const author = note.is_own ? 'you' : (note.author.email || 'unknown');\n console.log([note.id, note.title, author, note.updated_at].join('\\t'));\n }\n }\n}\n\n// Output shared notes (public links)\nexport function outputSharedNotes(data: ListSharedNotesResponse, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(data);\n return;\n }\n\n const c = getColors(ctx);\n\n if (data.count === 0) {\n console.log(c.dim('No shared notes.'));\n return;\n }\n\n if (isHumanOutput(ctx)) {\n console.log(c.bold(`Shared Notes (${data.count})`));\n console.log('');\n\n for (const share of data.shares) {\n const revoked = share.is_revoked ? c.red(' [R]') : '';\n console.log(\n ' ' + truncate(share.note_title, 20) +\n ' ' + c.cyan(share.share_url) +\n ' ' + c.dim(`${share.view_count} views`) +\n ' ' + c.dim(formatRelativeTime(share.created_at)) +\n revoked\n );\n }\n } else {\n for (const share of data.shares) {\n console.log(\n [share.note_title, share.share_url, share.view_count, share.is_revoked, share.created_at].join('\\t')\n );\n }\n }\n}\n\n// Output simple message\nexport function outputMessage(message: string, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ message });\n return;\n }\n\n const c = getColors(ctx);\n console.log(c.green('✓') + ' ' + message);\n}\n\n// Output to stderr (for status messages when piping)\nexport function logStatus(message: string): void {\n if (process.stderr.isTTY) {\n console.error(pc.dim(message));\n }\n}\n","import { listNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputNotes } from '../../lib/output.js';\nimport type { ListNotesResponse, CLIContext } from '../../types/index.js';\n\ninterface ListNotesOptions {\n tag?: string;\n archived?: boolean;\n pinned?: boolean;\n deleted?: boolean;\n search?: string;\n limit?: string;\n}\n\nexport async function listNotesAction(\n options: ListNotesOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listNotes<ListNotesResponse>(\n {\n tag: options.tag,\n archived: options.archived ?? false,\n pinned: options.pinned,\n deleted: options.deleted ?? false,\n search: options.search,\n limit: options.limit ? parseInt(options.limit, 10) : 50,\n },\n { pin: ctx.pin }\n );\n\n outputNotes(result.notes, ctx);\n\n // Show warning for protected notes if any\n if (result.warning && !ctx.json) {\n console.error('');\n console.error(result.warning);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { getNote } from '../../lib/api.js';\nimport { handleError, NotFoundError } from '../../lib/errors.js';\nimport { outputNote } from '../../lib/output.js';\nimport type { GetNoteResponse, CLIContext } from '../../types/index.js';\n\nexport async function getNoteAction(id: string, ctx: CLIContext): Promise<void> {\n try {\n const result = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n\n if (!result) {\n throw new NotFoundError('Note', id);\n }\n\n outputNote(result, result.latest_snippet, ctx);\n\n // Show protection status warning if applicable\n if (result.protection_status?.error && !ctx.json) {\n console.error('');\n console.error('Warning: ' + result.protection_status.error);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { createNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CreateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface CreateNoteOptions {\n tags?: string[];\n content?: string;\n}\n\nexport async function createNoteAction(\n title: string,\n options: CreateNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let content = options.content;\n\n // If stdin has content and no --content flag, read from stdin\n if (!content && !process.stdin.isTTY) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinContent = Buffer.concat(chunks).toString('utf-8').trim();\n if (stdinContent) {\n content = stdinContent;\n }\n }\n\n const result = await createNote<CreateNoteResponse>(\n {\n title,\n tags: options.tags && options.tags.length > 0 ? options.tags : undefined,\n content,\n },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Created note: ${result.note.title} (${result.note.id})`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { updateNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface ArchiveNoteOptions {\n undo?: boolean;\n}\n\nexport async function archiveNoteAction(\n id: string,\n options: ArchiveNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const archived = !options.undo;\n\n const result = await updateNote<UpdateNoteResponse>(\n id,\n { archived },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const action = archived ? 'Archived' : 'Unarchived';\n outputMessage(`${action} note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { getNote, updateNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { GetNoteResponse, UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\nexport async function pinNoteAction(id: string, ctx: CLIContext): Promise<void> {\n try {\n // First get current pin status\n const note = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n const newPinned = !note.pinned;\n\n const result = await updateNote<UpdateNoteResponse>(\n id,\n { pinned: newPinned },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const action = newPinned ? 'Pinned' : 'Unpinned';\n outputMessage(`${action} note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import pc from 'picocolors';\nimport { createInterface } from 'node:readline';\nimport { getNote, deleteNote } from '../../lib/api.js';\nimport { handleError, CLIError, ExitCode } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { GetNoteResponse, DeleteNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface DeleteNoteOptions {\n force?: boolean;\n}\n\nasync function confirm(message: string): Promise<boolean> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(message + ' [y/N] ', (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');\n });\n });\n}\n\nexport async function deleteNoteAction(\n id: string,\n options: DeleteNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Get note details first\n const note = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n\n // Confirm deletion unless --force or --json\n if (!options.force && !ctx.json) {\n if (!process.stdin.isTTY) {\n throw new CLIError(\n 'Cannot confirm deletion in non-interactive mode',\n ExitCode.GENERAL_ERROR,\n 'Use --force for non-interactive deletion'\n );\n }\n\n console.log(`About to delete: ${pc.bold(note.title)}`);\n const confirmed = await confirm('Are you sure?');\n\n if (!confirmed) {\n console.log(pc.dim('Cancelled.'));\n return;\n }\n }\n\n const result = await deleteNote<DeleteNoteResponse>(id, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Deleted note: ${note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { updateNote } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface UpdateNoteOptions {\n title?: string;\n tags?: string[];\n}\n\nexport async function updateNoteAction(\n id: string,\n options: UpdateNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n if (!options.title && !options.tags) {\n throw new CLIError(\n 'No changes provided',\n 1,\n 'Use --title or --tags to specify what to update'\n );\n }\n\n const data: { title?: string; tags?: string[] } = {};\n if (options.title) data.title = options.title;\n if (options.tags) data.tags = options.tags;\n\n const result = await updateNote<UpdateNoteResponse>(id, data, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Updated note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { createInterface } from 'node:readline';\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport pc from 'picocolors';\n\n// PIN session cache settings\nconst PIN_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst PIN_MAX_ATTEMPTS = 3;\n\nfunction getPinCachePath(): string {\n const uid = process.getuid?.() ?? 'unknown';\n return join(tmpdir(), `pnote-pin-${uid}`);\n}\n\n// Session cache management\n\nexport function getCachedPin(): string | null {\n const cachePath = getPinCachePath();\n\n if (!existsSync(cachePath)) {\n return null;\n }\n\n try {\n const stat = statSync(cachePath);\n const age = Date.now() - stat.mtimeMs;\n\n if (age > PIN_CACHE_TTL_MS) {\n // Cache expired, remove it\n unlinkSync(cachePath);\n return null;\n }\n\n const content = readFileSync(cachePath, 'utf-8').trim();\n return content || null;\n } catch {\n return null;\n }\n}\n\nexport function setCachedPin(pin: string): void {\n const cachePath = getPinCachePath();\n\n try {\n writeFileSync(cachePath, pin, { mode: 0o600 });\n } catch {\n // Silently fail - cache is optional\n }\n}\n\nexport function clearCachedPin(): boolean {\n const cachePath = getPinCachePath();\n\n if (existsSync(cachePath)) {\n try {\n unlinkSync(cachePath);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\n// PIN input methods\n\n/**\n * Read PIN from stdin (for --pin-stdin option)\n * Only reads the first line\n */\nexport async function readPinFromStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n // Only read first line\n const content = Buffer.concat(chunks).toString('utf-8');\n if (content.includes('\\n')) {\n break;\n }\n }\n\n const content = Buffer.concat(chunks).toString('utf-8');\n const firstLine = content.split('\\n')[0]?.trim() || '';\n\n if (!firstLine) {\n throw new Error('No PIN provided via stdin');\n }\n\n return firstLine;\n}\n\n/**\n * Prompt user for PIN interactively\n * Hides input and supports retry\n */\nexport async function promptForPin(\n noteTitle?: string,\n hint?: string,\n maxAttempts: number = PIN_MAX_ATTEMPTS\n): Promise<string | null> {\n if (!process.stdin.isTTY) {\n return null;\n }\n\n // Show context\n if (noteTitle) {\n console.error(pc.yellow('🔒') + ` Note \"${noteTitle}\" is PIN-protected.`);\n } else {\n console.error(pc.yellow('🔒') + ' This action requires your PIN.');\n }\n\n if (hint) {\n console.error(pc.dim(`Hint: ${hint}`));\n }\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const pin = await readPinHidden(\n attempt > 1 ? `Enter PIN (${attempt}/${maxAttempts}): ` : 'Enter PIN: '\n );\n\n if (pin) {\n return pin;\n }\n\n if (attempt < maxAttempts) {\n console.error(pc.red('Invalid or empty PIN. Try again.'));\n }\n }\n\n console.error(pc.red('Too many attempts.'));\n return null;\n}\n\n/**\n * Read a line with hidden input (for PIN entry)\n */\nasync function readPinHidden(prompt: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n terminal: true,\n });\n\n // Disable echo\n if (process.stdin.isTTY) {\n process.stdin.setRawMode?.(true);\n }\n\n process.stderr.write(prompt);\n\n let pin = '';\n\n const onKeypress = (key: Buffer) => {\n const char = key.toString();\n\n if (char === '\\r' || char === '\\n') {\n // Enter pressed\n process.stderr.write('\\n');\n cleanup();\n resolve(pin);\n } else if (char === '\\u0003') {\n // Ctrl+C\n process.stderr.write('\\n');\n cleanup();\n process.exit(130);\n } else if (char === '\\u007F' || char === '\\b') {\n // Backspace\n if (pin.length > 0) {\n pin = pin.slice(0, -1);\n // Move cursor back and clear\n process.stderr.write('\\b \\b');\n }\n } else if (char.length === 1 && char >= ' ') {\n // Regular character\n pin += char;\n process.stderr.write('*');\n }\n };\n\n const cleanup = () => {\n process.stdin.removeListener('data', onKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode?.(false);\n }\n rl.close();\n };\n\n process.stdin.on('data', onKeypress);\n });\n}\n\n/**\n * Get PIN from all sources in priority order\n *\n * Priority:\n * 1. --pin argument (passed in ctx.pin)\n * 2. --pin-stdin (if pinFromStdin is true)\n * 3. PNOTE_PIN environment variable\n * 4. Session cache\n * 5. Interactive prompt (if TTY)\n * 6. null (not available)\n */\nexport async function resolvePin(options: {\n pinArg?: string;\n pinFromStdin?: boolean;\n noteTitle?: string;\n hint?: string;\n skipCache?: boolean;\n skipPrompt?: boolean;\n}): Promise<string | null> {\n const { pinArg, pinFromStdin, noteTitle, hint, skipCache, skipPrompt } = options;\n\n // 1. Command line argument (highest priority)\n if (pinArg) {\n return pinArg;\n }\n\n // 2. stdin\n if (pinFromStdin) {\n try {\n return await readPinFromStdin();\n } catch {\n return null;\n }\n }\n\n // 3. Environment variable\n const envPin = process.env.PNOTE_PIN;\n if (envPin) {\n return envPin;\n }\n\n // 4. Session cache\n if (!skipCache) {\n const cached = getCachedPin();\n if (cached) {\n return cached;\n }\n }\n\n // 5. Interactive prompt\n if (!skipPrompt && process.stdin.isTTY) {\n const pin = await promptForPin(noteTitle, hint);\n if (pin) {\n // Cache for future use\n setCachedPin(pin);\n return pin;\n }\n }\n\n // 6. Not available\n return null;\n}\n\n/**\n * Check if PIN is required but not available\n * Returns error message if PIN is needed but missing\n */\nexport function checkPinRequired(\n isProtected: boolean,\n pin: string | null | undefined\n): string | null {\n if (!isProtected) {\n return null;\n }\n\n if (pin) {\n return null;\n }\n\n if (!process.stdin.isTTY) {\n return 'PIN required but not provided. Use -p <pin> or set PNOTE_PIN environment variable.';\n }\n\n return null;\n}\n","import { Command } from 'commander';\nimport { showSnippetAction } from './show.js';\nimport { copySnippetAction } from './copy.js';\nimport { addSnippetAction } from './add.js';\nimport { updateSnippetAction } from './update.js';\nimport { favoriteSnippetAction } from './favorite.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const snippetCommand = new Command('snippet')\n .description('Read and manage snippets (note versions)')\n .argument('[note-id]', 'Note ID to show snippet for')\n .option('--all', 'Show all snippet versions')\n .action(async (noteId: string | undefined, options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n\n if (noteId) {\n await showSnippetAction(noteId, options, ctx);\n } else {\n cmd.help();\n }\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote snippet abc123 Show latest snippet\n $ pnote snippet abc123 --all Show all versions\n $ pnote snippet copy abc123 Copy to clipboard\n $ cat file.txt | pnote snippet add abc123\n`\n );\n\nsnippetCommand\n .command('copy')\n .description('Copy snippet content to clipboard')\n .argument('<note-id>', 'Note ID')\n .option('--version <n>', 'Specific version number')\n .action(async (noteId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await copySnippetAction(noteId, options, ctx);\n });\n\nsnippetCommand\n .command('add')\n .description('Add a new snippet version (from stdin)')\n .argument('<note-id>', 'Note ID')\n .option('--title <title>', 'Snippet title')\n .action(async (noteId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await addSnippetAction(noteId, options, ctx);\n });\n\nsnippetCommand\n .command('update')\n .description('Update an existing snippet (from stdin)')\n .argument('<snippet-id>', 'Snippet ID')\n .option('--title <title>', 'New snippet title')\n .action(async (snippetId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await updateSnippetAction(snippetId, options, ctx);\n });\n\nsnippetCommand\n .command('favorite')\n .description('Toggle favorite status on a snippet')\n .argument('<snippet-id>', 'Snippet ID')\n .action(async (snippetId: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await favoriteSnippetAction(snippetId, ctx);\n });\n","import { getNote, listSnippets } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputSnippet, outputSnippets } from '../../lib/output.js';\nimport type { GetNoteResponse, ListSnippetsResponse, CLIContext } from '../../types/index.js';\n\ninterface ShowSnippetOptions {\n all?: boolean;\n}\n\nexport async function showSnippetAction(\n noteId: string,\n options: ShowSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n if (options.all) {\n // Show all versions\n const result = await listSnippets<ListSnippetsResponse>(\n { note_id: noteId, limit: 100 },\n { pin: ctx.pin }\n );\n\n outputSnippets(result.snippets, ctx);\n } else {\n // Show latest snippet only\n const result = await getNote<GetNoteResponse>(noteId, { pin: ctx.pin });\n\n if (result.latest_snippet) {\n outputSnippet(result.latest_snippet, ctx);\n } else {\n if (!ctx.json) {\n console.error('No snippet content found.');\n }\n process.exit(3);\n }\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import pc from 'picocolors';\nimport { getNote, listSnippets } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { copyToClipboard } from '../../lib/clipboard.js';\nimport { logStatus } from '../../lib/output.js';\nimport type { GetNoteResponse, ListSnippetsResponse, Snippet, CLIContext } from '../../types/index.js';\n\ninterface CopySnippetOptions {\n version?: string;\n}\n\nexport async function copySnippetAction(\n noteId: string,\n options: CopySnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let snippet: Snippet | null = null;\n\n if (options.version) {\n // Get specific version\n const versionNum = parseInt(options.version, 10);\n if (isNaN(versionNum)) {\n throw new CLIError('Invalid version number');\n }\n\n const result = await listSnippets<ListSnippetsResponse>(\n { note_id: noteId, limit: 100 },\n { pin: ctx.pin }\n );\n\n snippet = result.snippets.find((s) => s.version === versionNum) || null;\n\n if (!snippet) {\n throw new CLIError(`Version ${versionNum} not found`);\n }\n } else {\n // Get latest\n const result = await getNote<GetNoteResponse>(noteId, { pin: ctx.pin });\n snippet = result.latest_snippet;\n }\n\n if (!snippet) {\n throw new CLIError('No snippet content found');\n }\n\n try {\n await copyToClipboard(snippet.content);\n logStatus('Copied to clipboard');\n\n // If JSON mode, output the snippet data\n if (ctx.json) {\n console.log(JSON.stringify({ copied: true, content: snippet.content }));\n }\n } catch (clipboardError) {\n // Fallback: print to stdout\n if (!ctx.json) {\n console.error(pc.yellow('Clipboard not available, printing to stdout:'));\n console.error('');\n }\n console.log(snippet.content);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { default as clipboardy } from 'clipboardy';\nimport { CLIError } from './errors.js';\n\nexport async function copyToClipboard(text: string): Promise<void> {\n try {\n await clipboardy.write(text);\n } catch (error) {\n // Fallback: output to stdout with a warning\n if (error instanceof Error && error.message.includes('xsel')) {\n throw new CLIError(\n 'Clipboard not available. Install xsel or xclip on Linux.',\n 1,\n 'Content will be printed to stdout instead.'\n );\n }\n throw new CLIError('Failed to copy to clipboard');\n }\n}\n\nexport async function readFromClipboard(): Promise<string> {\n try {\n return await clipboardy.read();\n } catch {\n throw new CLIError('Failed to read from clipboard');\n }\n}\n","import { createSnippet } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CreateSnippetResponse, CLIContext } from '../../types/index.js';\n\ninterface AddSnippetOptions {\n title?: string;\n}\n\nexport async function addSnippetAction(\n noteId: string,\n options: AddSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let content: string;\n\n // Read content from stdin\n if (process.stdin.isTTY) {\n throw new CLIError(\n 'No content provided',\n 1,\n \"Pipe content to this command: echo 'content' | pnote snippet add <note-id>\"\n );\n }\n\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n content = Buffer.concat(chunks).toString('utf-8');\n\n // Trim trailing newline but preserve internal formatting\n if (content.endsWith('\\n')) {\n content = content.slice(0, -1);\n }\n\n if (!content) {\n throw new CLIError('Empty content provided');\n }\n\n const result = await createSnippet<CreateSnippetResponse>(\n {\n note_id: noteId,\n content,\n title: options.title,\n },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Created snippet v${result.snippet.version}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { updateSnippet } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CLIContext } from '../../types/index.js';\n\ninterface UpdateSnippetOptions {\n title?: string;\n}\n\ninterface UpdateSnippetResponse {\n message: string;\n snippet: {\n id: string;\n version: number;\n content: string;\n title: string | null;\n favorite: boolean;\n };\n}\n\nexport async function updateSnippetAction(\n snippetId: string,\n options: UpdateSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Read content from stdin\n let content: string | undefined;\n\n if (!process.stdin.isTTY) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n content = Buffer.concat(chunks).toString('utf-8');\n\n // Trim trailing newline but preserve internal formatting\n if (content.endsWith('\\n')) {\n content = content.slice(0, -1);\n }\n\n if (!content) {\n content = undefined;\n }\n }\n\n // Must provide content or title\n if (!content && !options.title) {\n throw new CLIError(\n 'No content or title provided',\n 1,\n \"Pipe content to this command: echo 'content' | pnote snippet update <snippet-id>\"\n );\n }\n\n const data: { content?: string; title?: string } = {};\n if (content) data.content = content;\n if (options.title) data.title = options.title;\n\n const result = await updateSnippet<UpdateSnippetResponse>(\n snippetId,\n data,\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage('Updated snippet', ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { toggleFavorite } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { ToggleFavoriteResponse, CLIContext } from '../../types/index.js';\n\nexport async function favoriteSnippetAction(\n snippetId: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await toggleFavorite<ToggleFavoriteResponse>(snippetId, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const status = result.snippet.favorite ? 'favorited' : 'unfavorited';\n outputMessage(`Snippet ${status}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { Command } from 'commander';\nimport { listTagsAction } from './list.js';\nimport { renameTagAction } from './rename.js';\nimport { mergeTagsAction } from './merge.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const tagsCommand = new Command('tags')\n .description('List and manage tags')\n .option('--include-archived', 'Include tags from archived notes')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listTagsAction(options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote tags List all tags\n $ pnote tags rename \"old\" \"new\" Rename a tag\n $ pnote tags merge \"tag1\" \"tag2\" --into \"target\"\n`\n );\n\ntagsCommand\n .command('rename')\n .description('Rename a tag across all notes')\n .argument('<old-tag>', 'Current tag name')\n .argument('<new-tag>', 'New tag name')\n .action(async (oldTag: string, newTag: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await renameTagAction(oldTag, newTag, ctx);\n });\n\ntagsCommand\n .command('merge')\n .description('Merge multiple tags into one')\n .argument('<source-tags...>', 'Tags to merge (space-separated)')\n .requiredOption('--into <target>', 'Target tag to merge into')\n .action(async (sourceTags: string[], options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await mergeTagsAction(sourceTags, options.into, ctx);\n });\n","import { listTags } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputTags } from '../../lib/output.js';\nimport type { ListTagsResponse, CLIContext } from '../../types/index.js';\n\ninterface ListTagsOptions {\n includeArchived?: boolean;\n}\n\nexport async function listTagsAction(\n options: ListTagsOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listTags<ListTagsResponse>(\n { include_archived: options.includeArchived ?? false },\n { pin: ctx.pin }\n );\n\n outputTags(result.tags, result.hierarchy, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { renameTag } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { RenameTagResponse, CLIContext } from '../../types/index.js';\n\nexport async function renameTagAction(\n oldTag: string,\n newTag: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await renameTag<RenameTagResponse>(\n { old_tag: oldTag, new_tag: newTag },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(\n `Renamed \"${oldTag}\" to \"${newTag}\" (${result.notes_updated} notes updated)`,\n ctx\n );\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { mergeTags } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { MergeTagsResponse, CLIContext } from '../../types/index.js';\n\nexport async function mergeTagsAction(\n sourceTags: string[],\n targetTag: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Validate that source doesn't include target\n if (sourceTags.includes(targetTag)) {\n throw new CLIError('Source tags cannot include the target tag');\n }\n\n if (sourceTags.length === 0) {\n throw new CLIError('At least one source tag is required');\n }\n\n const result = await mergeTags<MergeTagsResponse>(\n { source_tags: sourceTags, target_tag: targetTag },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const sourceList = sourceTags.map((t) => `\"${t}\"`).join(', ');\n outputMessage(\n `Merged ${sourceList} into \"${targetTag}\" (${result.notes_updated} notes updated)`,\n ctx\n );\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { Command } from 'commander';\nimport { search } from '../lib/api.js';\nimport { handleError } from '../lib/errors.js';\nimport { outputSearchResults } from '../lib/output.js';\nimport { resolvePin } from '../lib/pin.js';\nimport type { SearchResponse, CLIContext } from '../types/index.js';\n\ninterface SearchOptions {\n notesOnly?: boolean;\n snippetsOnly?: boolean;\n limit?: string;\n}\n\nasync function searchAction(\n query: string,\n options: SearchOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let search_notes = true;\n let search_snippets = true;\n\n if (options.notesOnly) {\n search_notes = true;\n search_snippets = false;\n } else if (options.snippetsOnly) {\n search_notes = false;\n search_snippets = true;\n }\n\n const result = await search<SearchResponse>(\n {\n query,\n search_notes,\n search_snippets,\n limit: options.limit ? parseInt(options.limit, 10) : 20,\n },\n { pin: ctx.pin }\n );\n\n outputSearchResults(query, result.notes, result.snippets, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n\nexport const searchCommand = new Command('search')\n .description('Search notes and snippets')\n .argument('<query>', 'Search query')\n .option('--notes-only', 'Only search note titles and tags')\n .option('--snippets-only', 'Only search snippet content')\n .option('--limit <n>', 'Limit results', '20')\n .action(async (query: string, options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n const ctx: CLIContext = {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n await searchAction(query, options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote search \"portrait\" Search all\n $ pnote search \"AI\" --notes-only Search note titles only\n $ pnote search \"code\" --limit 50 Limit results\n`\n );\n","import { Command } from 'commander';\nimport { listSharedTagsAction, getSharedTagNotesAction } from './tags.js';\nimport { listSharedNotesAction } from './notes.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const shareCommand = new Command('share')\n .description('View shared tags and shared note links')\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote share tags List shared tags\n $ pnote share tags abc123 View notes in shared tag\n $ pnote share notes List public share links\n $ pnote share notes --include-revoked\n`\n );\n\n// pnote share tags [id]\nshareCommand\n .command('tags')\n .description('List shared tags or view notes in a shared tag')\n .argument('[id]', 'Shared tag ID to view notes')\n .option('--limit <n>', 'Limit notes returned')\n .action(async (id: string | undefined, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n\n if (id) {\n await getSharedTagNotesAction(id, options, ctx);\n } else {\n await listSharedTagsAction(ctx);\n }\n });\n\n// pnote share notes\nshareCommand\n .command('notes')\n .description('List public share links for your notes')\n .option('--include-revoked', 'Include revoked share links')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listSharedNotesAction(options, ctx);\n });\n","import { listSharedTags, getSharedTagNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputSharedTags, outputSharedTagNotes } from '../../lib/output.js';\nimport type {\n ListSharedTagsResponse,\n GetSharedTagNotesResponse,\n CLIContext,\n} from '../../types/index.js';\n\ninterface SharedTagNotesOptions {\n limit?: string;\n}\n\nexport async function listSharedTagsAction(ctx: CLIContext): Promise<void> {\n try {\n const result = await listSharedTags<ListSharedTagsResponse>({ pin: ctx.pin });\n outputSharedTags(result, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n\nexport async function getSharedTagNotesAction(\n id: string,\n options: SharedTagNotesOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await getSharedTagNotes<GetSharedTagNotesResponse>(\n id,\n { limit: options.limit ? parseInt(options.limit, 10) : undefined },\n { pin: ctx.pin }\n );\n outputSharedTagNotes(result, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { listSharedNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputSharedNotes } from '../../lib/output.js';\nimport type { ListSharedNotesResponse, CLIContext } from '../../types/index.js';\n\ninterface SharedNotesOptions {\n includeRevoked?: boolean;\n}\n\nexport async function listSharedNotesAction(\n options: SharedNotesOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listSharedNotes<ListSharedNotesResponse>(\n { include_revoked: options.includeRevoked },\n { pin: ctx.pin }\n );\n outputSharedNotes(result, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n"],"mappings":"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","names":["Command","pc","pc","pc","pc","pc","pc","pc","pc","Command","pc","c","printTree","pc","pc","createInterface","existsSync","readFileSync","writeFileSync","unlinkSync","join","pc","content","pc","createInterface","Command","Command","pc","pc","buildContext","Command","Command","buildContext","Command","Command","Command","Command","buildContext","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pnote",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "pnote - The PromptNote CLI",
5
5
  "type": "module",
6
6
  "homepage": "https://promptnoteapp.com/",
@@ -17,7 +17,10 @@
17
17
  "build": "tsup",
18
18
  "dev": "tsup --watch",
19
19
  "start": "node dist/index.js",
20
- "typecheck": "tsc --noEmit"
20
+ "typecheck": "tsc --noEmit",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "test:coverage": "vitest run --coverage"
21
24
  },
22
25
  "keywords": [
23
26
  "promptnote",
@@ -32,13 +35,19 @@
32
35
  "node": ">=18.0.0"
33
36
  },
34
37
  "dependencies": {
38
+ "clipboardy": "^4.0.0",
35
39
  "commander": "^12.1.0",
36
- "picocolors": "^1.1.1",
37
- "clipboardy": "^4.0.0"
40
+ "picocolors": "^1.1.1"
38
41
  },
39
42
  "devDependencies": {
40
43
  "@types/node": "^22.0.0",
44
+ "@vitest/coverage-v8": "^4.0.18",
45
+ "c8": "^10.1.3",
46
+ "get-port": "^7.1.0",
47
+ "msw": "^2.12.10",
48
+ "polka": "^0.5.2",
41
49
  "tsup": "^8.3.5",
42
- "typescript": "^5.7.0"
50
+ "typescript": "^5.7.0",
51
+ "vitest": "^2.1.9"
43
52
  }
44
53
  }