pnote 0.1.2 → 0.2.0
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/dist/index.js +263 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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 Command8 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/lib/errors.ts
|
|
7
7
|
import pc from "picocolors";
|
|
@@ -105,12 +105,12 @@ function loadCredentials() {
|
|
|
105
105
|
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
|
-
const
|
|
109
|
-
if (!existsSync(
|
|
108
|
+
const path3 = getCredentialsPath();
|
|
109
|
+
if (!existsSync(path3)) {
|
|
110
110
|
return null;
|
|
111
111
|
}
|
|
112
112
|
try {
|
|
113
|
-
const content = readFileSync(
|
|
113
|
+
const content = readFileSync(path3, "utf-8");
|
|
114
114
|
return JSON.parse(content);
|
|
115
115
|
} catch {
|
|
116
116
|
return null;
|
|
@@ -118,14 +118,14 @@ function loadCredentials() {
|
|
|
118
118
|
}
|
|
119
119
|
function saveCredentials(credentials) {
|
|
120
120
|
const dir = ensureConfigDir();
|
|
121
|
-
const
|
|
122
|
-
writeFileSync(
|
|
123
|
-
chmodSync(
|
|
121
|
+
const path3 = join(dir, CREDENTIALS_FILE);
|
|
122
|
+
writeFileSync(path3, JSON.stringify(credentials, null, 2), "utf-8");
|
|
123
|
+
chmodSync(path3, 384);
|
|
124
124
|
}
|
|
125
125
|
function deleteCredentials() {
|
|
126
|
-
const
|
|
127
|
-
if (existsSync(
|
|
128
|
-
unlinkSync(
|
|
126
|
+
const path3 = getCredentialsPath();
|
|
127
|
+
if (existsSync(path3)) {
|
|
128
|
+
unlinkSync(path3);
|
|
129
129
|
return true;
|
|
130
130
|
}
|
|
131
131
|
return false;
|
|
@@ -142,12 +142,12 @@ function validateTokenFormat(token) {
|
|
|
142
142
|
}
|
|
143
143
|
var CONFIG_FILE = "config.json";
|
|
144
144
|
function loadConfig() {
|
|
145
|
-
const
|
|
146
|
-
if (!existsSync(
|
|
145
|
+
const path3 = join(getConfigDir(), CONFIG_FILE);
|
|
146
|
+
if (!existsSync(path3)) {
|
|
147
147
|
return {};
|
|
148
148
|
}
|
|
149
149
|
try {
|
|
150
|
-
const content = readFileSync(
|
|
150
|
+
const content = readFileSync(path3, "utf-8");
|
|
151
151
|
return JSON.parse(content);
|
|
152
152
|
} catch {
|
|
153
153
|
return {};
|
|
@@ -189,7 +189,7 @@ function getRestApiBase() {
|
|
|
189
189
|
const mcpEndpoint = getApiEndpoint();
|
|
190
190
|
return mcpEndpoint.replace(/\/mcp$/, "/v1");
|
|
191
191
|
}
|
|
192
|
-
async function callRestApi(method,
|
|
192
|
+
async function callRestApi(method, path3, body, options = {}) {
|
|
193
193
|
const token = getToken();
|
|
194
194
|
if (!token) {
|
|
195
195
|
throw new AuthError(
|
|
@@ -198,7 +198,7 @@ async function callRestApi(method, path, body, options = {}) {
|
|
|
198
198
|
);
|
|
199
199
|
}
|
|
200
200
|
const baseUrl = getRestApiBase();
|
|
201
|
-
const url = `${baseUrl}${
|
|
201
|
+
const url = `${baseUrl}${path3}`;
|
|
202
202
|
const headers = {
|
|
203
203
|
"Content-Type": "application/json",
|
|
204
204
|
Authorization: `Bearer ${token}`
|
|
@@ -256,6 +256,7 @@ async function listNotes(params = {}, options = {}) {
|
|
|
256
256
|
if (params.pinned !== void 0) query.set("pinned", String(params.pinned));
|
|
257
257
|
if (params.deleted !== void 0) query.set("deleted", String(params.deleted));
|
|
258
258
|
if (params.protected !== void 0) query.set("protected", String(params.protected));
|
|
259
|
+
if (params.note_type) query.set("note_type", params.note_type);
|
|
259
260
|
if (params.search) query.set("search", params.search);
|
|
260
261
|
if (params.limit) query.set("limit", String(params.limit));
|
|
261
262
|
if (params.offset) query.set("offset", String(params.offset));
|
|
@@ -940,10 +941,10 @@ async function confirm(message) {
|
|
|
940
941
|
input: process.stdin,
|
|
941
942
|
output: process.stdout
|
|
942
943
|
});
|
|
943
|
-
return new Promise((
|
|
944
|
+
return new Promise((resolve2) => {
|
|
944
945
|
rl.question(message + " [y/N] ", (answer) => {
|
|
945
946
|
rl.close();
|
|
946
|
-
|
|
947
|
+
resolve2(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
947
948
|
});
|
|
948
949
|
});
|
|
949
950
|
}
|
|
@@ -1080,7 +1081,7 @@ async function promptForPin(noteTitle, hint, maxAttempts = PIN_MAX_ATTEMPTS) {
|
|
|
1080
1081
|
return null;
|
|
1081
1082
|
}
|
|
1082
1083
|
async function readPinHidden(prompt) {
|
|
1083
|
-
return new Promise((
|
|
1084
|
+
return new Promise((resolve2) => {
|
|
1084
1085
|
const rl = createInterface2({
|
|
1085
1086
|
input: process.stdin,
|
|
1086
1087
|
output: process.stderr,
|
|
@@ -1096,7 +1097,7 @@ async function readPinHidden(prompt) {
|
|
|
1096
1097
|
if (char === "\r" || char === "\n") {
|
|
1097
1098
|
process.stderr.write("\n");
|
|
1098
1099
|
cleanup();
|
|
1099
|
-
|
|
1100
|
+
resolve2(pin);
|
|
1100
1101
|
} else if (char === "") {
|
|
1101
1102
|
process.stderr.write("\n");
|
|
1102
1103
|
cleanup();
|
|
@@ -1685,8 +1686,249 @@ shareCommand.command("notes").description("List public share links for your note
|
|
|
1685
1686
|
await listSharedNotesAction(options, ctx);
|
|
1686
1687
|
});
|
|
1687
1688
|
|
|
1689
|
+
// src/commands/skills/index.ts
|
|
1690
|
+
import { Command as Command7 } from "commander";
|
|
1691
|
+
|
|
1692
|
+
// src/commands/skills/list.ts
|
|
1693
|
+
import pc10 from "picocolors";
|
|
1694
|
+
async function listSkillsAction(ctx) {
|
|
1695
|
+
try {
|
|
1696
|
+
const result = await listNotes(
|
|
1697
|
+
{ note_type: "skill", limit: 200 },
|
|
1698
|
+
{ pin: ctx.pin }
|
|
1699
|
+
);
|
|
1700
|
+
const skills = result.notes;
|
|
1701
|
+
if (ctx.json) {
|
|
1702
|
+
const grouped2 = {};
|
|
1703
|
+
for (const note of skills) {
|
|
1704
|
+
const slashIdx = note.title.indexOf("/");
|
|
1705
|
+
const skillName = slashIdx > 0 ? note.title.slice(0, slashIdx) : note.title;
|
|
1706
|
+
if (!grouped2[skillName]) grouped2[skillName] = [];
|
|
1707
|
+
grouped2[skillName].push(note);
|
|
1708
|
+
}
|
|
1709
|
+
outputJson(grouped2);
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
if (skills.length === 0) {
|
|
1713
|
+
console.log(pc10.dim("No skills found. Create one with:"));
|
|
1714
|
+
console.log(pc10.dim(" pnote skills push ./my-skill"));
|
|
1715
|
+
return;
|
|
1716
|
+
}
|
|
1717
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
1718
|
+
for (const note of skills) {
|
|
1719
|
+
const slashIdx = note.title.indexOf("/");
|
|
1720
|
+
const skillName = slashIdx > 0 ? note.title.slice(0, slashIdx) : note.title;
|
|
1721
|
+
if (!grouped.has(skillName)) grouped.set(skillName, []);
|
|
1722
|
+
grouped.get(skillName).push(note);
|
|
1723
|
+
}
|
|
1724
|
+
console.log(pc10.bold(`Skills (${grouped.size})`));
|
|
1725
|
+
console.log("");
|
|
1726
|
+
for (const [name, files] of grouped) {
|
|
1727
|
+
const fileNames = files.map((f) => {
|
|
1728
|
+
const slashIdx = f.title.indexOf("/");
|
|
1729
|
+
return slashIdx > 0 ? f.title.slice(slashIdx + 1) : f.title;
|
|
1730
|
+
});
|
|
1731
|
+
console.log(
|
|
1732
|
+
" " + pc10.cyan(name) + pc10.dim(` (${files.length} file${files.length !== 1 ? "s" : ""})`) + " " + pc10.dim(fileNames.join(", "))
|
|
1733
|
+
);
|
|
1734
|
+
}
|
|
1735
|
+
console.log("");
|
|
1736
|
+
console.log(pc10.dim("Pull to local: pnote skills pull"));
|
|
1737
|
+
} catch (error) {
|
|
1738
|
+
handleError(error, ctx.noColor);
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// src/commands/skills/pull.ts
|
|
1743
|
+
import * as fs from "fs";
|
|
1744
|
+
import * as path from "path";
|
|
1745
|
+
import * as os from "os";
|
|
1746
|
+
import pc11 from "picocolors";
|
|
1747
|
+
async function pullSkillsAction(skillName, options, ctx) {
|
|
1748
|
+
try {
|
|
1749
|
+
const baseDir = options.dir || path.join(os.homedir(), ".claude", "skills");
|
|
1750
|
+
const result = await listNotes(
|
|
1751
|
+
{ note_type: "skill", limit: 200 },
|
|
1752
|
+
{ pin: ctx.pin }
|
|
1753
|
+
);
|
|
1754
|
+
let skills = result.notes;
|
|
1755
|
+
if (skillName) {
|
|
1756
|
+
skills = skills.filter((n) => {
|
|
1757
|
+
const prefix = n.title.split("/")[0];
|
|
1758
|
+
return prefix === skillName;
|
|
1759
|
+
});
|
|
1760
|
+
if (skills.length === 0) {
|
|
1761
|
+
console.error(pc11.red(`No skill found with name "${skillName}"`));
|
|
1762
|
+
process.exit(1);
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
if (skills.length === 0) {
|
|
1766
|
+
console.log(pc11.dim("No skills to pull."));
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
let pulled = 0;
|
|
1770
|
+
let skipped = 0;
|
|
1771
|
+
for (const note of skills) {
|
|
1772
|
+
const slashIdx = note.title.indexOf("/");
|
|
1773
|
+
if (slashIdx <= 0) {
|
|
1774
|
+
logStatus(`Skipping "${note.title}" (invalid title format, expected "name/file")`);
|
|
1775
|
+
skipped++;
|
|
1776
|
+
continue;
|
|
1777
|
+
}
|
|
1778
|
+
const skillDir = note.title.slice(0, slashIdx);
|
|
1779
|
+
const fileName = note.title.slice(slashIdx + 1);
|
|
1780
|
+
const filePath = path.join(baseDir, skillDir, fileName);
|
|
1781
|
+
const noteData = await getNote(note.id, { pin: ctx.pin });
|
|
1782
|
+
const content = noteData.latest_snippet?.content;
|
|
1783
|
+
if (!content) {
|
|
1784
|
+
logStatus(`Skipping "${note.title}" (no snippet content)`);
|
|
1785
|
+
skipped++;
|
|
1786
|
+
continue;
|
|
1787
|
+
}
|
|
1788
|
+
if (options.dryRun) {
|
|
1789
|
+
console.log(`${pc11.dim("would write")} ${filePath} ${pc11.dim(`(${content.length} chars)`)}`);
|
|
1790
|
+
pulled++;
|
|
1791
|
+
continue;
|
|
1792
|
+
}
|
|
1793
|
+
const dir = path.dirname(filePath);
|
|
1794
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
1795
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
1796
|
+
console.log(`${pc11.green("\u2713")} ${filePath}`);
|
|
1797
|
+
pulled++;
|
|
1798
|
+
}
|
|
1799
|
+
console.log("");
|
|
1800
|
+
if (options.dryRun) {
|
|
1801
|
+
console.log(pc11.dim(`Dry run: ${pulled} file(s) would be written, ${skipped} skipped`));
|
|
1802
|
+
} else {
|
|
1803
|
+
console.log(`Pulled ${pulled} file(s) to ${baseDir}` + (skipped > 0 ? `, ${skipped} skipped` : ""));
|
|
1804
|
+
}
|
|
1805
|
+
} catch (error) {
|
|
1806
|
+
handleError(error, ctx.noColor);
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
// src/commands/skills/push.ts
|
|
1811
|
+
import * as fs2 from "fs";
|
|
1812
|
+
import * as path2 from "path";
|
|
1813
|
+
import pc12 from "picocolors";
|
|
1814
|
+
async function pushSkillsAction(dir, options, ctx) {
|
|
1815
|
+
try {
|
|
1816
|
+
const resolvedDir = path2.resolve(dir);
|
|
1817
|
+
if (!fs2.existsSync(resolvedDir) || !fs2.statSync(resolvedDir).isDirectory()) {
|
|
1818
|
+
console.error(pc12.red(`Not a directory: ${resolvedDir}`));
|
|
1819
|
+
process.exit(1);
|
|
1820
|
+
}
|
|
1821
|
+
const skillMdPath = path2.join(resolvedDir, "SKILL.md");
|
|
1822
|
+
if (!fs2.existsSync(skillMdPath)) {
|
|
1823
|
+
console.error(pc12.red(`No SKILL.md found in ${resolvedDir}`));
|
|
1824
|
+
console.error(pc12.dim("A valid skill directory must contain a SKILL.md file."));
|
|
1825
|
+
process.exit(1);
|
|
1826
|
+
}
|
|
1827
|
+
const skillName = options.name || path2.basename(resolvedDir);
|
|
1828
|
+
const files = collectFiles(resolvedDir, resolvedDir);
|
|
1829
|
+
if (files.length === 0) {
|
|
1830
|
+
console.log(pc12.dim("No files to push."));
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1833
|
+
const existing = await listNotes(
|
|
1834
|
+
{ note_type: "skill", limit: 200 },
|
|
1835
|
+
{ pin: ctx.pin }
|
|
1836
|
+
);
|
|
1837
|
+
const existingMap = /* @__PURE__ */ new Map();
|
|
1838
|
+
for (const note of existing.notes) {
|
|
1839
|
+
existingMap.set(note.title, note.id);
|
|
1840
|
+
}
|
|
1841
|
+
let created = 0;
|
|
1842
|
+
let updated = 0;
|
|
1843
|
+
for (const relPath of files) {
|
|
1844
|
+
const noteTitle = `${skillName}/${relPath}`;
|
|
1845
|
+
const filePath = path2.join(resolvedDir, relPath);
|
|
1846
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
1847
|
+
const existingId = existingMap.get(noteTitle);
|
|
1848
|
+
if (existingId) {
|
|
1849
|
+
await createSnippet(
|
|
1850
|
+
{ note_id: existingId, content },
|
|
1851
|
+
{ pin: ctx.pin }
|
|
1852
|
+
);
|
|
1853
|
+
console.log(`${pc12.yellow("\u21BB")} ${noteTitle} ${pc12.dim("(new version)")}`);
|
|
1854
|
+
updated++;
|
|
1855
|
+
} else {
|
|
1856
|
+
await createNote(
|
|
1857
|
+
{ title: noteTitle, content, note_type: "skill" },
|
|
1858
|
+
{ pin: ctx.pin }
|
|
1859
|
+
);
|
|
1860
|
+
console.log(`${pc12.green("+")} ${noteTitle}`);
|
|
1861
|
+
created++;
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
console.log("");
|
|
1865
|
+
console.log(
|
|
1866
|
+
`Pushed ${pc12.bold(skillName)}: ` + (created > 0 ? `${created} created` : "") + (created > 0 && updated > 0 ? ", " : "") + (updated > 0 ? `${updated} updated` : "")
|
|
1867
|
+
);
|
|
1868
|
+
} catch (error) {
|
|
1869
|
+
handleError(error, ctx.noColor);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
function collectFiles(baseDir, currentDir) {
|
|
1873
|
+
const files = [];
|
|
1874
|
+
const entries = fs2.readdirSync(currentDir, { withFileTypes: true });
|
|
1875
|
+
for (const entry of entries) {
|
|
1876
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
1877
|
+
const fullPath = path2.join(currentDir, entry.name);
|
|
1878
|
+
const relPath = path2.relative(baseDir, fullPath);
|
|
1879
|
+
if (entry.isFile()) {
|
|
1880
|
+
files.push(relPath);
|
|
1881
|
+
} else if (entry.isDirectory()) {
|
|
1882
|
+
files.push(...collectFiles(baseDir, fullPath));
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
return files;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
// src/commands/skills/index.ts
|
|
1889
|
+
async function buildContext5(globalOpts) {
|
|
1890
|
+
const pin = await resolvePin({
|
|
1891
|
+
pinArg: globalOpts.pin,
|
|
1892
|
+
pinFromStdin: globalOpts.pinStdin,
|
|
1893
|
+
skipPrompt: true
|
|
1894
|
+
});
|
|
1895
|
+
return {
|
|
1896
|
+
json: globalOpts.json ?? false,
|
|
1897
|
+
noColor: globalOpts.noColor ?? false,
|
|
1898
|
+
plain: globalOpts.plain ?? false,
|
|
1899
|
+
pin: pin ?? void 0
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
var skillsCommand = new Command7("skills").description("Manage agent skills (sync between cloud and local)").action(async (_options, cmd) => {
|
|
1903
|
+
const globalOpts = cmd.parent?.opts() || {};
|
|
1904
|
+
const ctx = await buildContext5(globalOpts);
|
|
1905
|
+
await listSkillsAction(ctx);
|
|
1906
|
+
}).addHelpText(
|
|
1907
|
+
"after",
|
|
1908
|
+
`
|
|
1909
|
+
Examples:
|
|
1910
|
+
$ pnote skills List all skills in cloud
|
|
1911
|
+
$ pnote skills pull Download all skills to ~/.claude/skills/
|
|
1912
|
+
$ pnote skills pull myskill Download a specific skill
|
|
1913
|
+
$ pnote skills push ./my-skill Upload a local skill directory
|
|
1914
|
+
|
|
1915
|
+
Skills are notes with type "skill" and title format "skill-name/filename.md".
|
|
1916
|
+
They sync to ~/.claude/skills/<skill-name>/<filename> for use with Claude Code.
|
|
1917
|
+
`
|
|
1918
|
+
);
|
|
1919
|
+
skillsCommand.command("pull").description("Download skills from cloud to local (~/.claude/skills/)").argument("[skill-name]", "Specific skill to pull (pulls all if omitted)").option("--dir <path>", "Custom output directory (default: ~/.claude/skills)").option("--dry-run", "Show what would be downloaded without writing files").action(async (skillName, options, cmd) => {
|
|
1920
|
+
const globalOpts = cmd.parent?.parent?.opts() || {};
|
|
1921
|
+
const ctx = await buildContext5(globalOpts);
|
|
1922
|
+
await pullSkillsAction(skillName, options, ctx);
|
|
1923
|
+
});
|
|
1924
|
+
skillsCommand.command("push").description("Upload a local skill directory to cloud").argument("<dir>", "Path to skill directory (must contain SKILL.md)").option("--name <name>", "Override skill name (default: directory name)").action(async (dir, options, cmd) => {
|
|
1925
|
+
const globalOpts = cmd.parent?.parent?.opts() || {};
|
|
1926
|
+
const ctx = await buildContext5(globalOpts);
|
|
1927
|
+
await pushSkillsAction(dir, options, ctx);
|
|
1928
|
+
});
|
|
1929
|
+
|
|
1688
1930
|
// src/index.ts
|
|
1689
|
-
var program = new
|
|
1931
|
+
var program = new Command8();
|
|
1690
1932
|
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({
|
|
1691
1933
|
sortSubcommands: true,
|
|
1692
1934
|
sortOptions: true
|
|
@@ -1717,6 +1959,7 @@ program.addCommand(snippetCommand);
|
|
|
1717
1959
|
program.addCommand(tagsCommand);
|
|
1718
1960
|
program.addCommand(searchCommand);
|
|
1719
1961
|
program.addCommand(shareCommand);
|
|
1962
|
+
program.addCommand(skillsCommand);
|
|
1720
1963
|
process.on("SIGINT", () => {
|
|
1721
1964
|
console.error("\nInterrupted");
|
|
1722
1965
|
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/commands/notes/update.ts","../src/lib/pin.ts","../src/commands/snippet/index.ts","../src/commands/snippet/show.ts","../src/commands/snippet/copy.ts","../src/lib/clipboard.ts","../src/commands/snippet/add.ts","../src/commands/snippet/update.ts","../src/commands/snippet/favorite.ts","../src/commands/tags/index.ts","../src/commands/tags/list.ts","../src/commands/tags/rename.ts","../src/commands/tags/merge.ts","../src/commands/search.ts","../src/commands/share/index.ts","../src/commands/share/tags.ts","../src/commands/share/notes.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { handleError } from './lib/errors.js';\nimport { authCommand } from './commands/auth/index.js';\nimport { notesCommand } from './commands/notes/index.js';\nimport { snippetCommand } from './commands/snippet/index.js';\nimport { tagsCommand } from './commands/tags/index.js';\nimport { searchCommand } from './commands/search.js';\nimport { shareCommand } from './commands/share/index.js';\n\nconst program = new Command();\n\nprogram\n .name('pnote')\n .description('pnote - The PromptNote CLI')\n .version('0.1.0', '-V, --version', 'Show version number')\n .option('--json', 'Output as JSON (for scripting)')\n .option('--no-color', 'Disable colored output')\n .option('--plain', 'Force plain text output (no formatting)')\n .option('-p, --pin <pin>', 'PIN for accessing protected notes')\n .option('--pin-stdin', 'Read PIN from stdin (first line only)')\n .configureHelp({\n sortSubcommands: true,\n sortOptions: true,\n })\n .addHelpText(\n 'after',\n `\nPIN Protection:\n Protected notes require a PIN to access their content.\n You can provide the PIN in several ways:\n -p, --pin <pin> Pass PIN directly (visible in history)\n --pin-stdin Read PIN from stdin\n PNOTE_PIN Set as environment variable (recommended)\n\nExamples:\n $ pnote notes List all notes\n $ pnote notes --tag \"AI/art\" Filter notes by tag\n $ pnote notes get abc123 -p 1234 Get protected note with PIN\n $ export PNOTE_PIN=1234 && pnote notes\n $ pnote snippet copy abc123 Copy snippet to clipboard\n $ pnote search \"portrait\" Search notes and snippets\n\nDocumentation: https://promptnoteapp.com/docs\n`\n );\n\n// Add commands\nprogram.addCommand(authCommand);\nprogram.addCommand(notesCommand);\nprogram.addCommand(snippetCommand);\nprogram.addCommand(tagsCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(shareCommand);\n\n// Handle signals\nprocess.on('SIGINT', () => {\n console.error('\\nInterrupted');\n process.exit(130);\n});\n\nprocess.on('SIGTERM', () => {\n process.exit(0);\n});\n\n// Suppress broken pipe errors (when piping to head, etc.)\nprocess.stdout.on('error', (err) => {\n if (err.code === 'EPIPE') {\n process.exit(0);\n }\n throw err;\n});\n\n// Parse and run\nprogram.parseAsync(process.argv).catch((error) => {\n const noColor = program.opts().noColor ?? process.env.NO_COLOR !== undefined;\n handleError(error, noColor);\n});\n","import pc from 'picocolors';\n\n// Exit codes following Unix conventions\nexport const ExitCode = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n AUTH_ERROR: 2,\n NOT_FOUND: 3,\n NETWORK_ERROR: 4,\n} as const;\n\nexport type ExitCodeType = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport class CLIError extends Error {\n constructor(\n message: string,\n public exitCode: ExitCodeType = ExitCode.GENERAL_ERROR,\n public hint?: string\n ) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\nexport class AuthError extends CLIError {\n constructor(message: string, hint?: string) {\n super(message, ExitCode.AUTH_ERROR, hint);\n this.name = 'AuthError';\n }\n}\n\nexport class NotFoundError extends CLIError {\n constructor(resource: string, id: string) {\n super(`${resource} not found (id: ${id})`, ExitCode.NOT_FOUND);\n this.name = 'NotFoundError';\n }\n}\n\nexport class NetworkError extends CLIError {\n constructor(message: string = 'Network error. Check your connection.') {\n super(message, ExitCode.NETWORK_ERROR);\n this.name = 'NetworkError';\n }\n}\n\n// Error formatting for stderr\n\nexport function formatError(error: unknown, noColor: boolean = false): string {\n const red = noColor ? (s: string) => s : pc.red;\n const dim = noColor ? (s: string) => s : pc.dim;\n\n if (error instanceof CLIError) {\n let message = `${red('Error:')} ${error.message}`;\n if (error.hint) {\n message += `\\n${dim('Hint:')} ${error.hint}`;\n }\n return message;\n }\n\n if (error instanceof Error) {\n return `${red('Error:')} ${error.message}`;\n }\n\n return `${red('Error:')} ${String(error)}`;\n}\n\n// Handle errors and exit\n\nexport function handleError(error: unknown, noColor: boolean = false): never {\n console.error(formatError(error, noColor));\n\n if (error instanceof CLIError) {\n process.exit(error.exitCode);\n }\n\n process.exit(ExitCode.GENERAL_ERROR);\n}\n\n// Parse API errors\n\nexport function parseApiError(statusCode: number, body: string): CLIError {\n try {\n const parsed = JSON.parse(body);\n const message = parsed.error?.message || parsed.message || body;\n\n switch (statusCode) {\n case 401:\n return new AuthError(\n message.includes('Unauthorized') ? 'Not logged in or invalid token' : message,\n \"Run 'pnote auth login' to authenticate\"\n );\n case 403:\n return new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n case 404:\n return new CLIError('Resource not found', ExitCode.NOT_FOUND);\n default:\n return new CLIError(message);\n }\n } catch {\n return new CLIError(`HTTP ${statusCode}: ${body}`);\n }\n}\n","import { Command } from 'commander';\nimport { loginAction } from './login.js';\nimport { tokenAction } from './token.js';\nimport { logoutAction } from './logout.js';\nimport { whoamiAction } from './whoami.js';\n\nexport const authCommand = new Command('auth')\n .description('Manage authentication')\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote auth login Open browser to login\n $ pnote auth token pn_xxx Set token directly\n $ pnote auth whoami Show current user\n $ pnote auth logout Remove credentials\n`\n );\n\nauthCommand\n .command('login')\n .description('Login to PromptNote (opens browser)')\n .action(loginAction);\n\nauthCommand\n .command('token')\n .description('Set API token directly')\n .argument('<token>', 'Personal Access Token (pn_xxx)')\n .action(tokenAction);\n\nauthCommand\n .command('logout')\n .description('Remove stored credentials')\n .action(logoutAction);\n\nauthCommand\n .command('whoami')\n .description('Show current authenticated user')\n .action(whoamiAction);\n","import pc from 'picocolors';\nimport { isLoggedIn, getCredentialsPath } from '../../lib/config.js';\n\nexport async function loginAction(): Promise<void> {\n if (isLoggedIn()) {\n console.log(pc.yellow('Already logged in.'));\n console.log(pc.dim(`Credentials stored at: ${getCredentialsPath()}`));\n console.log('');\n console.log(`Run ${pc.cyan(\"'pnote auth logout'\")} to logout first.`);\n return;\n }\n\n console.log(pc.bold('Login to PromptNote'));\n console.log('');\n console.log('To authenticate, you need a Personal Access Token (PAT).');\n console.log('');\n console.log(pc.dim('Steps:'));\n console.log(' 1. Open ' + pc.cyan('https://app.promptnoteapp.com'));\n console.log(' 2. Go to Settings > API Tokens');\n console.log(' 3. Generate a new token');\n console.log(' 4. Run: ' + pc.cyan(\"pnote auth token <your-token>\"));\n console.log('');\n console.log(pc.dim('Or set the PNOTE_TOKEN environment variable.'));\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { Credentials, Config } from '../types/index.js';\n\n// XDG Base Directory paths\nfunction getConfigDir(): string {\n const xdgConfig = process.env.XDG_CONFIG_HOME;\n if (xdgConfig) {\n return join(xdgConfig, 'pnote');\n }\n\n // macOS: also check ~/Library/Application Support\n const platform = process.platform;\n if (platform === 'darwin') {\n const macPath = join(homedir(), 'Library', 'Application Support', 'pnote');\n if (existsSync(macPath)) {\n return macPath;\n }\n }\n\n // Default to ~/.config/pnote\n return join(homedir(), '.config', 'pnote');\n}\n\nfunction ensureConfigDir(): string {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n return dir;\n}\n\n// Credentials management\n\nconst CREDENTIALS_FILE = 'credentials.json';\n\nexport function getCredentialsPath(): string {\n return join(getConfigDir(), CREDENTIALS_FILE);\n}\n\nexport function loadCredentials(): Credentials | null {\n // Priority 1: Environment variable\n const envToken = process.env.PNOTE_TOKEN;\n if (envToken) {\n return {\n token: envToken,\n created_at: new Date().toISOString(),\n };\n }\n\n // Priority 2: Credentials file\n const path = getCredentialsPath();\n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as Credentials;\n } catch {\n return null;\n }\n}\n\nexport function saveCredentials(credentials: Credentials): void {\n const dir = ensureConfigDir();\n const path = join(dir, CREDENTIALS_FILE);\n\n writeFileSync(path, JSON.stringify(credentials, null, 2), 'utf-8');\n\n // Set file permissions to 600 (owner read/write only)\n chmodSync(path, 0o600);\n}\n\nexport function deleteCredentials(): boolean {\n const path = getCredentialsPath();\n if (existsSync(path)) {\n unlinkSync(path);\n return true;\n }\n return false;\n}\n\n// Token utilities\n\nexport function getToken(): string | null {\n const creds = loadCredentials();\n return creds?.token ?? null;\n}\n\nexport function isLoggedIn(): boolean {\n return getToken() !== null;\n}\n\nexport function validateTokenFormat(token: string): boolean {\n // PAT format: pn_ + 32 characters\n return /^pn_[A-Za-z0-9_-]{20,50}$/.test(token);\n}\n\n// Config management (optional, for future use)\n\nconst CONFIG_FILE = 'config.json';\n\nexport function loadConfig(): Config {\n const path = join(getConfigDir(), CONFIG_FILE);\n if (!existsSync(path)) {\n return {};\n }\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as Config;\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(config: Config): void {\n const dir = ensureConfigDir();\n const path = join(dir, CONFIG_FILE);\n writeFileSync(path, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n// API Endpoint\n\nconst DEFAULT_API_ENDPOINT = 'https://tafnybfhwybgijozwfyq.supabase.co/functions/v1/promptnote-mcp/mcp';\n\nexport function getApiEndpoint(): string {\n const config = loadConfig();\n return config.api_endpoint ?? process.env.PNOTE_API_ENDPOINT ?? DEFAULT_API_ENDPOINT;\n}\n\n// PIN utilities\n\n/**\n * Get PIN from environment variable\n * Note: This is for display/status purposes only.\n * The MCP server reads PROMPTNOTE_PIN from its own environment configuration,\n * not from CLI requests. To access protected notes via MCP, users must configure\n * PROMPTNOTE_PIN in their MCP server config (e.g., claude_desktop_config.json).\n *\n * For CLI-specific operations, we use PNOTE_PIN to maintain consistency.\n */\nexport function getEnvPin(): string | null {\n return process.env.PNOTE_PIN ?? process.env.PROMPTNOTE_PIN ?? null;\n}\n","import pc from 'picocolors';\nimport { validateTokenFormat, saveCredentials, getCredentialsPath } from '../../lib/config.js';\nimport { verifyToken } from '../../lib/api.js';\nimport { CLIError, handleError } from '../../lib/errors.js';\n\nexport async function tokenAction(token: string): Promise<void> {\n // Validate token format\n if (!validateTokenFormat(token)) {\n throw new CLIError(\n 'Invalid token format',\n 1,\n \"Token should start with 'pn_' followed by 20-50 characters\"\n );\n }\n\n console.log(pc.dim('Verifying token...'));\n\n try {\n const result = await verifyToken(token);\n\n if (!result.valid) {\n throw new CLIError(\n 'Invalid token',\n 2,\n 'The token was rejected by the server. Please generate a new one.'\n );\n }\n\n // Save credentials\n saveCredentials({\n token,\n email: result.email,\n created_at: new Date().toISOString(),\n });\n\n console.log(pc.green('✓') + ' Token saved successfully!');\n console.log(pc.dim(`Credentials stored at: ${getCredentialsPath()}`));\n console.log('');\n console.log(`You can now use ${pc.cyan('pnote')} commands.`);\n } catch (error) {\n handleError(error);\n }\n}\n","import { getToken, getApiEndpoint } from './config.js';\nimport { AuthError, NetworkError, CLIError, ExitCode } from './errors.js';\n\n// REST API base URL (replace /mcp with /v1)\nfunction getRestApiBase(): string {\n const mcpEndpoint = getApiEndpoint();\n return mcpEndpoint.replace(/\\/mcp$/, '/v1');\n}\n\nexport interface RequestOptions {\n pin?: string;\n timeout?: number;\n}\n\n// Generic REST API call\nasync function callRestApi<T>(\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body?: Record<string, unknown>,\n options: RequestOptions = {}\n): Promise<T> {\n const token = getToken();\n if (!token) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' or 'pnote auth token <token>' to authenticate\"\n );\n }\n\n const baseUrl = getRestApiBase();\n const url = `${baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n };\n\n // Add PIN header if provided\n if (options.pin) {\n headers['X-PromptNote-PIN'] = options.pin;\n }\n\n let response: Response;\n try {\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(options.timeout ?? 30000),\n };\n\n if (body && (method === 'POST' || method === 'PATCH')) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n response = await fetch(url, fetchOptions);\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'TimeoutError' || error.name === 'AbortError') {\n throw new NetworkError('Request timed out. Please try again.');\n }\n if (error.message.includes('fetch')) {\n throw new NetworkError('Unable to connect to PromptNote API. Check your internet connection.');\n }\n }\n throw new NetworkError();\n }\n\n // Handle HTTP errors\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({})) as { message?: string };\n\n if (response.status === 401) {\n throw new AuthError(\n errorBody.message || 'Invalid or expired token',\n \"Run 'pnote auth login' to re-authenticate\"\n );\n }\n\n if (response.status === 403) {\n throw new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n }\n\n if (response.status === 404) {\n throw new CLIError(errorBody.message || 'Resource not found', ExitCode.NOT_FOUND);\n }\n\n if (response.status === 400) {\n throw new CLIError(errorBody.message || 'Invalid request', ExitCode.GENERAL_ERROR);\n }\n\n throw new CLIError(`API error (${response.status}): ${errorBody.message || 'Unknown error'}`);\n }\n\n return response.json() as Promise<T>;\n}\n\n// ============================================================\n// Notes API\n// ============================================================\n\nexport interface ListNotesParams {\n tag?: string;\n archived?: boolean;\n pinned?: boolean;\n deleted?: boolean;\n protected?: boolean;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport async function listNotes<T>(params: ListNotesParams = {}, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n if (params.tag) query.set('tag', params.tag);\n if (params.archived !== undefined) query.set('archived', String(params.archived));\n if (params.pinned !== undefined) query.set('pinned', String(params.pinned));\n if (params.deleted !== undefined) query.set('deleted', String(params.deleted));\n if (params.protected !== undefined) query.set('protected', String(params.protected));\n if (params.search) query.set('search', params.search);\n if (params.limit) query.set('limit', String(params.limit));\n if (params.offset) query.set('offset', String(params.offset));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function getNote<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', `/notes/${id}`, undefined, options);\n}\n\nexport async function createNote<T>(\n data: { title: string; tags?: string[]; content?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/notes', data, options);\n}\n\nexport async function updateNote<T>(\n id: string,\n data: { title?: string; tags?: string[]; archived?: boolean; pinned?: boolean },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('PATCH', `/notes/${id}`, data, options);\n}\n\nexport async function deleteNote<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('DELETE', `/notes/${id}`, undefined, options);\n}\n\n// ============================================================\n// Snippets API\n// ============================================================\n\nexport interface ListSnippetsParams {\n note_id: string;\n include_deleted?: boolean;\n limit?: number;\n}\n\nexport async function listSnippets<T>(params: ListSnippetsParams, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n query.set('note_id', params.note_id);\n if (params.include_deleted !== undefined) query.set('include_deleted', String(params.include_deleted));\n if (params.limit) query.set('limit', String(params.limit));\n\n return callRestApi<T>('GET', `/snippets?${query.toString()}`, undefined, options);\n}\n\nexport async function getSnippet<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', `/snippets/${id}`, undefined, options);\n}\n\nexport async function createSnippet<T>(\n data: { note_id: string; content: string; title?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/snippets', data, options);\n}\n\nexport async function updateSnippet<T>(\n id: string,\n data: { content?: string; title?: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('PATCH', `/snippets/${id}`, data, options);\n}\n\nexport async function toggleFavorite<T>(id: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('POST', `/snippets/${id}/favorite`, {}, options);\n}\n\n// ============================================================\n// Tags API\n// ============================================================\n\nexport interface ListTagsParams {\n include_archived?: boolean;\n}\n\nexport async function listTags<T>(params: ListTagsParams = {}, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n if (params.include_archived !== undefined) query.set('include_archived', String(params.include_archived));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/tags${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function renameTag<T>(\n data: { old_tag: string; new_tag: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/tags/rename', data, options);\n}\n\nexport async function mergeTags<T>(\n data: { source_tags: string[]; target_tag: string },\n options: RequestOptions = {}\n): Promise<T> {\n return callRestApi<T>('POST', '/tags/merge', data, options);\n}\n\n// ============================================================\n// Search API\n// ============================================================\n\nexport interface SearchParams {\n query: string;\n search_notes?: boolean;\n search_snippets?: boolean;\n limit?: number;\n}\n\nexport async function search<T>(params: SearchParams, options: RequestOptions = {}): Promise<T> {\n const query = new URLSearchParams();\n query.set('q', params.query);\n if (params.search_notes !== undefined) query.set('search_notes', String(params.search_notes));\n if (params.search_snippets !== undefined) query.set('search_snippets', String(params.search_snippets));\n if (params.limit) query.set('limit', String(params.limit));\n\n return callRestApi<T>('GET', `/search?${query.toString()}`, undefined, options);\n}\n\n// ============================================================\n// PIN API\n// ============================================================\n\nexport async function checkPinStatus<T>(options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', '/pin/status', undefined, options);\n}\n\nexport async function listProtectedNotes<T>(\n params: { limit?: number; offset?: number } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.limit) query.set('limit', String(params.limit));\n if (params.offset) query.set('offset', String(params.offset));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/pin/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function verifyPin<T>(pin: string, options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('POST', '/pin/verify', { pin }, options);\n}\n\n// ============================================================\n// Sharing API\n// ============================================================\n\nexport async function listSharedTags<T>(options: RequestOptions = {}): Promise<T> {\n return callRestApi<T>('GET', '/share/tags', undefined, options);\n}\n\nexport async function getSharedTagNotes<T>(\n id: string,\n params: { limit?: number } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.limit) query.set('limit', String(params.limit));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/share/tags/${id}/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\nexport async function listSharedNotes<T>(\n params: { include_revoked?: boolean } = {},\n options: RequestOptions = {}\n): Promise<T> {\n const query = new URLSearchParams();\n if (params.include_revoked !== undefined) query.set('include_revoked', String(params.include_revoked));\n\n const queryString = query.toString();\n return callRestApi<T>('GET', `/share/notes${queryString ? `?${queryString}` : ''}`, undefined, options);\n}\n\n// ============================================================\n// Legacy MCP API (for backward compatibility and token verification)\n// ============================================================\n\nimport type { MCPRequest, MCPResponse } from '../types/index.js';\n\nlet requestId = 0;\n\nfunction getNextId(): number {\n return ++requestId;\n}\n\n/**\n * @deprecated Use REST API functions instead (listNotes, getNote, etc.)\n */\nexport async function callMCP<T>(\n toolName: string,\n args: Record<string, unknown> = {}\n): Promise<T> {\n const token = getToken();\n if (!token) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' or 'pnote auth token <token>' to authenticate\"\n );\n }\n\n const endpoint = getApiEndpoint();\n\n const request: MCPRequest = {\n jsonrpc: '2.0',\n id: getNextId(),\n method: 'tools/call',\n params: {\n name: toolName,\n arguments: args,\n },\n };\n\n let response: Response;\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(30000),\n });\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'TimeoutError' || error.name === 'AbortError') {\n throw new NetworkError('Request timed out. Please try again.');\n }\n if (error.message.includes('fetch')) {\n throw new NetworkError('Unable to connect to PromptNote API. Check your internet connection.');\n }\n }\n throw new NetworkError();\n }\n\n if (!response.ok) {\n const body = await response.text();\n\n if (response.status === 401) {\n throw new AuthError(\n 'Invalid or expired token',\n \"Run 'pnote auth login' to re-authenticate\"\n );\n }\n\n if (response.status === 403) {\n throw new CLIError('Permission denied', ExitCode.AUTH_ERROR);\n }\n\n throw new CLIError(`API error (${response.status}): ${body}`);\n }\n\n const mcpResponse = (await response.json()) as MCPResponse;\n\n if (mcpResponse.error) {\n throw new CLIError(`MCP error: ${mcpResponse.error.message}`);\n }\n\n if (!mcpResponse.result) {\n throw new CLIError('Invalid response from API');\n }\n\n const content = mcpResponse.result.content;\n if (!content || content.length === 0) {\n throw new CLIError('Empty response from API');\n }\n\n if (mcpResponse.result.isError) {\n const errorText = content[0]?.text || 'Unknown error';\n\n if (errorText.includes('not found') || errorText.includes('PGRST116')) {\n throw new CLIError('Resource not found', ExitCode.NOT_FOUND);\n }\n if (errorText.includes('Unauthorized')) {\n throw new AuthError(errorText);\n }\n\n throw new CLIError(errorText);\n }\n\n const textContent = content[0]?.text;\n if (!textContent) {\n throw new CLIError('No content in response');\n }\n\n try {\n return JSON.parse(textContent) as T;\n } catch {\n return textContent as T;\n }\n}\n\n// Verify token is valid by making a simple API call (using REST API)\nexport async function verifyToken(token: string): Promise<{ valid: boolean; email?: string }> {\n const baseUrl = getApiEndpoint().replace(/\\/mcp$/, '/v1');\n\n try {\n const response = await fetch(`${baseUrl}/notes?limit=1`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n signal: AbortSignal.timeout(10000),\n });\n\n if (response.status === 401) {\n return { valid: false };\n }\n\n if (!response.ok) {\n return { valid: false };\n }\n\n return { valid: true };\n } catch {\n throw new NetworkError('Unable to verify token. Check your internet connection.');\n }\n}\n","import pc from 'picocolors';\nimport { deleteCredentials, isLoggedIn } from '../../lib/config.js';\n\nexport async function logoutAction(): Promise<void> {\n if (!isLoggedIn()) {\n console.log(pc.dim('Not logged in.'));\n return;\n }\n\n const deleted = deleteCredentials();\n\n if (deleted) {\n console.log(pc.green('✓') + ' Logged out successfully.');\n } else {\n console.log(pc.dim('No credentials to remove.'));\n }\n\n // Remind about environment variable\n if (process.env.PNOTE_TOKEN) {\n console.log('');\n console.log(\n pc.yellow('Note:') +\n ' PNOTE_TOKEN environment variable is still set.'\n );\n console.log(pc.dim('Unset it with: unset PNOTE_TOKEN'));\n }\n}\n","import pc from 'picocolors';\nimport { loadCredentials, isLoggedIn, getCredentialsPath } from '../../lib/config.js';\nimport { listNotes } from '../../lib/api.js';\nimport { handleError, AuthError } from '../../lib/errors.js';\nimport type { ListNotesResponse } from '../../types/index.js';\n\nexport async function whoamiAction(): Promise<void> {\n if (!isLoggedIn()) {\n throw new AuthError(\n 'Not logged in',\n \"Run 'pnote auth login' to authenticate\"\n );\n }\n\n const creds = loadCredentials();\n if (!creds) {\n throw new AuthError('No credentials found');\n }\n\n try {\n // Verify token is still valid by making a simple API call\n const result = await listNotes<ListNotesResponse>({ limit: 1 });\n\n console.log(pc.green('✓') + ' Authenticated');\n console.log('');\n\n if (creds.email) {\n console.log(pc.dim('Email: ') + creds.email);\n }\n\n console.log(pc.dim('Token: ') + creds.token.slice(0, 7) + '...' + creds.token.slice(-4));\n console.log(pc.dim('Stored: ') + getCredentialsPath());\n\n if (process.env.PNOTE_TOKEN) {\n console.log(pc.dim('Source: ') + 'PNOTE_TOKEN environment variable');\n } else {\n console.log(pc.dim('Source: ') + 'credentials file');\n }\n\n console.log('');\n console.log(pc.dim(`Total notes: ${result.count}`));\n } catch (error) {\n handleError(error);\n }\n}\n","import { Command } from 'commander';\nimport { listNotesAction } from './list.js';\nimport { getNoteAction } from './get.js';\nimport { createNoteAction } from './create.js';\nimport { archiveNoteAction } from './archive.js';\nimport { pinNoteAction } from './pin.js';\nimport { deleteNoteAction } from './delete.js';\nimport { updateNoteAction } from './update.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n // Resolve PIN from various sources\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true, // Don't prompt interactively for list/search operations\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const notesCommand = new Command('notes')\n .description('List and manage notes')\n .option('--tag <tag>', 'Filter by tag (e.g., \"AI/art\")')\n .option('--archived', 'Show archived notes')\n .option('--pinned', 'Show only pinned notes')\n .option('--deleted', 'Show deleted notes')\n .option('--search <query>', 'Search notes by title')\n .option('--limit <n>', 'Limit number of results', '50')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listNotesAction(options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote notes List all active notes\n $ pnote notes --tag \"AI/art\" Filter by tag\n $ pnote notes --archived Show archived notes\n $ pnote notes --pinned Show only pinned notes\n $ pnote notes get abc123 Get note details\n $ pnote notes create \"My Note\" Create a new note\n $ pnote notes update abc123 --title \"New Title\"\n`\n );\n\nnotesCommand\n .command('get')\n .description('Get a note with its latest snippet')\n .argument('<id>', 'Note ID')\n .action(async (id: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await getNoteAction(id, ctx);\n });\n\nnotesCommand\n .command('create')\n .description('Create a new note')\n .argument('<title>', 'Note title')\n .option('--tags <tags...>', 'Tags for the note')\n .option('--content <content>', 'Initial snippet content')\n .action(async (title: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await createNoteAction(title, options, ctx);\n });\n\nnotesCommand\n .command('archive')\n .description('Archive or unarchive a note')\n .argument('<id>', 'Note ID')\n .option('--undo', 'Unarchive the note')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await archiveNoteAction(id, options, ctx);\n });\n\nnotesCommand\n .command('pin')\n .description('Pin or unpin a note')\n .argument('<id>', 'Note ID')\n .action(async (id: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await pinNoteAction(id, ctx);\n });\n\nnotesCommand\n .command('update')\n .description('Update a note title or tags')\n .argument('<id>', 'Note ID')\n .option('--title <title>', 'New title')\n .option('--tags <tags...>', 'New tags (replaces existing)')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await updateNoteAction(id, options, ctx);\n });\n\nnotesCommand\n .command('delete')\n .description('Delete a note (soft delete)')\n .argument('<id>', 'Note ID')\n .option('--force', 'Skip confirmation')\n .action(async (id: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await deleteNoteAction(id, options, ctx);\n });\n","import pc from 'picocolors';\nimport type {\n CLIContext, Note, Snippet, Tag, TagHierarchy,\n ListSharedTagsResponse, GetSharedTagNotesResponse, ListSharedNotesResponse,\n} from '../types/index.js';\n\n// Check if output should use colors\nfunction shouldUseColor(ctx: CLIContext): boolean {\n if (ctx.noColor) return false;\n if (process.env.NO_COLOR) return false;\n if (process.env.TERM === 'dumb') return false;\n return process.stdout.isTTY ?? false;\n}\n\n// Check if output should be formatted for humans\nfunction isHumanOutput(ctx: CLIContext): boolean {\n if (ctx.json) return false;\n if (ctx.plain) return false;\n return process.stdout.isTTY ?? false;\n}\n\n// Color helpers\nfunction getColors(ctx: CLIContext) {\n const useColor = shouldUseColor(ctx);\n return {\n dim: useColor ? pc.dim : (s: string) => s,\n bold: useColor ? pc.bold : (s: string) => s,\n green: useColor ? pc.green : (s: string) => s,\n yellow: useColor ? pc.yellow : (s: string) => s,\n blue: useColor ? pc.blue : (s: string) => s,\n cyan: useColor ? pc.cyan : (s: string) => s,\n red: useColor ? pc.red : (s: string) => s,\n magenta: useColor ? pc.magenta : (s: string) => s,\n };\n}\n\n// Format relative time\nfunction formatRelativeTime(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffSecs = Math.floor(diffMs / 1000);\n const diffMins = Math.floor(diffSecs / 60);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffDays > 30) {\n return date.toLocaleDateString();\n }\n if (diffDays > 0) {\n return `${diffDays}d ago`;\n }\n if (diffHours > 0) {\n return `${diffHours}h ago`;\n }\n if (diffMins > 0) {\n return `${diffMins}m ago`;\n }\n return 'just now';\n}\n\n// Truncate string with ellipsis\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen - 1) + '…';\n}\n\n// Pad string to fixed width\nfunction pad(str: string, width: number): string {\n if (str.length >= width) return str.slice(0, width);\n return str + ' '.repeat(width - str.length);\n}\n\n// Output JSON to stdout\nexport function outputJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\n// Output notes list\nexport function outputNotes(notes: Note[], ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(notes);\n return;\n }\n\n if (notes.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No notes found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n // Table header\n console.log(\n c.dim(pad('ID', 12)) +\n ' ' +\n c.dim(pad('TITLE', 30)) +\n ' ' +\n c.dim(pad('TAGS', 20)) +\n ' ' +\n c.dim('UPDATED')\n );\n\n for (const note of notes) {\n const id = truncate(note.id.slice(0, 8), 12);\n const title = truncate(note.title || '(untitled)', 30);\n const tags = truncate(note.tags.join(', ') || '-', 20);\n const updated = formatRelativeTime(note.updated_at);\n\n let line = pad(id, 12) + ' ' + pad(title, 30) + ' ' + pad(tags, 20) + ' ' + updated;\n\n // Add indicators\n const indicators: string[] = [];\n if (note.pinned) indicators.push(c.yellow('*'));\n if (note.archived) indicators.push(c.dim('[A]'));\n if (note.is_protected) indicators.push(c.magenta('[P]'));\n\n if (indicators.length > 0) {\n line = indicators.join('') + ' ' + line;\n }\n\n console.log(line);\n }\n } else {\n // Plain output - one note per line, tab-separated\n for (const note of notes) {\n console.log(\n [note.id, note.title, note.tags.join(','), note.updated_at].join('\\t')\n );\n }\n }\n}\n\n// Output single note\nexport function outputNote(note: Note, snippet: Snippet | null, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ ...note, latest_snippet: snippet });\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n console.log(c.bold(note.title || '(untitled)'));\n console.log(c.dim('ID: ') + note.id);\n console.log(c.dim('Tags: ') + (note.tags.length > 0 ? note.tags.join(', ') : '-'));\n console.log(c.dim('Created: ') + new Date(note.created_at).toLocaleString());\n console.log(c.dim('Updated: ') + new Date(note.updated_at).toLocaleString());\n\n const status: string[] = [];\n if (note.pinned) status.push(c.yellow('pinned'));\n if (note.archived) status.push(c.dim('archived'));\n if (note.is_protected) status.push(c.magenta('protected'));\n if (status.length > 0) {\n console.log(c.dim('Status: ') + status.join(', '));\n }\n\n if (snippet) {\n console.log('');\n console.log(c.dim(`--- Snippet v${snippet.version} ---`));\n console.log(snippet.content);\n } else {\n console.log('');\n console.log(c.dim('(no content)'));\n }\n } else {\n // Plain output\n console.log(`Title: ${note.title}`);\n console.log(`ID: ${note.id}`);\n console.log(`Tags: ${note.tags.join(', ')}`);\n if (snippet) {\n console.log('');\n console.log(snippet.content);\n }\n }\n}\n\n// Output snippet content\nexport function outputSnippet(snippet: Snippet, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(snippet);\n return;\n }\n\n // For snippet, just output the content directly (useful for piping)\n console.log(snippet.content);\n}\n\n// Output snippets list\nexport function outputSnippets(snippets: Snippet[], ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(snippets);\n return;\n }\n\n if (snippets.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No snippets found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n for (const snippet of snippets) {\n const header = `v${snippet.version}` +\n (snippet.favorite ? c.yellow(' ★') : '') +\n c.dim(` (${formatRelativeTime(snippet.created_at)})`);\n\n console.log(c.bold(header));\n console.log(snippet.content);\n console.log('');\n }\n } else {\n for (const snippet of snippets) {\n console.log(`v${snippet.version}\\t${snippet.id}\\t${snippet.content.slice(0, 100)}`);\n }\n }\n}\n\n// Output tags tree\nexport function outputTags(tags: Tag[], hierarchy: TagHierarchy, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ tags, hierarchy });\n return;\n }\n\n if (tags.length === 0) {\n const c = getColors(ctx);\n console.log(c.dim('No tags found.'));\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n // Build tree structure\n const roots: string[] = [];\n const childrenMap: Map<string, string[]> = new Map();\n\n for (const tag of tags) {\n const parts = tag.tag.split('/');\n if (parts.length === 1) {\n roots.push(tag.tag);\n } else {\n const parent = parts.slice(0, -1).join('/');\n const children = childrenMap.get(parent) || [];\n children.push(tag.tag);\n childrenMap.set(parent, children);\n }\n }\n\n // Sort roots\n roots.sort();\n\n const tagCountMap = new Map(tags.map((t) => [t.tag, t.count]));\n\n function printTree(tagPath: string, prefix: string, isLast: boolean): void {\n const count = tagCountMap.get(tagPath) || 0;\n const name = tagPath.split('/').pop() || tagPath;\n const connector = isLast ? '└── ' : '├── ';\n\n console.log(prefix + connector + c.cyan(name) + c.dim(` (${count})`));\n\n const children = childrenMap.get(tagPath) || [];\n children.sort();\n\n const newPrefix = prefix + (isLast ? ' ' : '│ ');\n children.forEach((child, i) => {\n printTree(child, newPrefix, i === children.length - 1);\n });\n }\n\n roots.forEach((root, i) => {\n const count = tagCountMap.get(root) || 0;\n console.log(c.cyan(root) + c.dim(` (${count})`));\n\n const children = childrenMap.get(root) || [];\n children.sort();\n children.forEach((child, j) => {\n printTree(child, '', j === children.length - 1);\n });\n });\n } else {\n // Plain output\n for (const tag of tags) {\n console.log(`${tag.tag}\\t${tag.count}`);\n }\n }\n}\n\n// Output search results\nexport function outputSearchResults(\n query: string,\n notes: Note[],\n snippets: Array<{\n id: string;\n note_id: string;\n note_title: string;\n version: number;\n content_preview: string;\n favorite: boolean;\n }>,\n ctx: CLIContext\n): void {\n if (ctx.json) {\n outputJson({ query, notes, snippets });\n return;\n }\n\n const c = getColors(ctx);\n\n if (notes.length === 0 && snippets.length === 0) {\n console.log(c.dim(`No results for \"${query}\"`));\n return;\n }\n\n if (notes.length > 0) {\n console.log(c.bold(`Notes (${notes.length})`));\n console.log('');\n for (const note of notes) {\n console.log(\n ' ' + c.cyan(note.id.slice(0, 8)) + ' ' + note.title + ' ' + c.dim(note.tags.join(', '))\n );\n }\n console.log('');\n }\n\n if (snippets.length > 0) {\n console.log(c.bold(`Snippets (${snippets.length})`));\n console.log('');\n for (const snippet of snippets) {\n console.log(\n ' ' +\n c.cyan(snippet.note_id.slice(0, 8)) +\n ' ' +\n snippet.note_title +\n c.dim(` v${snippet.version}`)\n );\n console.log(' ' + c.dim(truncate(snippet.content_preview, 60)));\n }\n }\n}\n\n// Output shared tags list\nexport function outputSharedTags(data: ListSharedTagsResponse, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(data);\n return;\n }\n\n const c = getColors(ctx);\n const totalCount = data.owned.count + data.shared_with_me.count;\n\n if (totalCount === 0) {\n console.log(c.dim('No shared tags.'));\n return;\n }\n\n if (isHumanOutput(ctx)) {\n if (data.owned.count > 0) {\n console.log(c.bold(`Owned (${data.owned.count})`));\n console.log('');\n for (const tag of data.owned.tags) {\n console.log(\n ' ' + c.cyan(tag.id.slice(0, 8)) + ' ' +\n pad(tag.tag_path, 24) + ' ' +\n c.dim(formatRelativeTime(tag.created_at))\n );\n }\n console.log('');\n }\n\n if (data.shared_with_me.count > 0) {\n console.log(c.bold(`Shared with me (${data.shared_with_me.count})`));\n console.log('');\n for (const tag of data.shared_with_me.tags) {\n console.log(\n ' ' + c.cyan(tag.id.slice(0, 8)) + ' ' +\n pad(tag.tag_path, 24) + ' ' +\n c.dim('joined ' + formatRelativeTime(tag.joined_at))\n );\n }\n }\n } else {\n for (const tag of data.owned.tags) {\n console.log(['owned', tag.id, tag.tag_path, tag.created_at].join('\\t'));\n }\n for (const tag of data.shared_with_me.tags) {\n console.log(['shared', tag.id, tag.tag_path, tag.joined_at].join('\\t'));\n }\n }\n}\n\n// Output shared tag notes\nexport function outputSharedTagNotes(data: GetSharedTagNotesResponse, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(data);\n return;\n }\n\n const c = getColors(ctx);\n\n if (isHumanOutput(ctx)) {\n const role = data.shared_tag.is_owner ? 'owner' : 'member';\n console.log(c.bold(data.shared_tag.tag_path) + c.dim(` (${role}, ${data.members_count} members)`));\n console.log('');\n\n if (data.notes.length === 0) {\n console.log(c.dim(' No notes in this shared tag.'));\n return;\n }\n\n console.log(\n ' ' + c.dim(pad('ID', 10)) +\n ' ' + c.dim(pad('TITLE', 24)) +\n ' ' + c.dim(pad('AUTHOR', 20)) +\n ' ' + c.dim('UPDATED')\n );\n\n for (const note of data.notes) {\n const author = note.is_own ? 'you' : (note.author.email || 'unknown');\n console.log(\n ' ' + pad(note.id.slice(0, 8), 10) +\n ' ' + pad(truncate(note.title, 24), 24) +\n ' ' + pad(truncate(author, 20), 20) +\n ' ' + formatRelativeTime(note.updated_at)\n );\n }\n } else {\n for (const note of data.notes) {\n const author = note.is_own ? 'you' : (note.author.email || 'unknown');\n console.log([note.id, note.title, author, note.updated_at].join('\\t'));\n }\n }\n}\n\n// Output shared notes (public links)\nexport function outputSharedNotes(data: ListSharedNotesResponse, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson(data);\n return;\n }\n\n const c = getColors(ctx);\n\n if (data.count === 0) {\n console.log(c.dim('No shared notes.'));\n return;\n }\n\n if (isHumanOutput(ctx)) {\n console.log(c.bold(`Shared Notes (${data.count})`));\n console.log('');\n\n for (const share of data.shares) {\n const revoked = share.is_revoked ? c.red(' [R]') : '';\n console.log(\n ' ' + truncate(share.note_title, 20) +\n ' ' + c.cyan(share.share_url) +\n ' ' + c.dim(`${share.view_count} views`) +\n ' ' + c.dim(formatRelativeTime(share.created_at)) +\n revoked\n );\n }\n } else {\n for (const share of data.shares) {\n console.log(\n [share.note_title, share.share_url, share.view_count, share.is_revoked, share.created_at].join('\\t')\n );\n }\n }\n}\n\n// Output simple message\nexport function outputMessage(message: string, ctx: CLIContext): void {\n if (ctx.json) {\n outputJson({ message });\n return;\n }\n\n const c = getColors(ctx);\n console.log(c.green('✓') + ' ' + message);\n}\n\n// Output to stderr (for status messages when piping)\nexport function logStatus(message: string): void {\n if (process.stderr.isTTY) {\n console.error(pc.dim(message));\n }\n}\n","import { listNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputNotes } from '../../lib/output.js';\nimport type { ListNotesResponse, CLIContext } from '../../types/index.js';\n\ninterface ListNotesOptions {\n tag?: string;\n archived?: boolean;\n pinned?: boolean;\n deleted?: boolean;\n search?: string;\n limit?: string;\n}\n\nexport async function listNotesAction(\n options: ListNotesOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listNotes<ListNotesResponse>(\n {\n tag: options.tag,\n archived: options.archived ?? false,\n pinned: options.pinned,\n deleted: options.deleted ?? false,\n search: options.search,\n limit: options.limit ? parseInt(options.limit, 10) : 50,\n },\n { pin: ctx.pin }\n );\n\n outputNotes(result.notes, ctx);\n\n // Show warning for protected notes if any\n if (result.warning && !ctx.json) {\n console.error('');\n console.error(result.warning);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { getNote } from '../../lib/api.js';\nimport { handleError, NotFoundError } from '../../lib/errors.js';\nimport { outputNote } from '../../lib/output.js';\nimport type { GetNoteResponse, CLIContext } from '../../types/index.js';\n\nexport async function getNoteAction(id: string, ctx: CLIContext): Promise<void> {\n try {\n const result = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n\n if (!result) {\n throw new NotFoundError('Note', id);\n }\n\n outputNote(result, result.latest_snippet, ctx);\n\n // Show protection status warning if applicable\n if (result.protection_status?.error && !ctx.json) {\n console.error('');\n console.error('Warning: ' + result.protection_status.error);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { createNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CreateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface CreateNoteOptions {\n tags?: string[];\n content?: string;\n}\n\nexport async function createNoteAction(\n title: string,\n options: CreateNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let content = options.content;\n\n // If stdin has content and no --content flag, read from stdin\n if (!content && !process.stdin.isTTY) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinContent = Buffer.concat(chunks).toString('utf-8').trim();\n if (stdinContent) {\n content = stdinContent;\n }\n }\n\n const result = await createNote<CreateNoteResponse>(\n {\n title,\n tags: options.tags && options.tags.length > 0 ? options.tags : undefined,\n content,\n },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Created note: ${result.note.title} (${result.note.id})`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { updateNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface ArchiveNoteOptions {\n undo?: boolean;\n}\n\nexport async function archiveNoteAction(\n id: string,\n options: ArchiveNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const archived = !options.undo;\n\n const result = await updateNote<UpdateNoteResponse>(\n id,\n { archived },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const action = archived ? 'Archived' : 'Unarchived';\n outputMessage(`${action} note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { getNote, updateNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { GetNoteResponse, UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\nexport async function pinNoteAction(id: string, ctx: CLIContext): Promise<void> {\n try {\n // First get current pin status\n const note = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n const newPinned = !note.pinned;\n\n const result = await updateNote<UpdateNoteResponse>(\n id,\n { pinned: newPinned },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const action = newPinned ? 'Pinned' : 'Unpinned';\n outputMessage(`${action} note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import pc from 'picocolors';\nimport { createInterface } from 'node:readline';\nimport { getNote, deleteNote } from '../../lib/api.js';\nimport { handleError, CLIError, ExitCode } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { GetNoteResponse, DeleteNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface DeleteNoteOptions {\n force?: boolean;\n}\n\nasync function confirm(message: string): Promise<boolean> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(message + ' [y/N] ', (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');\n });\n });\n}\n\nexport async function deleteNoteAction(\n id: string,\n options: DeleteNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Get note details first\n const note = await getNote<GetNoteResponse>(id, { pin: ctx.pin });\n\n // Confirm deletion unless --force or --json\n if (!options.force && !ctx.json) {\n if (!process.stdin.isTTY) {\n throw new CLIError(\n 'Cannot confirm deletion in non-interactive mode',\n ExitCode.GENERAL_ERROR,\n 'Use --force for non-interactive deletion'\n );\n }\n\n console.log(`About to delete: ${pc.bold(note.title)}`);\n const confirmed = await confirm('Are you sure?');\n\n if (!confirmed) {\n console.log(pc.dim('Cancelled.'));\n return;\n }\n }\n\n const result = await deleteNote<DeleteNoteResponse>(id, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Deleted note: ${note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { updateNote } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { UpdateNoteResponse, CLIContext } from '../../types/index.js';\n\ninterface UpdateNoteOptions {\n title?: string;\n tags?: string[];\n}\n\nexport async function updateNoteAction(\n id: string,\n options: UpdateNoteOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n if (!options.title && !options.tags) {\n throw new CLIError(\n 'No changes provided',\n 1,\n 'Use --title or --tags to specify what to update'\n );\n }\n\n const data: { title?: string; tags?: string[] } = {};\n if (options.title) data.title = options.title;\n if (options.tags) data.tags = options.tags;\n\n const result = await updateNote<UpdateNoteResponse>(id, data, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Updated note: ${result.note.title}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { createInterface } from 'node:readline';\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport pc from 'picocolors';\n\n// PIN session cache settings\nconst PIN_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst PIN_MAX_ATTEMPTS = 3;\n\nfunction getPinCachePath(): string {\n const uid = process.getuid?.() ?? 'unknown';\n return join(tmpdir(), `pnote-pin-${uid}`);\n}\n\n// Session cache management\n\nexport function getCachedPin(): string | null {\n const cachePath = getPinCachePath();\n\n if (!existsSync(cachePath)) {\n return null;\n }\n\n try {\n const stat = statSync(cachePath);\n const age = Date.now() - stat.mtimeMs;\n\n if (age > PIN_CACHE_TTL_MS) {\n // Cache expired, remove it\n unlinkSync(cachePath);\n return null;\n }\n\n const content = readFileSync(cachePath, 'utf-8').trim();\n return content || null;\n } catch {\n return null;\n }\n}\n\nexport function setCachedPin(pin: string): void {\n const cachePath = getPinCachePath();\n\n try {\n writeFileSync(cachePath, pin, { mode: 0o600 });\n } catch {\n // Silently fail - cache is optional\n }\n}\n\nexport function clearCachedPin(): boolean {\n const cachePath = getPinCachePath();\n\n if (existsSync(cachePath)) {\n try {\n unlinkSync(cachePath);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\n// PIN input methods\n\n/**\n * Read PIN from stdin (for --pin-stdin option)\n * Only reads the first line\n */\nexport async function readPinFromStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n // Only read first line\n const content = Buffer.concat(chunks).toString('utf-8');\n if (content.includes('\\n')) {\n break;\n }\n }\n\n const content = Buffer.concat(chunks).toString('utf-8');\n const firstLine = content.split('\\n')[0]?.trim() || '';\n\n if (!firstLine) {\n throw new Error('No PIN provided via stdin');\n }\n\n return firstLine;\n}\n\n/**\n * Prompt user for PIN interactively\n * Hides input and supports retry\n */\nexport async function promptForPin(\n noteTitle?: string,\n hint?: string,\n maxAttempts: number = PIN_MAX_ATTEMPTS\n): Promise<string | null> {\n if (!process.stdin.isTTY) {\n return null;\n }\n\n // Show context\n if (noteTitle) {\n console.error(pc.yellow('🔒') + ` Note \"${noteTitle}\" is PIN-protected.`);\n } else {\n console.error(pc.yellow('🔒') + ' This action requires your PIN.');\n }\n\n if (hint) {\n console.error(pc.dim(`Hint: ${hint}`));\n }\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const pin = await readPinHidden(\n attempt > 1 ? `Enter PIN (${attempt}/${maxAttempts}): ` : 'Enter PIN: '\n );\n\n if (pin) {\n return pin;\n }\n\n if (attempt < maxAttempts) {\n console.error(pc.red('Invalid or empty PIN. Try again.'));\n }\n }\n\n console.error(pc.red('Too many attempts.'));\n return null;\n}\n\n/**\n * Read a line with hidden input (for PIN entry)\n */\nasync function readPinHidden(prompt: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n terminal: true,\n });\n\n // Disable echo\n if (process.stdin.isTTY) {\n process.stdin.setRawMode?.(true);\n }\n\n process.stderr.write(prompt);\n\n let pin = '';\n\n const onKeypress = (key: Buffer) => {\n const char = key.toString();\n\n if (char === '\\r' || char === '\\n') {\n // Enter pressed\n process.stderr.write('\\n');\n cleanup();\n resolve(pin);\n } else if (char === '\\u0003') {\n // Ctrl+C\n process.stderr.write('\\n');\n cleanup();\n process.exit(130);\n } else if (char === '\\u007F' || char === '\\b') {\n // Backspace\n if (pin.length > 0) {\n pin = pin.slice(0, -1);\n // Move cursor back and clear\n process.stderr.write('\\b \\b');\n }\n } else if (char.length === 1 && char >= ' ') {\n // Regular character\n pin += char;\n process.stderr.write('*');\n }\n };\n\n const cleanup = () => {\n process.stdin.removeListener('data', onKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode?.(false);\n }\n rl.close();\n };\n\n process.stdin.on('data', onKeypress);\n });\n}\n\n/**\n * Get PIN from all sources in priority order\n *\n * Priority:\n * 1. --pin argument (passed in ctx.pin)\n * 2. --pin-stdin (if pinFromStdin is true)\n * 3. PNOTE_PIN environment variable\n * 4. Session cache\n * 5. Interactive prompt (if TTY)\n * 6. null (not available)\n */\nexport async function resolvePin(options: {\n pinArg?: string;\n pinFromStdin?: boolean;\n noteTitle?: string;\n hint?: string;\n skipCache?: boolean;\n skipPrompt?: boolean;\n}): Promise<string | null> {\n const { pinArg, pinFromStdin, noteTitle, hint, skipCache, skipPrompt } = options;\n\n // 1. Command line argument (highest priority)\n if (pinArg) {\n return pinArg;\n }\n\n // 2. stdin\n if (pinFromStdin) {\n try {\n return await readPinFromStdin();\n } catch {\n return null;\n }\n }\n\n // 3. Environment variable\n const envPin = process.env.PNOTE_PIN;\n if (envPin) {\n return envPin;\n }\n\n // 4. Session cache\n if (!skipCache) {\n const cached = getCachedPin();\n if (cached) {\n return cached;\n }\n }\n\n // 5. Interactive prompt\n if (!skipPrompt && process.stdin.isTTY) {\n const pin = await promptForPin(noteTitle, hint);\n if (pin) {\n // Cache for future use\n setCachedPin(pin);\n return pin;\n }\n }\n\n // 6. Not available\n return null;\n}\n\n/**\n * Check if PIN is required but not available\n * Returns error message if PIN is needed but missing\n */\nexport function checkPinRequired(\n isProtected: boolean,\n pin: string | null | undefined\n): string | null {\n if (!isProtected) {\n return null;\n }\n\n if (pin) {\n return null;\n }\n\n if (!process.stdin.isTTY) {\n return 'PIN required but not provided. Use -p <pin> or set PNOTE_PIN environment variable.';\n }\n\n return null;\n}\n","import { Command } from 'commander';\nimport { showSnippetAction } from './show.js';\nimport { copySnippetAction } from './copy.js';\nimport { addSnippetAction } from './add.js';\nimport { updateSnippetAction } from './update.js';\nimport { favoriteSnippetAction } from './favorite.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const snippetCommand = new Command('snippet')\n .description('Read and manage snippets (note versions)')\n .argument('[note-id]', 'Note ID to show snippet for')\n .option('--all', 'Show all snippet versions')\n .action(async (noteId: string | undefined, options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n\n if (noteId) {\n await showSnippetAction(noteId, options, ctx);\n } else {\n cmd.help();\n }\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote snippet abc123 Show latest snippet\n $ pnote snippet abc123 --all Show all versions\n $ pnote snippet copy abc123 Copy to clipboard\n $ cat file.txt | pnote snippet add abc123\n`\n );\n\nsnippetCommand\n .command('copy')\n .description('Copy snippet content to clipboard')\n .argument('<note-id>', 'Note ID')\n .option('--version <n>', 'Specific version number')\n .action(async (noteId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await copySnippetAction(noteId, options, ctx);\n });\n\nsnippetCommand\n .command('add')\n .description('Add a new snippet version (from stdin)')\n .argument('<note-id>', 'Note ID')\n .option('--title <title>', 'Snippet title')\n .action(async (noteId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await addSnippetAction(noteId, options, ctx);\n });\n\nsnippetCommand\n .command('update')\n .description('Update an existing snippet (from stdin)')\n .argument('<snippet-id>', 'Snippet ID')\n .option('--title <title>', 'New snippet title')\n .action(async (snippetId: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await updateSnippetAction(snippetId, options, ctx);\n });\n\nsnippetCommand\n .command('favorite')\n .description('Toggle favorite status on a snippet')\n .argument('<snippet-id>', 'Snippet ID')\n .action(async (snippetId: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await favoriteSnippetAction(snippetId, ctx);\n });\n","import { getNote, listSnippets } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputSnippet, outputSnippets } from '../../lib/output.js';\nimport type { GetNoteResponse, ListSnippetsResponse, CLIContext } from '../../types/index.js';\n\ninterface ShowSnippetOptions {\n all?: boolean;\n}\n\nexport async function showSnippetAction(\n noteId: string,\n options: ShowSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n if (options.all) {\n // Show all versions\n const result = await listSnippets<ListSnippetsResponse>(\n { note_id: noteId, limit: 100 },\n { pin: ctx.pin }\n );\n\n outputSnippets(result.snippets, ctx);\n } else {\n // Show latest snippet only\n const result = await getNote<GetNoteResponse>(noteId, { pin: ctx.pin });\n\n if (result.latest_snippet) {\n outputSnippet(result.latest_snippet, ctx);\n } else {\n if (!ctx.json) {\n console.error('No snippet content found.');\n }\n process.exit(3);\n }\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import pc from 'picocolors';\nimport { getNote, listSnippets } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { copyToClipboard } from '../../lib/clipboard.js';\nimport { logStatus } from '../../lib/output.js';\nimport type { GetNoteResponse, ListSnippetsResponse, Snippet, CLIContext } from '../../types/index.js';\n\ninterface CopySnippetOptions {\n version?: string;\n}\n\nexport async function copySnippetAction(\n noteId: string,\n options: CopySnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let snippet: Snippet | null = null;\n\n if (options.version) {\n // Get specific version\n const versionNum = parseInt(options.version, 10);\n if (isNaN(versionNum)) {\n throw new CLIError('Invalid version number');\n }\n\n const result = await listSnippets<ListSnippetsResponse>(\n { note_id: noteId, limit: 100 },\n { pin: ctx.pin }\n );\n\n snippet = result.snippets.find((s) => s.version === versionNum) || null;\n\n if (!snippet) {\n throw new CLIError(`Version ${versionNum} not found`);\n }\n } else {\n // Get latest\n const result = await getNote<GetNoteResponse>(noteId, { pin: ctx.pin });\n snippet = result.latest_snippet;\n }\n\n if (!snippet) {\n throw new CLIError('No snippet content found');\n }\n\n try {\n await copyToClipboard(snippet.content);\n logStatus('Copied to clipboard');\n\n // If JSON mode, output the snippet data\n if (ctx.json) {\n console.log(JSON.stringify({ copied: true, content: snippet.content }));\n }\n } catch (clipboardError) {\n // Fallback: print to stdout\n if (!ctx.json) {\n console.error(pc.yellow('Clipboard not available, printing to stdout:'));\n console.error('');\n }\n console.log(snippet.content);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { default as clipboardy } from 'clipboardy';\nimport { CLIError } from './errors.js';\n\nexport async function copyToClipboard(text: string): Promise<void> {\n try {\n await clipboardy.write(text);\n } catch (error) {\n // Fallback: output to stdout with a warning\n if (error instanceof Error && error.message.includes('xsel')) {\n throw new CLIError(\n 'Clipboard not available. Install xsel or xclip on Linux.',\n 1,\n 'Content will be printed to stdout instead.'\n );\n }\n throw new CLIError('Failed to copy to clipboard');\n }\n}\n\nexport async function readFromClipboard(): Promise<string> {\n try {\n return await clipboardy.read();\n } catch {\n throw new CLIError('Failed to read from clipboard');\n }\n}\n","import { createSnippet } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CreateSnippetResponse, CLIContext } from '../../types/index.js';\n\ninterface AddSnippetOptions {\n title?: string;\n}\n\nexport async function addSnippetAction(\n noteId: string,\n options: AddSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let content: string;\n\n // Read content from stdin\n if (process.stdin.isTTY) {\n throw new CLIError(\n 'No content provided',\n 1,\n \"Pipe content to this command: echo 'content' | pnote snippet add <note-id>\"\n );\n }\n\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n content = Buffer.concat(chunks).toString('utf-8');\n\n // Trim trailing newline but preserve internal formatting\n if (content.endsWith('\\n')) {\n content = content.slice(0, -1);\n }\n\n if (!content) {\n throw new CLIError('Empty content provided');\n }\n\n const result = await createSnippet<CreateSnippetResponse>(\n {\n note_id: noteId,\n content,\n title: options.title,\n },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(`Created snippet v${result.snippet.version}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { updateSnippet } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { CLIContext } from '../../types/index.js';\n\ninterface UpdateSnippetOptions {\n title?: string;\n}\n\ninterface UpdateSnippetResponse {\n message: string;\n snippet: {\n id: string;\n version: number;\n content: string;\n title: string | null;\n favorite: boolean;\n };\n}\n\nexport async function updateSnippetAction(\n snippetId: string,\n options: UpdateSnippetOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Read content from stdin\n let content: string | undefined;\n\n if (!process.stdin.isTTY) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n content = Buffer.concat(chunks).toString('utf-8');\n\n // Trim trailing newline but preserve internal formatting\n if (content.endsWith('\\n')) {\n content = content.slice(0, -1);\n }\n\n if (!content) {\n content = undefined;\n }\n }\n\n // Must provide content or title\n if (!content && !options.title) {\n throw new CLIError(\n 'No content or title provided',\n 1,\n \"Pipe content to this command: echo 'content' | pnote snippet update <snippet-id>\"\n );\n }\n\n const data: { content?: string; title?: string } = {};\n if (content) data.content = content;\n if (options.title) data.title = options.title;\n\n const result = await updateSnippet<UpdateSnippetResponse>(\n snippetId,\n data,\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage('Updated snippet', ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { toggleFavorite } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { ToggleFavoriteResponse, CLIContext } from '../../types/index.js';\n\nexport async function favoriteSnippetAction(\n snippetId: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await toggleFavorite<ToggleFavoriteResponse>(snippetId, { pin: ctx.pin });\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const status = result.snippet.favorite ? 'favorited' : 'unfavorited';\n outputMessage(`Snippet ${status}`, ctx);\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { Command } from 'commander';\nimport { listTagsAction } from './list.js';\nimport { renameTagAction } from './rename.js';\nimport { mergeTagsAction } from './merge.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const tagsCommand = new Command('tags')\n .description('List and manage tags')\n .option('--include-archived', 'Include tags from archived notes')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listTagsAction(options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote tags List all tags\n $ pnote tags rename \"old\" \"new\" Rename a tag\n $ pnote tags merge \"tag1\" \"tag2\" --into \"target\"\n`\n );\n\ntagsCommand\n .command('rename')\n .description('Rename a tag across all notes')\n .argument('<old-tag>', 'Current tag name')\n .argument('<new-tag>', 'New tag name')\n .action(async (oldTag: string, newTag: string, _options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await renameTagAction(oldTag, newTag, ctx);\n });\n\ntagsCommand\n .command('merge')\n .description('Merge multiple tags into one')\n .argument('<source-tags...>', 'Tags to merge (space-separated)')\n .requiredOption('--into <target>', 'Target tag to merge into')\n .action(async (sourceTags: string[], options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await mergeTagsAction(sourceTags, options.into, ctx);\n });\n","import { listTags } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputTags } from '../../lib/output.js';\nimport type { ListTagsResponse, CLIContext } from '../../types/index.js';\n\ninterface ListTagsOptions {\n includeArchived?: boolean;\n}\n\nexport async function listTagsAction(\n options: ListTagsOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listTags<ListTagsResponse>(\n { include_archived: options.includeArchived ?? false },\n { pin: ctx.pin }\n );\n\n outputTags(result.tags, result.hierarchy, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { renameTag } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { RenameTagResponse, CLIContext } from '../../types/index.js';\n\nexport async function renameTagAction(\n oldTag: string,\n newTag: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await renameTag<RenameTagResponse>(\n { old_tag: oldTag, new_tag: newTag },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n outputMessage(\n `Renamed \"${oldTag}\" to \"${newTag}\" (${result.notes_updated} notes updated)`,\n ctx\n );\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { mergeTags } from '../../lib/api.js';\nimport { handleError, CLIError } from '../../lib/errors.js';\nimport { outputMessage, outputJson } from '../../lib/output.js';\nimport type { MergeTagsResponse, CLIContext } from '../../types/index.js';\n\nexport async function mergeTagsAction(\n sourceTags: string[],\n targetTag: string,\n ctx: CLIContext\n): Promise<void> {\n try {\n // Validate that source doesn't include target\n if (sourceTags.includes(targetTag)) {\n throw new CLIError('Source tags cannot include the target tag');\n }\n\n if (sourceTags.length === 0) {\n throw new CLIError('At least one source tag is required');\n }\n\n const result = await mergeTags<MergeTagsResponse>(\n { source_tags: sourceTags, target_tag: targetTag },\n { pin: ctx.pin }\n );\n\n if (ctx.json) {\n outputJson(result);\n } else {\n const sourceList = sourceTags.map((t) => `\"${t}\"`).join(', ');\n outputMessage(\n `Merged ${sourceList} into \"${targetTag}\" (${result.notes_updated} notes updated)`,\n ctx\n );\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { Command } from 'commander';\nimport { search } from '../lib/api.js';\nimport { handleError } from '../lib/errors.js';\nimport { outputSearchResults } from '../lib/output.js';\nimport { resolvePin } from '../lib/pin.js';\nimport type { SearchResponse, CLIContext } from '../types/index.js';\n\ninterface SearchOptions {\n notesOnly?: boolean;\n snippetsOnly?: boolean;\n limit?: string;\n}\n\nasync function searchAction(\n query: string,\n options: SearchOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n let search_notes = true;\n let search_snippets = true;\n\n if (options.notesOnly) {\n search_notes = true;\n search_snippets = false;\n } else if (options.snippetsOnly) {\n search_notes = false;\n search_snippets = true;\n }\n\n const result = await search<SearchResponse>(\n {\n query,\n search_notes,\n search_snippets,\n limit: options.limit ? parseInt(options.limit, 10) : 20,\n },\n { pin: ctx.pin }\n );\n\n outputSearchResults(query, result.notes, result.snippets, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n\nexport const searchCommand = new Command('search')\n .description('Search notes and snippets')\n .argument('<query>', 'Search query')\n .option('--notes-only', 'Only search note titles and tags')\n .option('--snippets-only', 'Only search snippet content')\n .option('--limit <n>', 'Limit results', '20')\n .action(async (query: string, options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n const ctx: CLIContext = {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n await searchAction(query, options, ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote search \"portrait\" Search all\n $ pnote search \"AI\" --notes-only Search note titles only\n $ pnote search \"code\" --limit 50 Limit results\n`\n );\n","import { Command } from 'commander';\nimport { listSharedTagsAction, getSharedTagNotesAction } from './tags.js';\nimport { listSharedNotesAction } from './notes.js';\nimport type { CLIContext } from '../../types/index.js';\nimport { resolvePin } from '../../lib/pin.js';\n\n// Helper to build CLI context with PIN support\nasync function buildContext(globalOpts: Record<string, unknown>): Promise<CLIContext> {\n const pin = await resolvePin({\n pinArg: globalOpts.pin as string | undefined,\n pinFromStdin: globalOpts.pinStdin as boolean | undefined,\n skipPrompt: true,\n });\n\n return {\n json: (globalOpts.json as boolean) ?? false,\n noColor: (globalOpts.noColor as boolean) ?? false,\n plain: (globalOpts.plain as boolean) ?? false,\n pin: pin ?? undefined,\n };\n}\n\nexport const shareCommand = new Command('share')\n .description('View shared tags and shared note links')\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote share tags List shared tags\n $ pnote share tags abc123 View notes in shared tag\n $ pnote share notes List public share links\n $ pnote share notes --include-revoked\n`\n );\n\n// pnote share tags [id]\nshareCommand\n .command('tags')\n .description('List shared tags or view notes in a shared tag')\n .argument('[id]', 'Shared tag ID to view notes')\n .option('--limit <n>', 'Limit notes returned')\n .action(async (id: string | undefined, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n\n if (id) {\n await getSharedTagNotesAction(id, options, ctx);\n } else {\n await listSharedTagsAction(ctx);\n }\n });\n\n// pnote share notes\nshareCommand\n .command('notes')\n .description('List public share links for your notes')\n .option('--include-revoked', 'Include revoked share links')\n .action(async (options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listSharedNotesAction(options, ctx);\n });\n","import { listSharedTags, getSharedTagNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputSharedTags, outputSharedTagNotes } from '../../lib/output.js';\nimport type {\n ListSharedTagsResponse,\n GetSharedTagNotesResponse,\n CLIContext,\n} from '../../types/index.js';\n\ninterface SharedTagNotesOptions {\n limit?: string;\n}\n\nexport async function listSharedTagsAction(ctx: CLIContext): Promise<void> {\n try {\n const result = await listSharedTags<ListSharedTagsResponse>({ pin: ctx.pin });\n outputSharedTags(result, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n\nexport async function getSharedTagNotesAction(\n id: string,\n options: SharedTagNotesOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await getSharedTagNotes<GetSharedTagNotesResponse>(\n id,\n { limit: options.limit ? parseInt(options.limit, 10) : undefined },\n { pin: ctx.pin }\n );\n outputSharedTagNotes(result, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import { listSharedNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputSharedNotes } from '../../lib/output.js';\nimport type { ListSharedNotesResponse, CLIContext } from '../../types/index.js';\n\ninterface SharedNotesOptions {\n includeRevoked?: boolean;\n}\n\nexport async function listSharedNotesAction(\n options: SharedNotesOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const result = await listSharedNotes<ListSharedNotesResponse>(\n { include_revoked: options.includeRevoked },\n { pin: ctx.pin }\n );\n outputSharedNotes(result, ctx);\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n"],"mappings":"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","names":["Command","pc","pc","pc","pc","pc","pc","pc","pc","Command","pc","c","printTree","pc","pc","createInterface","existsSync","readFileSync","writeFileSync","unlinkSync","join","pc","content","pc","createInterface","Command","Command","pc","pc","buildContext","Command","Command","buildContext","Command","Command","Command","Command","buildContext","Command","Command"]}
|
|
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","../src/commands/skills/index.ts","../src/commands/skills/list.ts","../src/commands/skills/pull.ts","../src/commands/skills/push.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';\nimport { skillsCommand } from './commands/skills/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);\nprogram.addCommand(skillsCommand);\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 note_type?: 'note' | 'skill';\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.note_type) query.set('note_type', params.note_type);\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; note_type?: 'note' | 'skill' },\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","import { Command } from 'commander';\nimport { listSkillsAction } from './list.js';\nimport { pullSkillsAction } from './pull.js';\nimport { pushSkillsAction } from './push.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 skillsCommand = new Command('skills')\n .description('Manage agent skills (sync between cloud and local)')\n .action(async (_options, cmd) => {\n const globalOpts = cmd.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await listSkillsAction(ctx);\n })\n .addHelpText(\n 'after',\n `\nExamples:\n $ pnote skills List all skills in cloud\n $ pnote skills pull Download all skills to ~/.claude/skills/\n $ pnote skills pull myskill Download a specific skill\n $ pnote skills push ./my-skill Upload a local skill directory\n\nSkills are notes with type \"skill\" and title format \"skill-name/filename.md\".\nThey sync to ~/.claude/skills/<skill-name>/<filename> for use with Claude Code.\n`\n );\n\nskillsCommand\n .command('pull')\n .description('Download skills from cloud to local (~/.claude/skills/)')\n .argument('[skill-name]', 'Specific skill to pull (pulls all if omitted)')\n .option('--dir <path>', 'Custom output directory (default: ~/.claude/skills)')\n .option('--dry-run', 'Show what would be downloaded without writing files')\n .action(async (skillName: string | undefined, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await pullSkillsAction(skillName, options, ctx);\n });\n\nskillsCommand\n .command('push')\n .description('Upload a local skill directory to cloud')\n .argument('<dir>', 'Path to skill directory (must contain SKILL.md)')\n .option('--name <name>', 'Override skill name (default: directory name)')\n .action(async (dir: string, options, cmd) => {\n const globalOpts = cmd.parent?.parent?.opts() || {};\n const ctx = await buildContext(globalOpts);\n await pushSkillsAction(dir, options, ctx);\n });\n","import { listNotes } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputJson, logStatus } from '../../lib/output.js';\nimport type { ListNotesResponse, CLIContext } from '../../types/index.js';\nimport pc from 'picocolors';\n\n/**\n * List all skill notes from cloud, grouped by skill name.\n */\nexport async function listSkillsAction(ctx: CLIContext): Promise<void> {\n try {\n const result = await listNotes<ListNotesResponse>(\n { note_type: 'skill', limit: 200 },\n { pin: ctx.pin }\n );\n\n const skills = result.notes;\n\n if (ctx.json) {\n // Group by skill name for JSON output\n const grouped: Record<string, typeof skills> = {};\n for (const note of skills) {\n const slashIdx = note.title.indexOf('/');\n const skillName = slashIdx > 0 ? note.title.slice(0, slashIdx) : note.title;\n if (!grouped[skillName]) grouped[skillName] = [];\n grouped[skillName].push(note);\n }\n outputJson(grouped);\n return;\n }\n\n if (skills.length === 0) {\n console.log(pc.dim('No skills found. Create one with:'));\n console.log(pc.dim(' pnote skills push ./my-skill'));\n return;\n }\n\n // Group skills by name prefix (before first /)\n const grouped = new Map<string, typeof skills>();\n for (const note of skills) {\n const slashIdx = note.title.indexOf('/');\n const skillName = slashIdx > 0 ? note.title.slice(0, slashIdx) : note.title;\n if (!grouped.has(skillName)) grouped.set(skillName, []);\n grouped.get(skillName)!.push(note);\n }\n\n console.log(pc.bold(`Skills (${grouped.size})`));\n console.log('');\n\n for (const [name, files] of grouped) {\n const fileNames = files.map(f => {\n const slashIdx = f.title.indexOf('/');\n return slashIdx > 0 ? f.title.slice(slashIdx + 1) : f.title;\n });\n console.log(\n ' ' + pc.cyan(name) +\n pc.dim(` (${files.length} file${files.length !== 1 ? 's' : ''})`) +\n ' ' + pc.dim(fileNames.join(', '))\n );\n }\n\n console.log('');\n console.log(pc.dim('Pull to local: pnote skills pull'));\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { listNotes, getNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputJson, logStatus } from '../../lib/output.js';\nimport type { ListNotesResponse, GetNoteResponse, CLIContext } from '../../types/index.js';\nimport pc from 'picocolors';\n\ninterface PullOptions {\n dir?: string;\n dryRun?: boolean;\n}\n\n/**\n * Pull skills from cloud → local filesystem.\n * Maps note title \"skill-name/filename.md\" → ~/.claude/skills/skill-name/filename.md\n */\nexport async function pullSkillsAction(\n skillName: string | undefined,\n options: PullOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const baseDir = options.dir || path.join(os.homedir(), '.claude', 'skills');\n\n // Fetch all skill notes\n const result = await listNotes<ListNotesResponse>(\n { note_type: 'skill', limit: 200 },\n { pin: ctx.pin }\n );\n\n let skills = result.notes;\n\n // Filter by skill name if specified\n if (skillName) {\n skills = skills.filter(n => {\n const prefix = n.title.split('/')[0];\n return prefix === skillName;\n });\n\n if (skills.length === 0) {\n console.error(pc.red(`No skill found with name \"${skillName}\"`));\n process.exit(1);\n }\n }\n\n if (skills.length === 0) {\n console.log(pc.dim('No skills to pull.'));\n return;\n }\n\n // Fetch content for each skill note\n let pulled = 0;\n let skipped = 0;\n\n for (const note of skills) {\n const slashIdx = note.title.indexOf('/');\n if (slashIdx <= 0) {\n logStatus(`Skipping \"${note.title}\" (invalid title format, expected \"name/file\")`);\n skipped++;\n continue;\n }\n\n const skillDir = note.title.slice(0, slashIdx);\n const fileName = note.title.slice(slashIdx + 1);\n const filePath = path.join(baseDir, skillDir, fileName);\n\n // Fetch note with latest snippet content\n const noteData = await getNote<GetNoteResponse>(note.id, { pin: ctx.pin });\n const content = noteData.latest_snippet?.content;\n\n if (!content) {\n logStatus(`Skipping \"${note.title}\" (no snippet content)`);\n skipped++;\n continue;\n }\n\n if (options.dryRun) {\n console.log(`${pc.dim('would write')} ${filePath} ${pc.dim(`(${content.length} chars)`)}`);\n pulled++;\n continue;\n }\n\n // Ensure directory exists\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n\n // Write file\n fs.writeFileSync(filePath, content, 'utf-8');\n console.log(`${pc.green('✓')} ${filePath}`);\n pulled++;\n }\n\n console.log('');\n if (options.dryRun) {\n console.log(pc.dim(`Dry run: ${pulled} file(s) would be written, ${skipped} skipped`));\n } else {\n console.log(`Pulled ${pulled} file(s) to ${baseDir}` + (skipped > 0 ? `, ${skipped} skipped` : ''));\n }\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { listNotes, createNote, createSnippet, getNote } from '../../lib/api.js';\nimport { handleError } from '../../lib/errors.js';\nimport { outputJson } from '../../lib/output.js';\nimport type { ListNotesResponse, CreateNoteResponse, CreateSnippetResponse, GetNoteResponse, CLIContext } from '../../types/index.js';\nimport pc from 'picocolors';\n\ninterface PushOptions {\n name?: string;\n}\n\n/**\n * Push a local skill directory → cloud.\n * Each file becomes a note with title \"skill-name/filename\" and note_type='skill'.\n * Content is stored as the latest snippet.\n */\nexport async function pushSkillsAction(\n dir: string,\n options: PushOptions,\n ctx: CLIContext\n): Promise<void> {\n try {\n const resolvedDir = path.resolve(dir);\n\n // Validate directory exists\n if (!fs.existsSync(resolvedDir) || !fs.statSync(resolvedDir).isDirectory()) {\n console.error(pc.red(`Not a directory: ${resolvedDir}`));\n process.exit(1);\n }\n\n // Check for SKILL.md\n const skillMdPath = path.join(resolvedDir, 'SKILL.md');\n if (!fs.existsSync(skillMdPath)) {\n console.error(pc.red(`No SKILL.md found in ${resolvedDir}`));\n console.error(pc.dim('A valid skill directory must contain a SKILL.md file.'));\n process.exit(1);\n }\n\n // Determine skill name\n const skillName = options.name || path.basename(resolvedDir);\n\n // Collect all files (non-recursive for now, matching typical skill structure)\n const files = collectFiles(resolvedDir, resolvedDir);\n\n if (files.length === 0) {\n console.log(pc.dim('No files to push.'));\n return;\n }\n\n // Fetch existing skill notes to check for updates\n const existing = await listNotes<ListNotesResponse>(\n { note_type: 'skill', limit: 200 },\n { pin: ctx.pin }\n );\n\n const existingMap = new Map<string, string>(); // title → note_id\n for (const note of existing.notes) {\n existingMap.set(note.title, note.id);\n }\n\n let created = 0;\n let updated = 0;\n\n for (const relPath of files) {\n const noteTitle = `${skillName}/${relPath}`;\n const filePath = path.join(resolvedDir, relPath);\n const content = fs.readFileSync(filePath, 'utf-8');\n\n const existingId = existingMap.get(noteTitle);\n\n if (existingId) {\n // Update existing: add new snippet version\n await createSnippet<CreateSnippetResponse>(\n { note_id: existingId, content },\n { pin: ctx.pin }\n );\n console.log(`${pc.yellow('↻')} ${noteTitle} ${pc.dim('(new version)')}`);\n updated++;\n } else {\n // Create new note with content\n await createNote<CreateNoteResponse>(\n { title: noteTitle, content, note_type: 'skill' },\n { pin: ctx.pin }\n );\n console.log(`${pc.green('+')} ${noteTitle}`);\n created++;\n }\n }\n\n console.log('');\n console.log(\n `Pushed ${pc.bold(skillName)}: ` +\n (created > 0 ? `${created} created` : '') +\n (created > 0 && updated > 0 ? ', ' : '') +\n (updated > 0 ? `${updated} updated` : '')\n );\n } catch (error) {\n handleError(error, ctx.noColor);\n }\n}\n\n/**\n * Collect files recursively from a directory, returning relative paths.\n * Skips hidden files/dirs and common non-skill files.\n */\nfunction collectFiles(baseDir: string, currentDir: string): string[] {\n const files: string[] = [];\n const entries = fs.readdirSync(currentDir, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip hidden files and common non-skill entries\n if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;\n\n const fullPath = path.join(currentDir, entry.name);\n const relPath = path.relative(baseDir, fullPath);\n\n if (entry.isFile()) {\n files.push(relPath);\n } else if (entry.isDirectory()) {\n files.push(...collectFiles(baseDir, fullPath));\n }\n }\n\n return files;\n}\n"],"mappings":"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","names":["Command","pc","path","pc","pc","path","pc","pc","pc","pc","pc","Command","pc","c","printTree","pc","resolve","pc","createInterface","existsSync","readFileSync","writeFileSync","unlinkSync","join","pc","content","pc","resolve","createInterface","Command","Command","pc","pc","buildContext","Command","Command","buildContext","Command","Command","Command","Command","buildContext","Command","Command","pc","grouped","pc","fs","path","pc","buildContext","Command","Command"]}
|