innernote 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +88 -49
  2. package/package.json +22 -1
package/dist/index.js CHANGED
@@ -83,6 +83,9 @@ class ApiError extends Error {
83
83
  get isRefusal() {
84
84
  return this.status === 402 || this.status === 429;
85
85
  }
86
+ get isNotConnected() {
87
+ return this.status === 401;
88
+ }
86
89
  }
87
90
 
88
91
  class NotLoggedIn extends Error {
@@ -497,13 +500,41 @@ function resolveRef(ref) {
497
500
  return /^[a-z0-9]{20,}$/.test(ref) ? { id: ref, title: ref } : null;
498
501
  }
499
502
 
500
- // src/commands/read.ts
501
- function parseFlags(args) {
503
+ // src/flags.ts
504
+ function parseFlags(args, valueFlags = []) {
505
+ const values = new Map;
506
+ const present = new Set;
507
+ const rest = [];
508
+ for (let i = 0;i < args.length; i++) {
509
+ const arg = args[i];
510
+ if (!arg.startsWith("--")) {
511
+ rest.push(arg);
512
+ continue;
513
+ }
514
+ const eq = arg.indexOf("=");
515
+ const name = eq === -1 ? arg.slice(2) : arg.slice(2, eq);
516
+ present.add(name);
517
+ if (!valueFlags.includes(name))
518
+ continue;
519
+ if (eq !== -1) {
520
+ values.set(name, arg.slice(eq + 1));
521
+ continue;
522
+ }
523
+ const next = args[i + 1];
524
+ if (next !== undefined && !next.startsWith("--")) {
525
+ values.set(name, next);
526
+ i++;
527
+ }
528
+ }
502
529
  return {
503
- json: args.includes("--json"),
504
- rest: args.filter((a) => !a.startsWith("--"))
530
+ json: present.has("json"),
531
+ rest,
532
+ value: (name) => values.get(name),
533
+ has: (name) => present.has(name)
505
534
  };
506
535
  }
536
+
537
+ // src/commands/read.ts
507
538
  function powers(scopes) {
508
539
  if (!scopes || scopes.length === 0)
509
540
  return "full access";
@@ -654,14 +685,6 @@ async function context(args) {
654
685
  return 0;
655
686
  }
656
687
 
657
- // src/commands/read.ts
658
- function parseFlags2(args) {
659
- return {
660
- json: args.includes("--json"),
661
- rest: args.filter((a) => !a.startsWith("--"))
662
- };
663
- }
664
-
665
688
  // src/progress.ts
666
689
  var DRAFTING = [
667
690
  { at: 0, text: "reading your voice..." },
@@ -831,9 +854,10 @@ async function whileThinking(phases, run) {
831
854
 
832
855
  // src/commands/write.ts
833
856
  async function capture(args) {
834
- const { json, rest } = parseFlags2(args);
835
- const piped = await readStdin();
836
- const content = (rest.join(" ").trim() || piped || "").trim();
857
+ const { json, rest } = parseFlags(args);
858
+ const typed = rest.join(" ").trim();
859
+ const piped = typed ? null : await readStdin();
860
+ const content = (typed || piped || "").trim();
837
861
  if (!content) {
838
862
  fail("Nothing to capture.");
839
863
  note(dim2('Try: innernote capture "the thing you just thought of"'));
@@ -853,21 +877,14 @@ async function capture(args) {
853
877
  return 0;
854
878
  }
855
879
  async function write(args) {
856
- const { json, rest } = parseFlags2(args);
857
- const flagValue = (name) => {
858
- const exact = args.indexOf(`--${name}`);
859
- if (exact !== -1 && args[exact + 1] && !args[exact + 1].startsWith("--")) {
860
- return args[exact + 1];
861
- }
862
- const inline = args.find((a) => a.startsWith(`--${name}=`));
863
- return inline?.slice(name.length + 3);
864
- };
865
- const piped = await readStdin();
866
- const thought = flagValue("thought") ?? (piped ?? undefined);
867
- const topic = rest.filter((a) => a !== thought).join(" ").trim();
868
- const format = flagValue("format");
869
- const series = flagValue("series");
870
- const save = args.includes("--save");
880
+ const { json, rest, value, has } = parseFlags(args, ["thought", "format", "series"]);
881
+ const topic = rest.join(" ").trim();
882
+ const thoughtFlag = value("thought");
883
+ const piped = thoughtFlag || topic ? null : await readStdin();
884
+ const thought = thoughtFlag ?? (piped ?? undefined);
885
+ const format = value("format");
886
+ const series = value("series");
887
+ const save = has("save");
871
888
  const call = () => request("/api/content/generate", {
872
889
  method: "POST",
873
890
  body: {
@@ -934,11 +951,11 @@ var SHAPES = [
934
951
  "jargon"
935
952
  ];
936
953
  async function shape(args) {
937
- const { json, rest } = parseFlags2(args);
938
- const piped = await readStdin();
954
+ const { json, rest } = parseFlags(args);
955
+ const held = getDraft();
956
+ const piped = held ? null : await readStdin();
939
957
  const chosen = rest.filter((a) => SHAPES.includes(a));
940
958
  const freeText = rest.filter((a) => !SHAPES.includes(a)).join(" ").trim();
941
- const held = getDraft();
942
959
  const content = (piped ?? held?.content ?? "").trim();
943
960
  if (!content) {
944
961
  fail("Nothing to reshape.");
@@ -977,14 +994,15 @@ async function shape(args) {
977
994
  return 0;
978
995
  }
979
996
  async function queue(args) {
980
- const { json, rest } = parseFlags2(args);
981
- const id = rest[0];
982
- if (!id) {
997
+ const { json, rest } = parseFlags(args);
998
+ const ref = rest[0] ? resolveRef(rest[0]) : null;
999
+ if (!ref) {
983
1000
  fail("Which post?");
984
- note(dim2(`${CMD} queue <post-id> (ids come from \`${CMD} drafts --json\`)`));
1001
+ note(dim2(`${CMD} drafts then ${CMD} queue 3`));
1002
+ note(dim2(`Or pass the id: ${CMD} queue <post-id>`));
985
1003
  return 1;
986
1004
  }
987
- const result = await request(`/api/posts/${encodeURIComponent(id)}/queue`, { method: "POST", timeoutMs: 60000 });
1005
+ const result = await request(`/api/posts/${encodeURIComponent(ref.id)}/queue`, { method: "POST", timeoutMs: 60000 });
988
1006
  if (json) {
989
1007
  out(JSON.stringify(result, null, 2));
990
1008
  return 0;
@@ -999,7 +1017,7 @@ async function queue(args) {
999
1017
  return 0;
1000
1018
  }
1001
1019
  async function save(args) {
1002
- const { json } = parseFlags2(args);
1020
+ const { json } = parseFlags(args);
1003
1021
  const held = getDraft();
1004
1022
  if (!held?.content) {
1005
1023
  fail("Nothing to save.");
@@ -1026,7 +1044,7 @@ async function save(args) {
1026
1044
  return 0;
1027
1045
  }
1028
1046
  async function open(args) {
1029
- const { json, rest } = parseFlags2(args);
1047
+ const { json, rest } = parseFlags(args);
1030
1048
  const ref = rest[0];
1031
1049
  if (!ref) {
1032
1050
  fail("Open which one?");
@@ -1058,7 +1076,7 @@ async function open(args) {
1058
1076
  return 0;
1059
1077
  }
1060
1078
  async function ask(args) {
1061
- const { json, rest } = parseFlags2(args);
1079
+ const { json, rest } = parseFlags(args);
1062
1080
  const message = rest.join(" ").trim();
1063
1081
  const held = getDraft();
1064
1082
  if (!message) {
@@ -1112,7 +1130,7 @@ async function ask(args) {
1112
1130
  return 0;
1113
1131
  }
1114
1132
  async function show(args) {
1115
- const { json } = parseFlags2(args);
1133
+ const { json } = parseFlags(args);
1116
1134
  const held = getDraft();
1117
1135
  if (!held?.content) {
1118
1136
  note("Nothing in hand.");
@@ -1150,7 +1168,7 @@ async function drop() {
1150
1168
  return 0;
1151
1169
  }
1152
1170
  async function unqueue(args) {
1153
- const { json, rest } = parseFlags2(args);
1171
+ const { json, rest } = parseFlags(args);
1154
1172
  const ref = rest[0] ? resolveRef(rest[0]) : null;
1155
1173
  if (!ref) {
1156
1174
  fail("Which post?");
@@ -1425,8 +1443,8 @@ var COMMANDS = {
1425
1443
  queue: {
1426
1444
  summary: "schedule a post into your next open slot",
1427
1445
  usage: "innernote queue <post-id>",
1428
- detail: "A queued post GOES LIVE on LinkedIn on its own at your next cadence slot. Nobody presses anything again. Needs a connection you allowed to publish: tick that box in Settings when you generate the code.",
1429
- examples: ["innernote drafts", "innernote queue p17a1yk936ywnan10643efjtc58dhkah"]
1446
+ detail: "A queued post GOES LIVE on LinkedIn on its own at your next cadence slot. Nobody presses anything again. Needs a connection you allowed to publish: tick that box in Settings when you generate the code. Takes a number from the last list, or a full id. It never assumes the draft in hand: this is the one command that makes you say which post.",
1447
+ examples: ["innernote drafts", "innernote queue 3", "innernote queue p17a1yk936ywnan10643efjtc58dhkah"]
1430
1448
  }
1431
1449
  };
1432
1450
  function commandHelp(name) {
@@ -1539,8 +1557,29 @@ function suggest(state) {
1539
1557
  // package.json
1540
1558
  var package_default = {
1541
1559
  name: "innernote",
1542
- version: "0.3.3",
1560
+ version: "0.3.4",
1543
1561
  description: "Write LinkedIn posts in your voice, from the terminal.",
1562
+ keywords: [
1563
+ "linkedin",
1564
+ "mcp",
1565
+ "mcp-server",
1566
+ "model-context-protocol",
1567
+ "ai-agent",
1568
+ "claude",
1569
+ "claude-code",
1570
+ "cursor",
1571
+ "agent-skill",
1572
+ "writing",
1573
+ "content",
1574
+ "personal-branding",
1575
+ "ghostwriting",
1576
+ "cli"
1577
+ ],
1578
+ homepage: "https://www.innernote.space/cli",
1579
+ license: "UNLICENSED",
1580
+ bugs: {
1581
+ url: "https://www.innernote.space/cli"
1582
+ },
1544
1583
  type: "module",
1545
1584
  bin: {
1546
1585
  innernote: "dist/index.js"
@@ -1818,8 +1857,8 @@ var COMMANDS2 = {
1818
1857
  queue: {
1819
1858
  summary: "schedule a post into your next open slot",
1820
1859
  usage: "innernote queue <post-id>",
1821
- detail: "A queued post GOES LIVE on LinkedIn on its own at your next cadence slot. Nobody presses anything again. Needs a connection you allowed to publish: tick that box in Settings when you generate the code.",
1822
- examples: ["innernote drafts", "innernote queue p17a1yk936ywnan10643efjtc58dhkah"]
1860
+ detail: "A queued post GOES LIVE on LinkedIn on its own at your next cadence slot. Nobody presses anything again. Needs a connection you allowed to publish: tick that box in Settings when you generate the code. Takes a number from the last list, or a full id. It never assumes the draft in hand: this is the one command that makes you say which post.",
1861
+ examples: ["innernote drafts", "innernote queue 3", "innernote queue p17a1yk936ywnan10643efjtc58dhkah"]
1823
1862
  }
1824
1863
  };
1825
1864
  function commandHelp2(name) {
@@ -2205,7 +2244,7 @@ main().then((code) => {
2205
2244
  }
2206
2245
  if (isApiError(err)) {
2207
2246
  fail2(err.message);
2208
- process.exitCode = err.isRefusal ? 3 : 1;
2247
+ process.exitCode = err.isNotConnected ? 2 : err.isRefusal ? 3 : 1;
2209
2248
  return;
2210
2249
  }
2211
2250
  fail2(err instanceof Error ? err.message : String(err));
package/package.json CHANGED
@@ -1,7 +1,28 @@
1
1
  {
2
2
  "name": "innernote",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Write LinkedIn posts in your voice, from the terminal.",
5
+ "keywords": [
6
+ "linkedin",
7
+ "mcp",
8
+ "mcp-server",
9
+ "model-context-protocol",
10
+ "ai-agent",
11
+ "claude",
12
+ "claude-code",
13
+ "cursor",
14
+ "agent-skill",
15
+ "writing",
16
+ "content",
17
+ "personal-branding",
18
+ "ghostwriting",
19
+ "cli"
20
+ ],
21
+ "homepage": "https://www.innernote.space/cli",
22
+ "license": "UNLICENSED",
23
+ "bugs": {
24
+ "url": "https://www.innernote.space/cli"
25
+ },
5
26
  "type": "module",
6
27
  "bin": {
7
28
  "innernote": "dist/index.js"