innernote 0.5.0 → 0.6.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 +84 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1098,7 +1098,9 @@ function parseWhen(input) {
|
|
|
1098
1098
|
return Number.isFinite(t) ? t : null;
|
|
1099
1099
|
}
|
|
1100
1100
|
async function queue(args) {
|
|
1101
|
-
const { json, rest, value } = parseFlags(args, ["at"]);
|
|
1101
|
+
const { json, rest, value, has } = parseFlags(args, ["at"]);
|
|
1102
|
+
if (has("ready"))
|
|
1103
|
+
return queueReady(json, rest, value("at"));
|
|
1102
1104
|
const ref = rest[0] ? resolveRef(rest[0]) : null;
|
|
1103
1105
|
if (!ref) {
|
|
1104
1106
|
fail("Which post?");
|
|
@@ -1133,6 +1135,40 @@ async function queue(args) {
|
|
|
1133
1135
|
note(dim2("`week` to see where it landed"));
|
|
1134
1136
|
return 0;
|
|
1135
1137
|
}
|
|
1138
|
+
async function queueReady(json, rest, at) {
|
|
1139
|
+
if (rest.length || at !== undefined) {
|
|
1140
|
+
fail("--ready queues every Ready post in order, so it takes no post and no time.");
|
|
1141
|
+
note(dim2(`${CMD} queue --ready or ${CMD} queue <post-id>`));
|
|
1142
|
+
return 1;
|
|
1143
|
+
}
|
|
1144
|
+
const res = await request("/api/posts/queue-ready", { method: "POST", timeoutMs: 90000 });
|
|
1145
|
+
if (json) {
|
|
1146
|
+
out(JSON.stringify(res, null, 2));
|
|
1147
|
+
return 0;
|
|
1148
|
+
}
|
|
1149
|
+
if (res.queued.length === 0) {
|
|
1150
|
+
fail("Nothing was queued.");
|
|
1151
|
+
if (res.stopped)
|
|
1152
|
+
note(res.stopped);
|
|
1153
|
+
return 1;
|
|
1154
|
+
}
|
|
1155
|
+
const n = res.queued.length;
|
|
1156
|
+
ok(`Queued ${n} ${n === 1 ? "post" : "posts"}, in your Ready order. Each goes live on its own.`);
|
|
1157
|
+
for (const q of res.queued) {
|
|
1158
|
+
const when = new Date(q.scheduledFor).toLocaleString(undefined, {
|
|
1159
|
+
weekday: "short",
|
|
1160
|
+
day: "numeric",
|
|
1161
|
+
month: "short",
|
|
1162
|
+
hour: "numeric",
|
|
1163
|
+
minute: "2-digit"
|
|
1164
|
+
});
|
|
1165
|
+
out(` ${dim2(when.padEnd(22))} ${q.title || q.id}`);
|
|
1166
|
+
}
|
|
1167
|
+
if (res.waiting > 0)
|
|
1168
|
+
note(`${res.waiting} still in Ready. ${res.stopped ?? ""}`.trim());
|
|
1169
|
+
note(dim2("`week` to see where they landed"));
|
|
1170
|
+
return 0;
|
|
1171
|
+
}
|
|
1136
1172
|
async function save(args) {
|
|
1137
1173
|
const { json } = parseFlags(args);
|
|
1138
1174
|
const held = getDraft();
|
|
@@ -1492,7 +1528,7 @@ async function showPost(refArg, json) {
|
|
|
1492
1528
|
return 0;
|
|
1493
1529
|
}
|
|
1494
1530
|
async function edit(args) {
|
|
1495
|
-
const { json, rest, value } = parseFlags(args, ["text", "file", "title", "first-comment", "series", "status"]);
|
|
1531
|
+
const { json, rest, value, has } = parseFlags(args, ["text", "file", "title", "first-comment", "series", "status", "after"]);
|
|
1496
1532
|
const refArg = rest[0];
|
|
1497
1533
|
if (!refArg) {
|
|
1498
1534
|
fail("Edit which post?");
|
|
@@ -1504,17 +1540,23 @@ async function edit(args) {
|
|
|
1504
1540
|
const firstComment = value("first-comment");
|
|
1505
1541
|
const seriesName = value("series");
|
|
1506
1542
|
const status = value("status");
|
|
1543
|
+
const first = has("first");
|
|
1544
|
+
const afterRef = value("after");
|
|
1507
1545
|
const file = value("file");
|
|
1508
1546
|
let text = value("text");
|
|
1509
1547
|
if (file)
|
|
1510
1548
|
text = await readFile2(file, "utf8");
|
|
1511
|
-
const fieldsGiven = title !== undefined || firstComment !== undefined || seriesName !== undefined || status !== undefined;
|
|
1549
|
+
const fieldsGiven = title !== undefined || firstComment !== undefined || seriesName !== undefined || status !== undefined || first || afterRef !== undefined;
|
|
1512
1550
|
if (text === undefined && !fieldsGiven) {
|
|
1513
1551
|
text = await readStdin() ?? undefined;
|
|
1514
1552
|
}
|
|
1515
1553
|
if (text === undefined && !fieldsGiven) {
|
|
1516
1554
|
fail("Nothing to change.");
|
|
1517
|
-
note(dim2("--file, --text or piped text for the post, --title, --first-comment, --series, --status"));
|
|
1555
|
+
note(dim2("--file, --text or piped text for the post, --title, --first-comment, --series, --status, --first, --after"));
|
|
1556
|
+
return 1;
|
|
1557
|
+
}
|
|
1558
|
+
if (first && afterRef !== undefined) {
|
|
1559
|
+
fail("--first or --after, not both.");
|
|
1518
1560
|
return 1;
|
|
1519
1561
|
}
|
|
1520
1562
|
if (status !== undefined && status !== "ready" && status !== "draft") {
|
|
@@ -1581,6 +1623,17 @@ async function edit(args) {
|
|
|
1581
1623
|
await request(`/api/posts/${encodeURIComponent(post._id)}/ready`, { method: status === "ready" ? "POST" : "DELETE" });
|
|
1582
1624
|
changed.push(`status (${status})`);
|
|
1583
1625
|
}
|
|
1626
|
+
if (first || afterRef !== undefined) {
|
|
1627
|
+
let after = null;
|
|
1628
|
+
if (afterRef !== undefined) {
|
|
1629
|
+
const target = await postFromRef(afterRef, `${CMD} edit <post-id> --after <post-id>`);
|
|
1630
|
+
if (!target)
|
|
1631
|
+
return 1;
|
|
1632
|
+
after = target._id;
|
|
1633
|
+
}
|
|
1634
|
+
await request(`/api/posts/${encodeURIComponent(post._id)}/move`, { method: "POST", body: { after } });
|
|
1635
|
+
changed.push(after ? "place in Ready" : "place in Ready (top)");
|
|
1636
|
+
}
|
|
1584
1637
|
if (json) {
|
|
1585
1638
|
out(JSON.stringify({ id: post._id, changed }, null, 2));
|
|
1586
1639
|
return 0;
|
|
@@ -1804,7 +1857,7 @@ var COMMANDS = {
|
|
|
1804
1857
|
},
|
|
1805
1858
|
edit: {
|
|
1806
1859
|
summary: "change a saved post: its text, title, first comment, series or status",
|
|
1807
|
-
usage: "innernote edit <id> [--file <path> | --text <text>] [--title <text>] [--first-comment <text>] [--series <name>] [--status ready|draft]",
|
|
1860
|
+
usage: "innernote edit <id> [--file <path> | --text <text>] [--title <text>] [--first-comment <text>] [--series <name>] [--status ready|draft] [--first | --after <id>]",
|
|
1808
1861
|
detail: "Puts your own words into a saved post. New text comes from --file, --text or a pipe, and is saved the way the app saves a draft, so the old text is one Undo away in the post's history. A post already live on LinkedIn keeps its text. The id comes from `drafts --json` or `show`.",
|
|
1809
1862
|
options: [
|
|
1810
1863
|
["--file <path>", "the new text of the post, from a file"],
|
|
@@ -1812,13 +1865,16 @@ var COMMANDS = {
|
|
|
1812
1865
|
["--title <text>", "the post's title in the app"],
|
|
1813
1866
|
["--first-comment <text>", "the comment posted under it when it goes live"],
|
|
1814
1867
|
["--series <name>", "file it into a series, or `none` to take it out"],
|
|
1815
|
-
["--status <ready|draft>", "mark it ready, or send it back to draft"]
|
|
1868
|
+
["--status <ready|draft>", "mark it ready, or send it back to draft"],
|
|
1869
|
+
["--first", "put a Ready post at the top of Ready, so it goes out next"],
|
|
1870
|
+
["--after <id>", "put a Ready post right after another one in Ready"]
|
|
1816
1871
|
],
|
|
1817
1872
|
examples: [
|
|
1818
1873
|
"innernote edit p17abc... --file post.txt",
|
|
1819
1874
|
"pbpaste | innernote edit p17abc...",
|
|
1820
1875
|
'innernote edit p17abc... --title "The sales call" --first-comment "link: innernote.space"',
|
|
1821
|
-
'innernote edit p17abc... --series "Build in Public" --status ready'
|
|
1876
|
+
'innernote edit p17abc... --series "Build in Public" --status ready',
|
|
1877
|
+
"innernote edit 3 --first"
|
|
1822
1878
|
]
|
|
1823
1879
|
},
|
|
1824
1880
|
captures: {
|
|
@@ -1961,10 +2017,13 @@ var COMMANDS = {
|
|
|
1961
2017
|
},
|
|
1962
2018
|
queue: {
|
|
1963
2019
|
summary: "schedule a post into your next open slot",
|
|
1964
|
-
usage: "innernote queue <post-id> [--at <time>]",
|
|
1965
|
-
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.",
|
|
1966
|
-
options: [
|
|
1967
|
-
|
|
2020
|
+
usage: "innernote queue <post-id> [--at <time>] | queue --ready",
|
|
2021
|
+
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. `--ready` queues every Ready post at once, in your Ready order, the top one first: Queue these in the app.",
|
|
2022
|
+
options: [
|
|
2023
|
+
["--at <time>", `a time you pick, like "2026-10-12 12:31" (this machine's timezone), instead of the next open slot`],
|
|
2024
|
+
["--ready", "every Ready post, in your Ready order, into your next open slots"]
|
|
2025
|
+
],
|
|
2026
|
+
examples: ["innernote drafts", "innernote queue 3", "innernote queue p17a1yk936ywnan10643efjtc58dhkah", "innernote drafts ready", "innernote queue --ready"]
|
|
1968
2027
|
}
|
|
1969
2028
|
};
|
|
1970
2029
|
function commandHelp(name) {
|
|
@@ -2077,7 +2136,7 @@ function suggest(state) {
|
|
|
2077
2136
|
// package.json
|
|
2078
2137
|
var package_default = {
|
|
2079
2138
|
name: "innernote",
|
|
2080
|
-
version: "0.
|
|
2139
|
+
version: "0.6.0",
|
|
2081
2140
|
description: "Write LinkedIn posts in your voice, from the terminal.",
|
|
2082
2141
|
keywords: [
|
|
2083
2142
|
"linkedin",
|
|
@@ -2791,7 +2850,7 @@ var COMMANDS2 = {
|
|
|
2791
2850
|
},
|
|
2792
2851
|
edit: {
|
|
2793
2852
|
summary: "change a saved post: its text, title, first comment, series or status",
|
|
2794
|
-
usage: "innernote edit <id> [--file <path> | --text <text>] [--title <text>] [--first-comment <text>] [--series <name>] [--status ready|draft]",
|
|
2853
|
+
usage: "innernote edit <id> [--file <path> | --text <text>] [--title <text>] [--first-comment <text>] [--series <name>] [--status ready|draft] [--first | --after <id>]",
|
|
2795
2854
|
detail: "Puts your own words into a saved post. New text comes from --file, --text or a pipe, and is saved the way the app saves a draft, so the old text is one Undo away in the post's history. A post already live on LinkedIn keeps its text. The id comes from `drafts --json` or `show`.",
|
|
2796
2855
|
options: [
|
|
2797
2856
|
["--file <path>", "the new text of the post, from a file"],
|
|
@@ -2799,13 +2858,16 @@ var COMMANDS2 = {
|
|
|
2799
2858
|
["--title <text>", "the post's title in the app"],
|
|
2800
2859
|
["--first-comment <text>", "the comment posted under it when it goes live"],
|
|
2801
2860
|
["--series <name>", "file it into a series, or `none` to take it out"],
|
|
2802
|
-
["--status <ready|draft>", "mark it ready, or send it back to draft"]
|
|
2861
|
+
["--status <ready|draft>", "mark it ready, or send it back to draft"],
|
|
2862
|
+
["--first", "put a Ready post at the top of Ready, so it goes out next"],
|
|
2863
|
+
["--after <id>", "put a Ready post right after another one in Ready"]
|
|
2803
2864
|
],
|
|
2804
2865
|
examples: [
|
|
2805
2866
|
"innernote edit p17abc... --file post.txt",
|
|
2806
2867
|
"pbpaste | innernote edit p17abc...",
|
|
2807
2868
|
'innernote edit p17abc... --title "The sales call" --first-comment "link: innernote.space"',
|
|
2808
|
-
'innernote edit p17abc... --series "Build in Public" --status ready'
|
|
2869
|
+
'innernote edit p17abc... --series "Build in Public" --status ready',
|
|
2870
|
+
"innernote edit 3 --first"
|
|
2809
2871
|
]
|
|
2810
2872
|
},
|
|
2811
2873
|
captures: {
|
|
@@ -2948,10 +3010,13 @@ var COMMANDS2 = {
|
|
|
2948
3010
|
},
|
|
2949
3011
|
queue: {
|
|
2950
3012
|
summary: "schedule a post into your next open slot",
|
|
2951
|
-
usage: "innernote queue <post-id> [--at <time>]",
|
|
2952
|
-
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.",
|
|
2953
|
-
options: [
|
|
2954
|
-
|
|
3013
|
+
usage: "innernote queue <post-id> [--at <time>] | queue --ready",
|
|
3014
|
+
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. `--ready` queues every Ready post at once, in your Ready order, the top one first: Queue these in the app.",
|
|
3015
|
+
options: [
|
|
3016
|
+
["--at <time>", `a time you pick, like "2026-10-12 12:31" (this machine's timezone), instead of the next open slot`],
|
|
3017
|
+
["--ready", "every Ready post, in your Ready order, into your next open slots"]
|
|
3018
|
+
],
|
|
3019
|
+
examples: ["innernote drafts", "innernote queue 3", "innernote queue p17a1yk936ywnan10643efjtc58dhkah", "innernote drafts ready", "innernote queue --ready"]
|
|
2955
3020
|
}
|
|
2956
3021
|
};
|
|
2957
3022
|
function commandHelp2(name) {
|