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.
- package/dist/index.js +88 -49
- 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/
|
|
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:
|
|
504
|
-
rest
|
|
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 } =
|
|
835
|
-
const
|
|
836
|
-
const
|
|
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 } =
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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 } =
|
|
938
|
-
const
|
|
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 } =
|
|
981
|
-
const
|
|
982
|
-
if (!
|
|
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}
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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.
|
|
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
|
+
"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"
|