pnote 0.1.1 → 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 +15 -3
- package/dist/index.js +292 -103
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
-
| `
|
|
107
|
+
| `PNOTE_TOKEN` | PAT token (overrides stored credentials) |
|
|
96
108
|
| `NO_COLOR` | Disable colors |
|
|
97
|
-
| `
|
|
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
|
|
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
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
return ++requestId;
|
|
313
|
+
async function listSharedTags(options = {}) {
|
|
314
|
+
return callRestApi("GET", "/share/tags", void 0, options);
|
|
313
315
|
}
|
|
314
|
-
async function
|
|
315
|
-
const
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
|
|
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.
|
|
397
|
+
if (process.env.PNOTE_TOKEN) {
|
|
468
398
|
console.log("");
|
|
469
399
|
console.log(
|
|
470
|
-
pc4.yellow("Note:") + "
|
|
400
|
+
pc4.yellow("Note:") + " PNOTE_TOKEN environment variable is still set."
|
|
471
401
|
);
|
|
472
|
-
console.log(pc4.dim("Unset it with: unset
|
|
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
|
|
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.
|
|
501
|
-
console.log(pc5.dim("Source: ") + "
|
|
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.
|
|
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("--
|
|
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:
|
|
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
|
|
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":";;;AAAA,SAAS,WAAAA,gBAAe;;;ACAxB,OAAO,QAAQ;AAGR,IAAM,WAAW;AAAA,EACtB,SAAS;AAAA,EACT,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,eAAe;AACjB;AAIO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YACE,SACO,WAAyB,SAAS,eAClC,MACP;AACA,UAAM,OAAO;AAHN;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,YAAN,cAAwB,SAAS;AAAA,EACtC,YAAY,SAAiB,MAAe;AAC1C,UAAM,SAAS,SAAS,YAAY,IAAI;AACxC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YAAY,UAAkB,IAAY;AACxC,UAAM,GAAG,QAAQ,mBAAmB,EAAE,KAAK,SAAS,SAAS;AAC7D,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,eAAN,cAA2B,SAAS;AAAA,EACzC,YAAY,UAAkB,yCAAyC;AACrE,UAAM,SAAS,SAAS,aAAa;AACrC,SAAK,OAAO;AAAA,EACd;AACF;AAIO,SAAS,YAAY,OAAgB,UAAmB,OAAe;AAC5E,QAAM,MAAM,UAAU,CAAC,MAAc,IAAI,GAAG;AAC5C,QAAM,MAAM,UAAU,CAAC,MAAc,IAAI,GAAG;AAE5C,MAAI,iBAAiB,UAAU;AAC7B,QAAI,UAAU,GAAG,IAAI,QAAQ,CAAC,IAAI,MAAM,OAAO;AAC/C,QAAI,MAAM,MAAM;AACd,iBAAW;AAAA,EAAK,IAAI,OAAO,CAAC,IAAI,MAAM,IAAI;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,OAAO;AAC1B,WAAO,GAAG,IAAI,QAAQ,CAAC,IAAI,MAAM,OAAO;AAAA,EAC1C;AAEA,SAAO,GAAG,IAAI,QAAQ,CAAC,IAAI,OAAO,KAAK,CAAC;AAC1C;AAIO,SAAS,YAAY,OAAgB,UAAmB,OAAc;AAC3E,UAAQ,MAAM,YAAY,OAAO,OAAO,CAAC;AAEzC,MAAI,iBAAiB,UAAU;AAC7B,YAAQ,KAAK,MAAM,QAAQ;AAAA,EAC7B;AAEA,UAAQ,KAAK,SAAS,aAAa;AACrC;;;AC5EA,SAAS,eAAe;;;ACAxB,OAAOC,SAAQ;;;ACAf,SAAS,YAAY,WAAW,cAAc,eAAe,YAAY,iBAAiB;AAC1F,SAAS,eAAe;AACxB,SAAS,YAAY;AAIrB,SAAS,eAAuB;AAC9B,QAAM,YAAY,QAAQ,IAAI;AAC9B,MAAI,WAAW;AACb,WAAO,KAAK,WAAW,OAAO;AAAA,EAChC;AAGA,QAAM,WAAW,QAAQ;AACzB,MAAI,aAAa,UAAU;AACzB,UAAM,UAAU,KAAK,QAAQ,GAAG,WAAW,uBAAuB,OAAO;AACzE,QAAI,WAAW,OAAO,GAAG;AACvB,aAAO;AAAA,IACT;AAAA,EACF;AAGA,SAAO,KAAK,QAAQ,GAAG,WAAW,OAAO;AAC3C;AAEA,SAAS,kBAA0B;AACjC,QAAM,MAAM,aAAa;AACzB,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAAA,EACjD;AACA,SAAO;AACT;AAIA,IAAM,mBAAmB;AAElB,SAAS,qBAA6B;AAC3C,SAAO,KAAK,aAAa,GAAG,gBAAgB;AAC9C;AAEO,SAAS,kBAAsC;AAEpD,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,UAAU;AACZ,WAAO;AAAA,MACL,OAAO;AAAA,MACP,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC;AAAA,EACF;AAGA,QAAM,OAAO,mBAAmB;AAChC,MAAI,CAAC,WAAW,IAAI,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,aAAa,MAAM,OAAO;AAC1C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBAAgB,aAAgC;AAC9D,QAAM,MAAM,gBAAgB;AAC5B,QAAM,OAAO,KAAK,KAAK,gBAAgB;AAEvC,gBAAc,MAAM,KAAK,UAAU,aAAa,MAAM,CAAC,GAAG,OAAO;AAGjE,YAAU,MAAM,GAAK;AACvB;AAEO,SAAS,oBAA6B;AAC3C,QAAM,OAAO,mBAAmB;AAChC,MAAI,WAAW,IAAI,GAAG;AACpB,eAAW,IAAI;AACf,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAIO,SAAS,WAA0B;AACxC,QAAM,QAAQ,gBAAgB;AAC9B,SAAO,OAAO,SAAS;AACzB;AAEO,SAAS,aAAsB;AACpC,SAAO,SAAS,MAAM;AACxB;AAEO,SAAS,oBAAoB,OAAwB;AAE1D,SAAO,4BAA4B,KAAK,KAAK;AAC/C;AAIA,IAAM,cAAc;AAEb,SAAS,aAAqB;AACnC,QAAM,OAAO,KAAK,aAAa,GAAG,WAAW;AAC7C,MAAI,CAAC,WAAW,IAAI,GAAG;AACrB,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACF,UAAM,UAAU,aAAa,MAAM,OAAO;AAC1C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAUA,IAAM,uBAAuB;AAEtB,SAAS,iBAAyB;AACvC,QAAM,SAAS,WAAW;AAC1B,SAAO,OAAO,gBAAgB,QAAQ,IAAI,sBAAsB;AAClE;;;ADhIA,eAAsB,cAA6B;AACjD,MAAI,WAAW,GAAG;AAChB,YAAQ,IAAIC,IAAG,OAAO,oBAAoB,CAAC;AAC3C,YAAQ,IAAIA,IAAG,IAAI,0BAA0B,mBAAmB,CAAC,EAAE,CAAC;AACpE,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAOA,IAAG,KAAK,qBAAqB,CAAC,mBAAmB;AACpE;AAAA,EACF;AAEA,UAAQ,IAAIA,IAAG,KAAK,qBAAqB,CAAC;AAC1C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,0DAA0D;AACtE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,IAAG,IAAI,QAAQ,CAAC;AAC5B,UAAQ,IAAI,eAAeA,IAAG,KAAK,+BAA+B,CAAC;AACnE,UAAQ,IAAI,kCAAkC;AAC9C,UAAQ,IAAI,2BAA2B;AACvC,UAAQ,IAAI,eAAeA,IAAG,KAAK,+BAA+B,CAAC;AACnE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,IAAG,IAAI,8CAA8C,CAAC;AACpE;;;AEvBA,OAAOC,SAAQ;;;ACIf,SAAS,iBAAyB;AAChC,QAAM,cAAc,eAAe;AACnC,SAAO,YAAY,QAAQ,UAAU,KAAK;AAC5C;AAQA,eAAe,YACb,QACA,MACA,MACA,UAA0B,CAAC,GACf;AACZ,QAAM,QAAQ,SAAS;AACvB,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,eAAe;AAC/B,QAAM,MAAM,GAAG,OAAO,GAAG,IAAI;AAE7B,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,eAAe,UAAU,KAAK;AAAA,EAChC;AAGA,MAAI,QAAQ,KAAK;AACf,YAAQ,kBAAkB,IAAI,QAAQ;AAAA,EACxC;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,eAA4B;AAAA,MAChC;AAAA,MACA;AAAA,MACA,QAAQ,YAAY,QAAQ,QAAQ,WAAW,GAAK;AAAA,IACtD;AAEA,QAAI,SAAS,WAAW,UAAU,WAAW,UAAU;AACrD,mBAAa,OAAO,KAAK,UAAU,IAAI;AAAA,IACzC;AAEA,eAAW,MAAM,MAAM,KAAK,YAAY;AAAA,EAC1C,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,UAAI,MAAM,SAAS,kBAAkB,MAAM,SAAS,cAAc;AAChE,cAAM,IAAI,aAAa,sCAAsC;AAAA,MAC/D;AACA,UAAI,MAAM,QAAQ,SAAS,OAAO,GAAG;AACnC,cAAM,IAAI,aAAa,sEAAsE;AAAA,MAC/F;AAAA,IACF;AACA,UAAM,IAAI,aAAa;AAAA,EACzB;AAGA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAExD,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,IAAI;AAAA,QACR,UAAU,WAAW;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,IAAI,SAAS,qBAAqB,SAAS,UAAU;AAAA,IAC7D;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,IAAI,SAAS,UAAU,WAAW,sBAAsB,SAAS,SAAS;AAAA,IAClF;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,IAAI,SAAS,UAAU,WAAW,mBAAmB,SAAS,aAAa;AAAA,IACnF;AAEA,UAAM,IAAI,SAAS,cAAc,SAAS,MAAM,MAAM,UAAU,WAAW,eAAe,EAAE;AAAA,EAC9F;AAEA,SAAO,SAAS,KAAK;AACvB;AAiBA,eAAsB,UAAa,SAA0B,CAAC,GAAG,UAA0B,CAAC,GAAe;AACzG,QAAM,QAAQ,IAAI,gBAAgB;AAClC,MAAI,OAAO,IAAK,OAAM,IAAI,OAAO,OAAO,GAAG;AAC3C,MAAI,OAAO,aAAa,OAAW,OAAM,IAAI,YAAY,OAAO,OAAO,QAAQ,CAAC;AAChF,MAAI,OAAO,WAAW,OAAW,OAAM,IAAI,UAAU,OAAO,OAAO,MAAM,CAAC;AAC1E,MAAI,OAAO,YAAY,OAAW,OAAM,IAAI,WAAW,OAAO,OAAO,OAAO,CAAC;AAC7E,MAAI,OAAO,cAAc,OAAW,OAAM,IAAI,aAAa,OAAO,OAAO,SAAS,CAAC;AACnF,MAAI,OAAO,OAAQ,OAAM,IAAI,UAAU,OAAO,MAAM;AACpD,MAAI,OAAO,MAAO,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AACzD,MAAI,OAAO,OAAQ,OAAM,IAAI,UAAU,OAAO,OAAO,MAAM,CAAC;AAE5D,QAAM,cAAc,MAAM,SAAS;AACnC,SAAO,YAAe,OAAO,SAAS,cAAc,IAAI,WAAW,KAAK,EAAE,IAAI,QAAW,OAAO;AAClG;AAEA,eAAsB,QAAW,IAAY,UAA0B,CAAC,GAAe;AACrF,SAAO,YAAe,OAAO,UAAU,EAAE,IAAI,QAAW,OAAO;AACjE;AAEA,eAAsB,WACpB,MACA,UAA0B,CAAC,GACf;AACZ,SAAO,YAAe,QAAQ,UAAU,MAAM,OAAO;AACvD;AAEA,eAAsB,WACpB,IACA,MACA,UAA0B,CAAC,GACf;AACZ,SAAO,YAAe,SAAS,UAAU,EAAE,IAAI,MAAM,OAAO;AAC9D;AAEA,eAAsB,WAAc,IAAY,UAA0B,CAAC,GAAe;AACxF,SAAO,YAAe,UAAU,UAAU,EAAE,IAAI,QAAW,OAAO;AACpE;AAYA,eAAsB,aAAgB,QAA4B,UAA0B,CAAC,GAAe;AAC1G,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,IAAI,WAAW,OAAO,OAAO;AACnC,MAAI,OAAO,oBAAoB,OAAW,OAAM,IAAI,mBAAmB,OAAO,OAAO,eAAe,CAAC;AACrG,MAAI,OAAO,MAAO,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAEzD,SAAO,YAAe,OAAO,aAAa,MAAM,SAAS,CAAC,IAAI,QAAW,OAAO;AAClF;AAMA,eAAsB,cACpB,MACA,UAA0B,CAAC,GACf;AACZ,SAAO,YAAe,QAAQ,aAAa,MAAM,OAAO;AAC1D;AAEA,eAAsB,cACpB,IACA,MACA,UAA0B,CAAC,GACf;AACZ,SAAO,YAAe,SAAS,aAAa,EAAE,IAAI,MAAM,OAAO;AACjE;AAEA,eAAsB,eAAkB,IAAY,UAA0B,CAAC,GAAe;AAC5F,SAAO,YAAe,QAAQ,aAAa,EAAE,aAAa,CAAC,GAAG,OAAO;AACvE;AAUA,eAAsB,SAAY,SAAyB,CAAC,GAAG,UAA0B,CAAC,GAAe;AACvG,QAAM,QAAQ,IAAI,gBAAgB;AAClC,MAAI,OAAO,qBAAqB,OAAW,OAAM,IAAI,oBAAoB,OAAO,OAAO,gBAAgB,CAAC;AAExG,QAAM,cAAc,MAAM,SAAS;AACnC,SAAO,YAAe,OAAO,QAAQ,cAAc,IAAI,WAAW,KAAK,EAAE,IAAI,QAAW,OAAO;AACjG;AAEA,eAAsB,UACpB,MACA,UAA0B,CAAC,GACf;AACZ,SAAO,YAAe,QAAQ,gBAAgB,MAAM,OAAO;AAC7D;AAEA,eAAsB,UACpB,MACA,UAA0B,CAAC,GACf;AACZ,SAAO,YAAe,QAAQ,eAAe,MAAM,OAAO;AAC5D;AAaA,eAAsB,OAAU,QAAsB,UAA0B,CAAC,GAAe;AAC9F,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,IAAI,KAAK,OAAO,KAAK;AAC3B,MAAI,OAAO,iBAAiB,OAAW,OAAM,IAAI,gBAAgB,OAAO,OAAO,YAAY,CAAC;AAC5F,MAAI,OAAO,oBAAoB,OAAW,OAAM,IAAI,mBAAmB,OAAO,OAAO,eAAe,CAAC;AACrG,MAAI,OAAO,MAAO,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAEzD,SAAO,YAAe,OAAO,WAAW,MAAM,SAAS,CAAC,IAAI,QAAW,OAAO;AAChF;AA8BA,eAAsB,eAAkB,UAA0B,CAAC,GAAe;AAChF,SAAO,YAAe,OAAO,eAAe,QAAW,OAAO;AAChE;AAEA,eAAsB,kBACpB,IACA,SAA6B,CAAC,GAC9B,UAA0B,CAAC,GACf;AACZ,QAAM,QAAQ,IAAI,gBAAgB;AAClC,MAAI,OAAO,MAAO,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAEzD,QAAM,cAAc,MAAM,SAAS;AACnC,SAAO,YAAe,OAAO,eAAe,EAAE,SAAS,cAAc,IAAI,WAAW,KAAK,EAAE,IAAI,QAAW,OAAO;AACnH;AAEA,eAAsB,gBACpB,SAAwC,CAAC,GACzC,UAA0B,CAAC,GACf;AACZ,QAAM,QAAQ,IAAI,gBAAgB;AAClC,MAAI,OAAO,oBAAoB,OAAW,OAAM,IAAI,mBAAmB,OAAO,OAAO,eAAe,CAAC;AAErG,QAAM,cAAc,MAAM,SAAS;AACnC,SAAO,YAAe,OAAO,eAAe,cAAc,IAAI,WAAW,KAAK,EAAE,IAAI,QAAW,OAAO;AACxG;AA0HA,eAAsB,YAAY,OAA4D;AAC5F,QAAM,UAAU,eAAe,EAAE,QAAQ,UAAU,KAAK;AAExD,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,kBAAkB;AAAA,MACvD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK;AAAA,MAChC;AAAA,MACA,QAAQ,YAAY,QAAQ,GAAK;AAAA,IACnC,CAAC;AAED,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO,EAAE,OAAO,MAAM;AAAA,IACxB;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,aAAO,EAAE,OAAO,MAAM;AAAA,IACxB;AAEA,WAAO,EAAE,OAAO,KAAK;AAAA,EACvB,QAAQ;AACN,UAAM,IAAI,aAAa,yDAAyD;AAAA,EAClF;AACF;;;ADrbA,eAAsB,YAAY,OAA8B;AAE9D,MAAI,CAAC,oBAAoB,KAAK,GAAG;AAC/B,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,IAAIC,IAAG,IAAI,oBAAoB,CAAC;AAExC,MAAI;AACF,UAAM,SAAS,MAAM,YAAY,KAAK;AAEtC,QAAI,CAAC,OAAO,OAAO;AACjB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,oBAAgB;AAAA,MACd;AAAA,MACA,OAAO,OAAO;AAAA,MACd,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,CAAC;AAED,YAAQ,IAAIA,IAAG,MAAM,QAAG,IAAI,4BAA4B;AACxD,YAAQ,IAAIA,IAAG,IAAI,0BAA0B,mBAAmB,CAAC,EAAE,CAAC;AACpE,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,mBAAmBA,IAAG,KAAK,OAAO,CAAC,YAAY;AAAA,EAC7D,SAAS,OAAO;AACd,gBAAY,KAAK;AAAA,EACnB;AACF;;;AE1CA,OAAOC,SAAQ;AAGf,eAAsB,eAA8B;AAClD,MAAI,CAAC,WAAW,GAAG;AACjB,YAAQ,IAAIC,IAAG,IAAI,gBAAgB,CAAC;AACpC;AAAA,EACF;AAEA,QAAM,UAAU,kBAAkB;AAElC,MAAI,SAAS;AACX,YAAQ,IAAIA,IAAG,MAAM,QAAG,IAAI,2BAA2B;AAAA,EACzD,OAAO;AACL,YAAQ,IAAIA,IAAG,IAAI,2BAA2B,CAAC;AAAA,EACjD;AAGA,MAAI,QAAQ,IAAI,aAAa;AAC3B,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACNA,IAAG,OAAO,OAAO,IACf;AAAA,IACJ;AACA,YAAQ,IAAIA,IAAG,IAAI,kCAAkC,CAAC;AAAA,EACxD;AACF;;;AC1BA,OAAOC,SAAQ;AAMf,eAAsB,eAA8B;AAClD,MAAI,CAAC,WAAW,GAAG;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,gBAAgB;AAC9B,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,UAAU,sBAAsB;AAAA,EAC5C;AAEA,MAAI;AAEF,UAAM,SAAS,MAAM,UAA6B,EAAE,OAAO,EAAE,CAAC;AAE9D,YAAQ,IAAIC,IAAG,MAAM,QAAG,IAAI,gBAAgB;AAC5C,YAAQ,IAAI,EAAE;AAEd,QAAI,MAAM,OAAO;AACf,cAAQ,IAAIA,IAAG,IAAI,SAAS,IAAI,MAAM,KAAK;AAAA,IAC7C;AAEA,YAAQ,IAAIA,IAAG,IAAI,SAAS,IAAI,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,QAAQ,MAAM,MAAM,MAAM,EAAE,CAAC;AACvF,YAAQ,IAAIA,IAAG,IAAI,UAAU,IAAI,mBAAmB,CAAC;AAErD,QAAI,QAAQ,IAAI,aAAa;AAC3B,cAAQ,IAAIA,IAAG,IAAI,UAAU,IAAI,kCAAkC;AAAA,IACrE,OAAO;AACL,cAAQ,IAAIA,IAAG,IAAI,UAAU,IAAI,kBAAkB;AAAA,IACrD;AAEA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAIA,IAAG,IAAI,gBAAgB,OAAO,KAAK,EAAE,CAAC;AAAA,EACpD,SAAS,OAAO;AACd,gBAAY,KAAK;AAAA,EACnB;AACF;;;ANtCO,IAAM,cAAc,IAAI,QAAQ,MAAM,EAC1C,YAAY,uBAAuB,EACnC;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOF;AAEF,YACG,QAAQ,OAAO,EACf,YAAY,qCAAqC,EACjD,OAAO,WAAW;AAErB,YACG,QAAQ,OAAO,EACf,YAAY,wBAAwB,EACpC,SAAS,WAAW,gCAAgC,EACpD,OAAO,WAAW;AAErB,YACG,QAAQ,QAAQ,EAChB,YAAY,2BAA2B,EACvC,OAAO,YAAY;AAEtB,YACG,QAAQ,QAAQ,EAChB,YAAY,iCAAiC,EAC7C,OAAO,YAAY;;;AOtCtB,SAAS,WAAAC,gBAAe;;;ACAxB,OAAOC,SAAQ;AAOf,SAAS,eAAe,KAA0B;AAChD,MAAI,IAAI,QAAS,QAAO;AACxB,MAAI,QAAQ,IAAI,SAAU,QAAO;AACjC,MAAI,QAAQ,IAAI,SAAS,OAAQ,QAAO;AACxC,SAAO,QAAQ,OAAO,SAAS;AACjC;AAGA,SAAS,cAAc,KAA0B;AAC/C,MAAI,IAAI,KAAM,QAAO;AACrB,MAAI,IAAI,MAAO,QAAO;AACtB,SAAO,QAAQ,OAAO,SAAS;AACjC;AAGA,SAAS,UAAU,KAAiB;AAClC,QAAM,WAAW,eAAe,GAAG;AACnC,SAAO;AAAA,IACL,KAAK,WAAWA,IAAG,MAAM,CAAC,MAAc;AAAA,IACxC,MAAM,WAAWA,IAAG,OAAO,CAAC,MAAc;AAAA,IAC1C,OAAO,WAAWA,IAAG,QAAQ,CAAC,MAAc;AAAA,IAC5C,QAAQ,WAAWA,IAAG,SAAS,CAAC,MAAc;AAAA,IAC9C,MAAM,WAAWA,IAAG,OAAO,CAAC,MAAc;AAAA,IAC1C,MAAM,WAAWA,IAAG,OAAO,CAAC,MAAc;AAAA,IAC1C,KAAK,WAAWA,IAAG,MAAM,CAAC,MAAc;AAAA,IACxC,SAAS,WAAWA,IAAG,UAAU,CAAC,MAAc;AAAA,EAClD;AACF;AAGA,SAAS,mBAAmB,SAAyB;AACnD,QAAM,OAAO,IAAI,KAAK,OAAO;AAC7B,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,SAAS,IAAI,QAAQ,IAAI,KAAK,QAAQ;AAC5C,QAAM,WAAW,KAAK,MAAM,SAAS,GAAI;AACzC,QAAM,WAAW,KAAK,MAAM,WAAW,EAAE;AACzC,QAAM,YAAY,KAAK,MAAM,WAAW,EAAE;AAC1C,QAAM,WAAW,KAAK,MAAM,YAAY,EAAE;AAE1C,MAAI,WAAW,IAAI;AACjB,WAAO,KAAK,mBAAmB;AAAA,EACjC;AACA,MAAI,WAAW,GAAG;AAChB,WAAO,GAAG,QAAQ;AAAA,EACpB;AACA,MAAI,YAAY,GAAG;AACjB,WAAO,GAAG,SAAS;AAAA,EACrB;AACA,MAAI,WAAW,GAAG;AAChB,WAAO,GAAG,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;AAGA,SAAS,SAAS,KAAa,QAAwB;AACrD,MAAI,IAAI,UAAU,OAAQ,QAAO;AACjC,SAAO,IAAI,MAAM,GAAG,SAAS,CAAC,IAAI;AACpC;AAGA,SAAS,IAAI,KAAa,OAAuB;AAC/C,MAAI,IAAI,UAAU,MAAO,QAAO,IAAI,MAAM,GAAG,KAAK;AAClD,SAAO,MAAM,IAAI,OAAO,QAAQ,IAAI,MAAM;AAC5C;AAGO,SAAS,WAAW,MAAqB;AAC9C,UAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAC3C;AAGO,SAAS,YAAY,OAAe,KAAuB;AAChE,MAAI,IAAI,MAAM;AACZ,eAAW,KAAK;AAChB;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,UAAMC,KAAI,UAAU,GAAG;AACvB,YAAQ,IAAIA,GAAE,IAAI,iBAAiB,CAAC;AACpC;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AAEvB,MAAI,cAAc,GAAG,GAAG;AAEtB,YAAQ;AAAA,MACN,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC,IACjB,OACA,EAAE,IAAI,IAAI,SAAS,EAAE,CAAC,IACtB,OACA,EAAE,IAAI,IAAI,QAAQ,EAAE,CAAC,IACrB,OACA,EAAE,IAAI,SAAS;AAAA,IACnB;AAEA,eAAW,QAAQ,OAAO;AACxB,YAAM,KAAK,SAAS,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,EAAE;AAC3C,YAAM,QAAQ,SAAS,KAAK,SAAS,cAAc,EAAE;AACrD,YAAM,OAAO,SAAS,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,EAAE;AACrD,YAAM,UAAU,mBAAmB,KAAK,UAAU;AAElD,UAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO,IAAI,OAAO,EAAE,IAAI,OAAO,IAAI,MAAM,EAAE,IAAI,OAAO;AAG/E,YAAM,aAAuB,CAAC;AAC9B,UAAI,KAAK,OAAQ,YAAW,KAAK,EAAE,OAAO,GAAG,CAAC;AAC9C,UAAI,KAAK,SAAU,YAAW,KAAK,EAAE,IAAI,KAAK,CAAC;AAC/C,UAAI,KAAK,aAAc,YAAW,KAAK,EAAE,QAAQ,KAAK,CAAC;AAEvD,UAAI,WAAW,SAAS,GAAG;AACzB,eAAO,WAAW,KAAK,EAAE,IAAI,MAAM;AAAA,MACrC;AAEA,cAAQ,IAAI,IAAI;AAAA,IAClB;AAAA,EACF,OAAO;AAEL,eAAW,QAAQ,OAAO;AACxB,cAAQ;AAAA,QACN,CAAC,KAAK,IAAI,KAAK,OAAO,KAAK,KAAK,KAAK,GAAG,GAAG,KAAK,UAAU,EAAE,KAAK,GAAI;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,WAAW,MAAY,SAAyB,KAAuB;AACrF,MAAI,IAAI,MAAM;AACZ,eAAW,EAAE,GAAG,MAAM,gBAAgB,QAAQ,CAAC;AAC/C;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AAEvB,MAAI,cAAc,GAAG,GAAG;AACtB,YAAQ,IAAI,EAAE,KAAK,KAAK,SAAS,YAAY,CAAC;AAC9C,YAAQ,IAAI,EAAE,IAAI,MAAM,IAAI,KAAK,EAAE;AACnC,YAAQ,IAAI,EAAE,IAAI,QAAQ,KAAK,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI,IAAI;AACjF,YAAQ,IAAI,EAAE,IAAI,WAAW,IAAI,IAAI,KAAK,KAAK,UAAU,EAAE,eAAe,CAAC;AAC3E,YAAQ,IAAI,EAAE,IAAI,WAAW,IAAI,IAAI,KAAK,KAAK,UAAU,EAAE,eAAe,CAAC;AAE3E,UAAM,SAAmB,CAAC;AAC1B,QAAI,KAAK,OAAQ,QAAO,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC/C,QAAI,KAAK,SAAU,QAAO,KAAK,EAAE,IAAI,UAAU,CAAC;AAChD,QAAI,KAAK,aAAc,QAAO,KAAK,EAAE,QAAQ,WAAW,CAAC;AACzD,QAAI,OAAO,SAAS,GAAG;AACrB,cAAQ,IAAI,EAAE,IAAI,UAAU,IAAI,OAAO,KAAK,IAAI,CAAC;AAAA,IACnD;AAEA,QAAI,SAAS;AACX,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,EAAE,IAAI,gBAAgB,QAAQ,OAAO,MAAM,CAAC;AACxD,cAAQ,IAAI,QAAQ,OAAO;AAAA,IAC7B,OAAO;AACL,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,EAAE,IAAI,cAAc,CAAC;AAAA,IACnC;AAAA,EACF,OAAO;AAEL,YAAQ,IAAI,UAAU,KAAK,KAAK,EAAE;AAClC,YAAQ,IAAI,OAAO,KAAK,EAAE,EAAE;AAC5B,YAAQ,IAAI,SAAS,KAAK,KAAK,KAAK,IAAI,CAAC,EAAE;AAC3C,QAAI,SAAS;AACX,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,QAAQ,OAAO;AAAA,IAC7B;AAAA,EACF;AACF;AAGO,SAAS,cAAc,SAAkB,KAAuB;AACrE,MAAI,IAAI,MAAM;AACZ,eAAW,OAAO;AAClB;AAAA,EACF;AAGA,UAAQ,IAAI,QAAQ,OAAO;AAC7B;AAGO,SAAS,eAAe,UAAqB,KAAuB;AACzE,MAAI,IAAI,MAAM;AACZ,eAAW,QAAQ;AACnB;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,UAAMA,KAAI,UAAU,GAAG;AACvB,YAAQ,IAAIA,GAAE,IAAI,oBAAoB,CAAC;AACvC;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AAEvB,MAAI,cAAc,GAAG,GAAG;AACtB,eAAW,WAAW,UAAU;AAC9B,YAAM,SAAS,IAAI,QAAQ,OAAO,MAC/B,QAAQ,WAAW,EAAE,OAAO,SAAI,IAAI,MACrC,EAAE,IAAI,KAAK,mBAAmB,QAAQ,UAAU,CAAC,GAAG;AAEtD,cAAQ,IAAI,EAAE,KAAK,MAAM,CAAC;AAC1B,cAAQ,IAAI,QAAQ,OAAO;AAC3B,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF,OAAO;AACL,eAAW,WAAW,UAAU;AAC9B,cAAQ,IAAI,IAAI,QAAQ,OAAO,IAAK,QAAQ,EAAE,IAAK,QAAQ,QAAQ,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,IACpF;AAAA,EACF;AACF;AAGO,SAAS,WAAW,MAAa,WAAyB,KAAuB;AACtF,MAAI,IAAI,MAAM;AACZ,eAAW,EAAE,MAAM,UAAU,CAAC;AAC9B;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,GAAG;AACrB,UAAMA,KAAI,UAAU,GAAG;AACvB,YAAQ,IAAIA,GAAE,IAAI,gBAAgB,CAAC;AACnC;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AAEvB,MAAI,cAAc,GAAG,GAAG;AAsBtB,QAASC,aAAT,SAAmB,SAAiB,QAAgB,QAAuB;AACzE,YAAM,QAAQ,YAAY,IAAI,OAAO,KAAK;AAC1C,YAAM,OAAO,QAAQ,MAAM,GAAG,EAAE,IAAI,KAAK;AACzC,YAAM,YAAY,SAAS,wBAAS;AAEpC,cAAQ,IAAI,SAAS,YAAY,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI,KAAK,KAAK,GAAG,CAAC;AAEpE,YAAM,WAAW,YAAY,IAAI,OAAO,KAAK,CAAC;AAC9C,eAAS,KAAK;AAEd,YAAM,YAAY,UAAU,SAAS,SAAS;AAC9C,eAAS,QAAQ,CAAC,OAAO,MAAM;AAC7B,QAAAA,WAAU,OAAO,WAAW,MAAM,SAAS,SAAS,CAAC;AAAA,MACvD,CAAC;AAAA,IACH;AAdS,oBAAAA;AApBT,UAAM,QAAkB,CAAC;AACzB,UAAM,cAAqC,oBAAI,IAAI;AAEnD,eAAW,OAAO,MAAM;AACtB,YAAM,QAAQ,IAAI,IAAI,MAAM,GAAG;AAC/B,UAAI,MAAM,WAAW,GAAG;AACtB,cAAM,KAAK,IAAI,GAAG;AAAA,MACpB,OAAO;AACL,cAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,cAAM,WAAW,YAAY,IAAI,MAAM,KAAK,CAAC;AAC7C,iBAAS,KAAK,IAAI,GAAG;AACrB,oBAAY,IAAI,QAAQ,QAAQ;AAAA,MAClC;AAAA,IACF;AAGA,UAAM,KAAK;AAEX,UAAM,cAAc,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAkB7D,UAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,YAAM,QAAQ,YAAY,IAAI,IAAI,KAAK;AACvC,cAAQ,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI,KAAK,KAAK,GAAG,CAAC;AAE/C,YAAM,WAAW,YAAY,IAAI,IAAI,KAAK,CAAC;AAC3C,eAAS,KAAK;AACd,eAAS,QAAQ,CAAC,OAAO,MAAM;AAC7B,QAAAA,WAAU,OAAO,IAAI,MAAM,SAAS,SAAS,CAAC;AAAA,MAChD,CAAC;AAAA,IACH,CAAC;AAAA,EACH,OAAO;AAEL,eAAW,OAAO,MAAM;AACtB,cAAQ,IAAI,GAAG,IAAI,GAAG,IAAK,IAAI,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;AAGO,SAAS,oBACd,OACA,OACA,UAQA,KACM;AACN,MAAI,IAAI,MAAM;AACZ,eAAW,EAAE,OAAO,OAAO,SAAS,CAAC;AACrC;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AAEvB,MAAI,MAAM,WAAW,KAAK,SAAS,WAAW,GAAG;AAC/C,YAAQ,IAAI,EAAE,IAAI,mBAAmB,KAAK,GAAG,CAAC;AAC9C;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,GAAG;AACpB,YAAQ,IAAI,EAAE,KAAK,UAAU,MAAM,MAAM,GAAG,CAAC;AAC7C,YAAQ,IAAI,EAAE;AACd,eAAW,QAAQ,OAAO;AACxB,cAAQ;AAAA,QACN,OAAO,EAAE,KAAK,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,OAAO,KAAK,QAAQ,OAAO,EAAE,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC;AAAA,MAC5F;AAAA,IACF;AACA,YAAQ,IAAI,EAAE;AAAA,EAChB;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,YAAQ,IAAI,EAAE,KAAK,aAAa,SAAS,MAAM,GAAG,CAAC;AACnD,YAAQ,IAAI,EAAE;AACd,eAAW,WAAW,UAAU;AAC9B,cAAQ;AAAA,QACN,OACE,EAAE,KAAK,QAAQ,QAAQ,MAAM,GAAG,CAAC,CAAC,IAClC,OACA,QAAQ,aACR,EAAE,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,MAChC;AACA,cAAQ,IAAI,SAAS,EAAE,IAAI,SAAS,QAAQ,iBAAiB,EAAE,CAAC,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGO,SAAS,iBAAiB,MAA8B,KAAuB;AACpF,MAAI,IAAI,MAAM;AACZ,eAAW,IAAI;AACf;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AACvB,QAAM,aAAa,KAAK,MAAM,QAAQ,KAAK,eAAe;AAE1D,MAAI,eAAe,GAAG;AACpB,YAAQ,IAAI,EAAE,IAAI,iBAAiB,CAAC;AACpC;AAAA,EACF;AAEA,MAAI,cAAc,GAAG,GAAG;AACtB,QAAI,KAAK,MAAM,QAAQ,GAAG;AACxB,cAAQ,IAAI,EAAE,KAAK,UAAU,KAAK,MAAM,KAAK,GAAG,CAAC;AACjD,cAAQ,IAAI,EAAE;AACd,iBAAW,OAAO,KAAK,MAAM,MAAM;AACjC,gBAAQ;AAAA,UACN,OAAO,EAAE,KAAK,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,OACpC,IAAI,IAAI,UAAU,EAAE,IAAI,OACxB,EAAE,IAAI,mBAAmB,IAAI,UAAU,CAAC;AAAA,QAC1C;AAAA,MACF;AACA,cAAQ,IAAI,EAAE;AAAA,IAChB;AAEA,QAAI,KAAK,eAAe,QAAQ,GAAG;AACjC,cAAQ,IAAI,EAAE,KAAK,mBAAmB,KAAK,eAAe,KAAK,GAAG,CAAC;AACnE,cAAQ,IAAI,EAAE;AACd,iBAAW,OAAO,KAAK,eAAe,MAAM;AAC1C,gBAAQ;AAAA,UACN,OAAO,EAAE,KAAK,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,OACpC,IAAI,IAAI,UAAU,EAAE,IAAI,OACxB,EAAE,IAAI,YAAY,mBAAmB,IAAI,SAAS,CAAC;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,eAAW,OAAO,KAAK,MAAM,MAAM;AACjC,cAAQ,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,UAAU,IAAI,UAAU,EAAE,KAAK,GAAI,CAAC;AAAA,IACxE;AACA,eAAW,OAAO,KAAK,eAAe,MAAM;AAC1C,cAAQ,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,UAAU,IAAI,SAAS,EAAE,KAAK,GAAI,CAAC;AAAA,IACxE;AAAA,EACF;AACF;AAGO,SAAS,qBAAqB,MAAiC,KAAuB;AAC3F,MAAI,IAAI,MAAM;AACZ,eAAW,IAAI;AACf;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AAEvB,MAAI,cAAc,GAAG,GAAG;AACtB,UAAM,OAAO,KAAK,WAAW,WAAW,UAAU;AAClD,YAAQ,IAAI,EAAE,KAAK,KAAK,WAAW,QAAQ,IAAI,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,aAAa,WAAW,CAAC;AACjG,YAAQ,IAAI,EAAE;AAEd,QAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,cAAQ,IAAI,EAAE,IAAI,gCAAgC,CAAC;AACnD;AAAA,IACF;AAEA,YAAQ;AAAA,MACN,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC,IAC1B,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,CAAC,IAC7B,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,CAAC,IAC9B,OAAO,EAAE,IAAI,SAAS;AAAA,IACxB;AAEA,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,SAAS,KAAK,SAAS,QAAS,KAAK,OAAO,SAAS;AAC3D,cAAQ;AAAA,QACN,OAAO,IAAI,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,EAAE,IAClC,OAAO,IAAI,SAAS,KAAK,OAAO,EAAE,GAAG,EAAE,IACvC,OAAO,IAAI,SAAS,QAAQ,EAAE,GAAG,EAAE,IACnC,OAAO,mBAAmB,KAAK,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF,OAAO;AACL,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,SAAS,KAAK,SAAS,QAAS,KAAK,OAAO,SAAS;AAC3D,cAAQ,IAAI,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,UAAU,EAAE,KAAK,GAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACF;AAGO,SAAS,kBAAkB,MAA+B,KAAuB;AACtF,MAAI,IAAI,MAAM;AACZ,eAAW,IAAI;AACf;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AAEvB,MAAI,KAAK,UAAU,GAAG;AACpB,YAAQ,IAAI,EAAE,IAAI,kBAAkB,CAAC;AACrC;AAAA,EACF;AAEA,MAAI,cAAc,GAAG,GAAG;AACtB,YAAQ,IAAI,EAAE,KAAK,iBAAiB,KAAK,KAAK,GAAG,CAAC;AAClD,YAAQ,IAAI,EAAE;AAEd,eAAW,SAAS,KAAK,QAAQ;AAC/B,YAAM,UAAU,MAAM,aAAa,EAAE,IAAI,MAAM,IAAI;AACnD,cAAQ;AAAA,QACN,OAAO,SAAS,MAAM,YAAY,EAAE,IACpC,OAAO,EAAE,KAAK,MAAM,SAAS,IAC7B,OAAO,EAAE,IAAI,GAAG,MAAM,UAAU,QAAQ,IACxC,OAAO,EAAE,IAAI,mBAAmB,MAAM,UAAU,CAAC,IACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,eAAW,SAAS,KAAK,QAAQ;AAC/B,cAAQ;AAAA,QACN,CAAC,MAAM,YAAY,MAAM,WAAW,MAAM,YAAY,MAAM,YAAY,MAAM,UAAU,EAAE,KAAK,GAAI;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,cAAc,SAAiB,KAAuB;AACpE,MAAI,IAAI,MAAM;AACZ,eAAW,EAAE,QAAQ,CAAC;AACtB;AAAA,EACF;AAEA,QAAM,IAAI,UAAU,GAAG;AACvB,UAAQ,IAAI,EAAE,MAAM,QAAG,IAAI,MAAM,OAAO;AAC1C;AAGO,SAAS,UAAU,SAAuB;AAC/C,MAAI,QAAQ,OAAO,OAAO;AACxB,YAAQ,MAAMF,IAAG,IAAI,OAAO,CAAC;AAAA,EAC/B;AACF;;;AC9dA,eAAsB,gBACpB,SACA,KACe;AACf,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE,KAAK,QAAQ;AAAA,QACb,UAAU,QAAQ,YAAY;AAAA,QAC9B,QAAQ,QAAQ;AAAA,QAChB,SAAS,QAAQ,WAAW;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,OAAO,QAAQ,QAAQ,SAAS,QAAQ,OAAO,EAAE,IAAI;AAAA,MACvD;AAAA,MACA,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,gBAAY,OAAO,OAAO,GAAG;AAG7B,QAAI,OAAO,WAAW,CAAC,IAAI,MAAM;AAC/B,cAAQ,MAAM,EAAE;AAChB,cAAQ,MAAM,OAAO,OAAO;AAAA,IAC9B;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACpCA,eAAsB,cAAc,IAAY,KAAgC;AAC9E,MAAI;AACF,UAAM,SAAS,MAAM,QAAyB,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC;AAElE,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,cAAc,QAAQ,EAAE;AAAA,IACpC;AAEA,eAAW,QAAQ,OAAO,gBAAgB,GAAG;AAG7C,QAAI,OAAO,mBAAmB,SAAS,CAAC,IAAI,MAAM;AAChD,cAAQ,MAAM,EAAE;AAChB,cAAQ,MAAM,cAAc,OAAO,kBAAkB,KAAK;AAAA,IAC5D;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACbA,eAAsB,iBACpB,OACA,SACA,KACe;AACf,MAAI;AACF,QAAI,UAAU,QAAQ;AAGtB,QAAI,CAAC,WAAW,CAAC,QAAQ,MAAM,OAAO;AACpC,YAAM,SAAmB,CAAC;AAC1B,uBAAiB,SAAS,QAAQ,OAAO;AACvC,eAAO,KAAK,KAAK;AAAA,MACnB;AACA,YAAM,eAAe,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK;AAClE,UAAI,cAAc;AAChB,kBAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE;AAAA,QACA,MAAM,QAAQ,QAAQ,QAAQ,KAAK,SAAS,IAAI,QAAQ,OAAO;AAAA,QAC/D;AAAA,MACF;AAAA,MACA,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,oBAAc,iBAAiB,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,EAAE,KAAK,GAAG;AAAA,IAC7E;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACtCA,eAAsB,kBACpB,IACA,SACA,KACe;AACf,MAAI;AACF,UAAM,WAAW,CAAC,QAAQ;AAE1B,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,EAAE,SAAS;AAAA,MACX,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,YAAM,SAAS,WAAW,aAAa;AACvC,oBAAc,GAAG,MAAM,UAAU,OAAO,KAAK,KAAK,IAAI,GAAG;AAAA,IAC3D;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;AC3BA,eAAsB,cAAc,IAAY,KAAgC;AAC9E,MAAI;AAEF,UAAM,OAAO,MAAM,QAAyB,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC;AAChE,UAAM,YAAY,CAAC,KAAK;AAExB,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,EAAE,QAAQ,UAAU;AAAA,MACpB,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,YAAM,SAAS,YAAY,WAAW;AACtC,oBAAc,GAAG,MAAM,UAAU,OAAO,KAAK,KAAK,IAAI,GAAG;AAAA,IAC3D;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;AC1BA,OAAOG,SAAQ;AACf,SAAS,uBAAuB;AAUhC,eAAe,QAAQ,SAAmC;AACxD,QAAM,KAAK,gBAAgB;AAAA,IACzB,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,OAAG,SAAS,UAAU,WAAW,CAAC,WAAW;AAC3C,SAAG,MAAM;AACT,cAAQ,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,KAAK;AAAA,IACxE,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,iBACpB,IACA,SACA,KACe;AACf,MAAI;AAEF,UAAM,OAAO,MAAM,QAAyB,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC;AAGhE,QAAI,CAAC,QAAQ,SAAS,CAAC,IAAI,MAAM;AAC/B,UAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAEA,cAAQ,IAAI,oBAAoBC,IAAG,KAAK,KAAK,KAAK,CAAC,EAAE;AACrD,YAAM,YAAY,MAAM,QAAQ,eAAe;AAE/C,UAAI,CAAC,WAAW;AACd,gBAAQ,IAAIA,IAAG,IAAI,YAAY,CAAC;AAChC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,WAA+B,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC;AAExE,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,oBAAc,iBAAiB,KAAK,KAAK,IAAI,GAAG;AAAA,IAClD;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACrDA,eAAsB,iBACpB,IACA,SACA,KACe;AACf,MAAI;AACF,QAAI,CAAC,QAAQ,SAAS,CAAC,QAAQ,MAAM;AACnC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAA4C,CAAC;AACnD,QAAI,QAAQ,MAAO,MAAK,QAAQ,QAAQ;AACxC,QAAI,QAAQ,KAAM,MAAK,OAAO,QAAQ;AAEtC,UAAM,SAAS,MAAM,WAA+B,IAAI,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;AAE9E,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,oBAAc,iBAAiB,OAAO,KAAK,KAAK,IAAI,GAAG;AAAA,IACzD;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACtCA,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,cAAAC,aAAY,gBAAAC,eAAc,iBAAAC,gBAAe,cAAAC,aAAY,gBAAgB;AAC9E,SAAS,cAAc;AACvB,SAAS,QAAAC,aAAY;AACrB,OAAOC,SAAQ;AAGf,IAAM,mBAAmB,IAAI,KAAK;AAClC,IAAM,mBAAmB;AAEzB,SAAS,kBAA0B;AACjC,QAAM,MAAM,QAAQ,SAAS,KAAK;AAClC,SAAOD,MAAK,OAAO,GAAG,aAAa,GAAG,EAAE;AAC1C;AAIO,SAAS,eAA8B;AAC5C,QAAM,YAAY,gBAAgB;AAElC,MAAI,CAACJ,YAAW,SAAS,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,OAAO,SAAS,SAAS;AAC/B,UAAM,MAAM,KAAK,IAAI,IAAI,KAAK;AAE9B,QAAI,MAAM,kBAAkB;AAE1B,MAAAG,YAAW,SAAS;AACpB,aAAO;AAAA,IACT;AAEA,UAAM,UAAUF,cAAa,WAAW,OAAO,EAAE,KAAK;AACtD,WAAO,WAAW;AAAA,EACpB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aAAa,KAAmB;AAC9C,QAAM,YAAY,gBAAgB;AAElC,MAAI;AACF,IAAAC,eAAc,WAAW,KAAK,EAAE,MAAM,IAAM,CAAC;AAAA,EAC/C,QAAQ;AAAA,EAER;AACF;AAsBA,eAAsB,mBAAoC;AACxD,QAAM,SAAmB,CAAC;AAE1B,mBAAiB,SAAS,QAAQ,OAAO;AACvC,WAAO,KAAK,KAAK;AAEjB,UAAMI,WAAU,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AACtD,QAAIA,SAAQ,SAAS,IAAI,GAAG;AAC1B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AACtD,QAAM,YAAY,QAAQ,MAAM,IAAI,EAAE,CAAC,GAAG,KAAK,KAAK;AAEpD,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AAEA,SAAO;AACT;AAMA,eAAsB,aACpB,WACA,MACA,cAAsB,kBACE;AACxB,MAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,WAAO;AAAA,EACT;AAGA,MAAI,WAAW;AACb,YAAQ,MAAMC,IAAG,OAAO,WAAI,IAAI,UAAU,SAAS,qBAAqB;AAAA,EAC1E,OAAO;AACL,YAAQ,MAAMA,IAAG,OAAO,WAAI,IAAI,iCAAiC;AAAA,EACnE;AAEA,MAAI,MAAM;AACR,YAAQ,MAAMA,IAAG,IAAI,SAAS,IAAI,EAAE,CAAC;AAAA,EACvC;AAEA,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,UAAM,MAAM,MAAM;AAAA,MAChB,UAAU,IAAI,cAAc,OAAO,IAAI,WAAW,QAAQ;AAAA,IAC5D;AAEA,QAAI,KAAK;AACP,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,aAAa;AACzB,cAAQ,MAAMA,IAAG,IAAI,kCAAkC,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,UAAQ,MAAMA,IAAG,IAAI,oBAAoB,CAAC;AAC1C,SAAO;AACT;AAKA,eAAe,cAAc,QAAiC;AAC5D,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,KAAKC,iBAAgB;AAAA,MACzB,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,MAChB,UAAU;AAAA,IACZ,CAAC;AAGD,QAAI,QAAQ,MAAM,OAAO;AACvB,cAAQ,MAAM,aAAa,IAAI;AAAA,IACjC;AAEA,YAAQ,OAAO,MAAM,MAAM;AAE3B,QAAI,MAAM;AAEV,UAAM,aAAa,CAAC,QAAgB;AAClC,YAAM,OAAO,IAAI,SAAS;AAE1B,UAAI,SAAS,QAAQ,SAAS,MAAM;AAElC,gBAAQ,OAAO,MAAM,IAAI;AACzB,gBAAQ;AACR,gBAAQ,GAAG;AAAA,MACb,WAAW,SAAS,KAAU;AAE5B,gBAAQ,OAAO,MAAM,IAAI;AACzB,gBAAQ;AACR,gBAAQ,KAAK,GAAG;AAAA,MAClB,WAAW,SAAS,UAAY,SAAS,MAAM;AAE7C,YAAI,IAAI,SAAS,GAAG;AAClB,gBAAM,IAAI,MAAM,GAAG,EAAE;AAErB,kBAAQ,OAAO,MAAM,OAAO;AAAA,QAC9B;AAAA,MACF,WAAW,KAAK,WAAW,KAAK,QAAQ,KAAK;AAE3C,eAAO;AACP,gBAAQ,OAAO,MAAM,GAAG;AAAA,MAC1B;AAAA,IACF;AAEA,UAAM,UAAU,MAAM;AACpB,cAAQ,MAAM,eAAe,QAAQ,UAAU;AAC/C,UAAI,QAAQ,MAAM,OAAO;AACvB,gBAAQ,MAAM,aAAa,KAAK;AAAA,MAClC;AACA,SAAG,MAAM;AAAA,IACX;AAEA,YAAQ,MAAM,GAAG,QAAQ,UAAU;AAAA,EACrC,CAAC;AACH;AAaA,eAAsB,WAAW,SAON;AACzB,QAAM,EAAE,QAAQ,cAAc,WAAW,MAAM,WAAW,WAAW,IAAI;AAGzE,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAGA,MAAI,cAAc;AAChB,QAAI;AACF,aAAO,MAAM,iBAAiB;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,WAAW;AACd,UAAM,SAAS,aAAa;AAC5B,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI,CAAC,cAAc,QAAQ,MAAM,OAAO;AACtC,UAAM,MAAM,MAAM,aAAa,WAAW,IAAI;AAC9C,QAAI,KAAK;AAEP,mBAAa,GAAG;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AAGA,SAAO;AACT;;;ATnPA,eAAe,aAAa,YAA0D;AAEpF,QAAM,MAAM,MAAM,WAAW;AAAA,IAC3B,QAAQ,WAAW;AAAA,IACnB,cAAc,WAAW;AAAA,IACzB,YAAY;AAAA;AAAA,EACd,CAAC;AAED,SAAO;AAAA,IACL,MAAO,WAAW,QAAoB;AAAA,IACtC,SAAU,WAAW,WAAuB;AAAA,IAC5C,OAAQ,WAAW,SAAqB;AAAA,IACxC,KAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,eAAe,IAAIC,SAAQ,OAAO,EAC5C,YAAY,uBAAuB,EACnC,OAAO,eAAe,gCAAgC,EACtD,OAAO,cAAc,qBAAqB,EAC1C,OAAO,YAAY,wBAAwB,EAC3C,OAAO,aAAa,oBAAoB,EACxC,OAAO,oBAAoB,uBAAuB,EAClD,OAAO,eAAe,2BAA2B,IAAI,EACrD,OAAO,OAAO,SAAS,QAAQ;AAC9B,QAAM,aAAa,IAAI,QAAQ,KAAK,KAAK,CAAC;AAC1C,QAAM,MAAM,MAAM,aAAa,UAAU;AACzC,QAAM,gBAAgB,SAAS,GAAG;AACpC,CAAC,EACA;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUF;AAEF,aACG,QAAQ,KAAK,EACb,YAAY,oCAAoC,EAChD,SAAS,QAAQ,SAAS,EAC1B,OAAO,OAAO,IAAY,UAAU,QAAQ;AAC3C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAM,aAAa,UAAU;AACzC,QAAM,cAAc,IAAI,GAAG;AAC7B,CAAC;AAEH,aACG,QAAQ,QAAQ,EAChB,YAAY,mBAAmB,EAC/B,SAAS,WAAW,YAAY,EAChC,OAAO,oBAAoB,mBAAmB,EAC9C,OAAO,uBAAuB,yBAAyB,EACvD,OAAO,OAAO,OAAe,SAAS,QAAQ;AAC7C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAM,aAAa,UAAU;AACzC,QAAM,iBAAiB,OAAO,SAAS,GAAG;AAC5C,CAAC;AAEH,aACG,QAAQ,SAAS,EACjB,YAAY,6BAA6B,EACzC,SAAS,QAAQ,SAAS,EAC1B,OAAO,UAAU,oBAAoB,EACrC,OAAO,OAAO,IAAY,SAAS,QAAQ;AAC1C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAM,aAAa,UAAU;AACzC,QAAM,kBAAkB,IAAI,SAAS,GAAG;AAC1C,CAAC;AAEH,aACG,QAAQ,KAAK,EACb,YAAY,qBAAqB,EACjC,SAAS,QAAQ,SAAS,EAC1B,OAAO,OAAO,IAAY,UAAU,QAAQ;AAC3C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAM,aAAa,UAAU;AACzC,QAAM,cAAc,IAAI,GAAG;AAC7B,CAAC;AAEH,aACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,SAAS,QAAQ,SAAS,EAC1B,OAAO,mBAAmB,WAAW,EACrC,OAAO,oBAAoB,8BAA8B,EACzD,OAAO,OAAO,IAAY,SAAS,QAAQ;AAC1C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAM,aAAa,UAAU;AACzC,QAAM,iBAAiB,IAAI,SAAS,GAAG;AACzC,CAAC;AAEH,aACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,SAAS,QAAQ,SAAS,EAC1B,OAAO,WAAW,mBAAmB,EACrC,OAAO,OAAO,IAAY,SAAS,QAAQ;AAC1C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAM,aAAa,UAAU;AACzC,QAAM,iBAAiB,IAAI,SAAS,GAAG;AACzC,CAAC;;;AUvHH,SAAS,WAAAC,gBAAe;;;ACSxB,eAAsB,kBACpB,QACA,SACA,KACe;AACf,MAAI;AACF,QAAI,QAAQ,KAAK;AAEf,YAAM,SAAS,MAAM;AAAA,QACnB,EAAE,SAAS,QAAQ,OAAO,IAAI;AAAA,QAC9B,EAAE,KAAK,IAAI,IAAI;AAAA,MACjB;AAEA,qBAAe,OAAO,UAAU,GAAG;AAAA,IACrC,OAAO;AAEL,YAAM,SAAS,MAAM,QAAyB,QAAQ,EAAE,KAAK,IAAI,IAAI,CAAC;AAEtE,UAAI,OAAO,gBAAgB;AACzB,sBAAc,OAAO,gBAAgB,GAAG;AAAA,MAC1C,OAAO;AACL,YAAI,CAAC,IAAI,MAAM;AACb,kBAAQ,MAAM,2BAA2B;AAAA,QAC3C;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACvCA,OAAOC,SAAQ;;;ACAf,SAAS,WAAW,kBAAkB;AAGtC,eAAsB,gBAAgB,MAA6B;AACjE,MAAI;AACF,UAAM,WAAW,MAAM,IAAI;AAAA,EAC7B,SAAS,OAAO;AAEd,QAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,MAAM,GAAG;AAC5D,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,IAAI,SAAS,6BAA6B;AAAA,EAClD;AACF;;;ADNA,eAAsB,kBACpB,QACA,SACA,KACe;AACf,MAAI;AACF,QAAI,UAA0B;AAE9B,QAAI,QAAQ,SAAS;AAEnB,YAAM,aAAa,SAAS,QAAQ,SAAS,EAAE;AAC/C,UAAI,MAAM,UAAU,GAAG;AACrB,cAAM,IAAI,SAAS,wBAAwB;AAAA,MAC7C;AAEA,YAAM,SAAS,MAAM;AAAA,QACnB,EAAE,SAAS,QAAQ,OAAO,IAAI;AAAA,QAC9B,EAAE,KAAK,IAAI,IAAI;AAAA,MACjB;AAEA,gBAAU,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,UAAU,KAAK;AAEnE,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,SAAS,WAAW,UAAU,YAAY;AAAA,MACtD;AAAA,IACF,OAAO;AAEL,YAAM,SAAS,MAAM,QAAyB,QAAQ,EAAE,KAAK,IAAI,IAAI,CAAC;AACtE,gBAAU,OAAO;AAAA,IACnB;AAEA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,SAAS,0BAA0B;AAAA,IAC/C;AAEA,QAAI;AACF,YAAM,gBAAgB,QAAQ,OAAO;AACrC,gBAAU,qBAAqB;AAG/B,UAAI,IAAI,MAAM;AACZ,gBAAQ,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,SAAS,QAAQ,QAAQ,CAAC,CAAC;AAAA,MACxE;AAAA,IACF,SAAS,gBAAgB;AAEvB,UAAI,CAAC,IAAI,MAAM;AACb,gBAAQ,MAAMC,IAAG,OAAO,8CAA8C,CAAC;AACvE,gBAAQ,MAAM,EAAE;AAAA,MAClB;AACA,cAAQ,IAAI,QAAQ,OAAO;AAAA,IAC7B;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;AExDA,eAAsB,iBACpB,QACA,SACA,KACe;AACf,MAAI;AACF,QAAI;AAGJ,QAAI,QAAQ,MAAM,OAAO;AACvB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAmB,CAAC;AAC1B,qBAAiB,SAAS,QAAQ,OAAO;AACvC,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,cAAU,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAGhD,QAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B,gBAAU,QAAQ,MAAM,GAAG,EAAE;AAAA,IAC/B;AAEA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,SAAS,wBAAwB;AAAA,IAC7C;AAEA,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE,SAAS;AAAA,QACT;AAAA,QACA,OAAO,QAAQ;AAAA,MACjB;AAAA,MACA,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,oBAAc,oBAAoB,OAAO,QAAQ,OAAO,IAAI,GAAG;AAAA,IACjE;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACtCA,eAAsB,oBACpB,WACA,SACA,KACe;AACf,MAAI;AAEF,QAAI;AAEJ,QAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,YAAM,SAAmB,CAAC;AAC1B,uBAAiB,SAAS,QAAQ,OAAO;AACvC,eAAO,KAAK,KAAK;AAAA,MACnB;AACA,gBAAU,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAGhD,UAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B,kBAAU,QAAQ,MAAM,GAAG,EAAE;AAAA,MAC/B;AAEA,UAAI,CAAC,SAAS;AACZ,kBAAU;AAAA,MACZ;AAAA,IACF;AAGA,QAAI,CAAC,WAAW,CAAC,QAAQ,OAAO;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAA6C,CAAC;AACpD,QAAI,QAAS,MAAK,UAAU;AAC5B,QAAI,QAAQ,MAAO,MAAK,QAAQ,QAAQ;AAExC,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,oBAAc,mBAAmB,GAAG;AAAA,IACtC;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACpEA,eAAsB,sBACpB,WACA,KACe;AACf,MAAI;AACF,UAAM,SAAS,MAAM,eAAuC,WAAW,EAAE,KAAK,IAAI,IAAI,CAAC;AAEvF,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,YAAM,SAAS,OAAO,QAAQ,WAAW,cAAc;AACvD,oBAAc,WAAW,MAAM,IAAI,GAAG;AAAA,IACxC;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ANXA,eAAeC,cAAa,YAA0D;AACpF,QAAM,MAAM,MAAM,WAAW;AAAA,IAC3B,QAAQ,WAAW;AAAA,IACnB,cAAc,WAAW;AAAA,IACzB,YAAY;AAAA,EACd,CAAC;AAED,SAAO;AAAA,IACL,MAAO,WAAW,QAAoB;AAAA,IACtC,SAAU,WAAW,WAAuB;AAAA,IAC5C,OAAQ,WAAW,SAAqB;AAAA,IACxC,KAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iBAAiB,IAAIC,SAAQ,SAAS,EAChD,YAAY,0CAA0C,EACtD,SAAS,aAAa,6BAA6B,EACnD,OAAO,SAAS,2BAA2B,EAC3C,OAAO,OAAO,QAA4B,SAAS,QAAQ;AAC1D,QAAM,aAAa,IAAI,QAAQ,KAAK,KAAK,CAAC;AAC1C,QAAM,MAAM,MAAMD,cAAa,UAAU;AAEzC,MAAI,QAAQ;AACV,UAAM,kBAAkB,QAAQ,SAAS,GAAG;AAAA,EAC9C,OAAO;AACL,QAAI,KAAK;AAAA,EACX;AACF,CAAC,EACA;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOF;AAEF,eACG,QAAQ,MAAM,EACd,YAAY,mCAAmC,EAC/C,SAAS,aAAa,SAAS,EAC/B,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,OAAO,QAAgB,SAAS,QAAQ;AAC9C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMA,cAAa,UAAU;AACzC,QAAM,kBAAkB,QAAQ,SAAS,GAAG;AAC9C,CAAC;AAEH,eACG,QAAQ,KAAK,EACb,YAAY,wCAAwC,EACpD,SAAS,aAAa,SAAS,EAC/B,OAAO,mBAAmB,eAAe,EACzC,OAAO,OAAO,QAAgB,SAAS,QAAQ;AAC9C,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMA,cAAa,UAAU;AACzC,QAAM,iBAAiB,QAAQ,SAAS,GAAG;AAC7C,CAAC;AAEH,eACG,QAAQ,QAAQ,EAChB,YAAY,yCAAyC,EACrD,SAAS,gBAAgB,YAAY,EACrC,OAAO,mBAAmB,mBAAmB,EAC7C,OAAO,OAAO,WAAmB,SAAS,QAAQ;AACjD,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMA,cAAa,UAAU;AACzC,QAAM,oBAAoB,WAAW,SAAS,GAAG;AACnD,CAAC;AAEH,eACG,QAAQ,UAAU,EAClB,YAAY,qCAAqC,EACjD,SAAS,gBAAgB,YAAY,EACrC,OAAO,OAAO,WAAmB,UAAU,QAAQ;AAClD,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMA,cAAa,UAAU;AACzC,QAAM,sBAAsB,WAAW,GAAG;AAC5C,CAAC;;;AO3FH,SAAS,WAAAE,gBAAe;;;ACSxB,eAAsB,eACpB,SACA,KACe;AACf,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB,EAAE,kBAAkB,QAAQ,mBAAmB,MAAM;AAAA,MACrD,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,eAAW,OAAO,MAAM,OAAO,WAAW,GAAG;AAAA,EAC/C,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;AClBA,eAAsB,gBACpB,QACA,QACA,KACe;AACf,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB,EAAE,SAAS,QAAQ,SAAS,OAAO;AAAA,MACnC,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL;AAAA,QACE,YAAY,MAAM,SAAS,MAAM,MAAM,OAAO,aAAa;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;ACtBA,eAAsB,gBACpB,YACA,WACA,KACe;AACf,MAAI;AAEF,QAAI,WAAW,SAAS,SAAS,GAAG;AAClC,YAAM,IAAI,SAAS,2CAA2C;AAAA,IAChE;AAEA,QAAI,WAAW,WAAW,GAAG;AAC3B,YAAM,IAAI,SAAS,qCAAqC;AAAA,IAC1D;AAEA,UAAM,SAAS,MAAM;AAAA,MACnB,EAAE,aAAa,YAAY,YAAY,UAAU;AAAA,MACjD,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,QAAI,IAAI,MAAM;AACZ,iBAAW,MAAM;AAAA,IACnB,OAAO;AACL,YAAM,aAAa,WAAW,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI;AAC5D;AAAA,QACE,UAAU,UAAU,UAAU,SAAS,MAAM,OAAO,aAAa;AAAA,QACjE;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;AH7BA,eAAeC,cAAa,YAA0D;AACpF,QAAM,MAAM,MAAM,WAAW;AAAA,IAC3B,QAAQ,WAAW;AAAA,IACnB,cAAc,WAAW;AAAA,IACzB,YAAY;AAAA,EACd,CAAC;AAED,SAAO;AAAA,IACL,MAAO,WAAW,QAAoB;AAAA,IACtC,SAAU,WAAW,WAAuB;AAAA,IAC5C,OAAQ,WAAW,SAAqB;AAAA,IACxC,KAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC1C,YAAY,sBAAsB,EAClC,OAAO,sBAAsB,kCAAkC,EAC/D,OAAO,OAAO,SAAS,QAAQ;AAC9B,QAAM,aAAa,IAAI,QAAQ,KAAK,KAAK,CAAC;AAC1C,QAAM,MAAM,MAAMD,cAAa,UAAU;AACzC,QAAM,eAAe,SAAS,GAAG;AACnC,CAAC,EACA;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMF;AAEF,YACG,QAAQ,QAAQ,EAChB,YAAY,+BAA+B,EAC3C,SAAS,aAAa,kBAAkB,EACxC,SAAS,aAAa,cAAc,EACpC,OAAO,OAAO,QAAgB,QAAgB,UAAU,QAAQ;AAC/D,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMA,cAAa,UAAU;AACzC,QAAM,gBAAgB,QAAQ,QAAQ,GAAG;AAC3C,CAAC;AAEH,YACG,QAAQ,OAAO,EACf,YAAY,8BAA8B,EAC1C,SAAS,oBAAoB,iCAAiC,EAC9D,eAAe,mBAAmB,0BAA0B,EAC5D,OAAO,OAAO,YAAsB,SAAS,QAAQ;AACpD,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMA,cAAa,UAAU;AACzC,QAAM,gBAAgB,YAAY,QAAQ,MAAM,GAAG;AACrD,CAAC;;;AI7DH,SAAS,WAAAE,gBAAe;AAaxB,eAAe,aACb,OACA,SACA,KACe;AACf,MAAI;AACF,QAAI,eAAe;AACnB,QAAI,kBAAkB;AAEtB,QAAI,QAAQ,WAAW;AACrB,qBAAe;AACf,wBAAkB;AAAA,IACpB,WAAW,QAAQ,cAAc;AAC/B,qBAAe;AACf,wBAAkB;AAAA,IACpB;AAEA,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,QAAQ,QAAQ,SAAS,QAAQ,OAAO,EAAE,IAAI;AAAA,MACvD;AAAA,MACA,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AAEA,wBAAoB,OAAO,OAAO,OAAO,OAAO,UAAU,GAAG;AAAA,EAC/D,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;AAEO,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC9C,YAAY,2BAA2B,EACvC,SAAS,WAAW,cAAc,EAClC,OAAO,gBAAgB,kCAAkC,EACzD,OAAO,mBAAmB,6BAA6B,EACvD,OAAO,eAAe,iBAAiB,IAAI,EAC3C,OAAO,OAAO,OAAe,SAAS,QAAQ;AAC7C,QAAM,aAAa,IAAI,QAAQ,KAAK,KAAK,CAAC;AAC1C,QAAM,MAAM,MAAM,WAAW;AAAA,IAC3B,QAAQ,WAAW;AAAA,IACnB,cAAc,WAAW;AAAA,IACzB,YAAY;AAAA,EACd,CAAC;AACD,QAAM,MAAkB;AAAA,IACtB,MAAO,WAAW,QAAoB;AAAA,IACtC,SAAU,WAAW,WAAuB;AAAA,IAC5C,OAAQ,WAAW,SAAqB;AAAA,IACxC,KAAK,OAAO;AAAA,EACd;AACA,QAAM,aAAa,OAAO,SAAS,GAAG;AACxC,CAAC,EACA;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMF;;;AC3EF,SAAS,WAAAC,gBAAe;;;ACaxB,eAAsB,qBAAqB,KAAgC;AACzE,MAAI;AACF,UAAM,SAAS,MAAM,eAAuC,EAAE,KAAK,IAAI,IAAI,CAAC;AAC5E,qBAAiB,QAAQ,GAAG;AAAA,EAC9B,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;AAEA,eAAsB,wBACpB,IACA,SACA,KACe;AACf,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,EAAE,OAAO,QAAQ,QAAQ,SAAS,QAAQ,OAAO,EAAE,IAAI,OAAU;AAAA,MACjE,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AACA,yBAAqB,QAAQ,GAAG;AAAA,EAClC,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;AC5BA,eAAsB,sBACpB,SACA,KACe;AACf,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB,EAAE,iBAAiB,QAAQ,eAAe;AAAA,MAC1C,EAAE,KAAK,IAAI,IAAI;AAAA,IACjB;AACA,sBAAkB,QAAQ,GAAG;AAAA,EAC/B,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI,OAAO;AAAA,EAChC;AACF;;;AFfA,eAAeC,cAAa,YAA0D;AACpF,QAAM,MAAM,MAAM,WAAW;AAAA,IAC3B,QAAQ,WAAW;AAAA,IACnB,cAAc,WAAW;AAAA,IACzB,YAAY;AAAA,EACd,CAAC;AAED,SAAO;AAAA,IACL,MAAO,WAAW,QAAoB;AAAA,IACtC,SAAU,WAAW,WAAuB;AAAA,IAC5C,OAAQ,WAAW,SAAqB;AAAA,IACxC,KAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,eAAe,IAAIC,SAAQ,OAAO,EAC5C,YAAY,wCAAwC,EACpD;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOF;AAGF,aACG,QAAQ,MAAM,EACd,YAAY,gDAAgD,EAC5D,SAAS,QAAQ,6BAA6B,EAC9C,OAAO,eAAe,sBAAsB,EAC5C,OAAO,OAAO,IAAwB,SAAS,QAAQ;AACtD,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMD,cAAa,UAAU;AAEzC,MAAI,IAAI;AACN,UAAM,wBAAwB,IAAI,SAAS,GAAG;AAAA,EAChD,OAAO;AACL,UAAM,qBAAqB,GAAG;AAAA,EAChC;AACF,CAAC;AAGH,aACG,QAAQ,OAAO,EACf,YAAY,wCAAwC,EACpD,OAAO,qBAAqB,6BAA6B,EACzD,OAAO,OAAO,SAAS,QAAQ;AAC9B,QAAM,aAAa,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAClD,QAAM,MAAM,MAAMA,cAAa,UAAU;AACzC,QAAM,sBAAsB,SAAS,GAAG;AAC1C,CAAC;;;A/BpDH,IAAM,UAAU,IAAIE,SAAQ;AAE5B,QACG,KAAK,OAAO,EACZ,YAAY,4BAA4B,EACxC,QAAQ,SAAS,iBAAiB,qBAAqB,EACvD,OAAO,UAAU,gCAAgC,EACjD,OAAO,cAAc,wBAAwB,EAC7C,OAAO,WAAW,yCAAyC,EAC3D,OAAO,mBAAmB,mCAAmC,EAC7D,OAAO,eAAe,uCAAuC,EAC7D,cAAc;AAAA,EACb,iBAAiB;AAAA,EACjB,aAAa;AACf,CAAC,EACA;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBF;AAGF,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,YAAY;AAC/B,QAAQ,WAAW,cAAc;AACjC,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,YAAY;AAG/B,QAAQ,GAAG,UAAU,MAAM;AACzB,UAAQ,MAAM,eAAe;AAC7B,UAAQ,KAAK,GAAG;AAClB,CAAC;AAED,QAAQ,GAAG,WAAW,MAAM;AAC1B,UAAQ,KAAK,CAAC;AAChB,CAAC;AAGD,QAAQ,OAAO,GAAG,SAAS,CAAC,QAAQ;AAClC,MAAI,IAAI,SAAS,SAAS;AACxB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM;AACR,CAAC;AAGD,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,UAAU;AAChD,QAAM,UAAU,QAAQ,KAAK,EAAE,WAAW,QAAQ,IAAI,aAAa;AACnE,cAAY,OAAO,OAAO;AAC5B,CAAC;","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"]}
|