innernote 0.2.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/dist/index.js +126 -11
- package/package.json +2 -1
- package/skills/innernote-cli/SKILL.md +125 -0
package/README.md
CHANGED
|
@@ -78,18 +78,28 @@ any time.
|
|
|
78
78
|
|
|
79
79
|
## Commands
|
|
80
80
|
|
|
81
|
+
The table below is asserted by `cli/src/parity.test.ts`: a command missing
|
|
82
|
+
from it fails the suite, so what you read here is what the binary has.
|
|
83
|
+
|
|
81
84
|
| Command | What it does |
|
|
82
85
|
| --- | --- |
|
|
83
86
|
| `login [code]` | connect this machine |
|
|
84
87
|
| `logout` | forget the token stored here |
|
|
85
|
-
| `whoami` | show which account is connected |
|
|
88
|
+
| `whoami` | show which account is connected, and what this key can do |
|
|
89
|
+
| `context` | what you post about: your pillars and your series |
|
|
86
90
|
| `capture <text>` | save an idea to your inbox |
|
|
87
91
|
| `write [topic]` | draft a post in your voice |
|
|
92
|
+
| `shape <shape...>` | push a post shorter, punchier, warmer |
|
|
93
|
+
| `ask <anything>` | talk to the post in your own words |
|
|
94
|
+
| `save` | keep the draft you are holding |
|
|
95
|
+
| `show` | reprint the post you are holding |
|
|
96
|
+
| `drop` | put down whatever you are holding |
|
|
97
|
+
| `open <n or id>` | pull a post out of the last list and work on it |
|
|
88
98
|
| `ideas [status]` | list what you have captured |
|
|
89
|
-
| `drafts [status]` | list your posts,
|
|
99
|
+
| `drafts [status]` | list your posts, numbered |
|
|
90
100
|
| `week` | what is scheduled for the next seven days |
|
|
91
|
-
| `shape <shape...>` | push a post shorter, punchier, warmer (reads stdin) |
|
|
92
101
|
| `queue <post-id>` | schedule a post into your next open slot |
|
|
102
|
+
| `unqueue <post-id>` | pull it back out before it goes live |
|
|
93
103
|
|
|
94
104
|
### write
|
|
95
105
|
|
package/dist/index.js
CHANGED
|
@@ -261,6 +261,14 @@ var MARK_BLOCK_COUNT = MARK_GRID.reduce((n, row) => n + row.split("").filter((c)
|
|
|
261
261
|
function paintRGB(r, g, b, s) {
|
|
262
262
|
return paint(r, g, b, s);
|
|
263
263
|
}
|
|
264
|
+
function paintBgRGB(r, g, b, s) {
|
|
265
|
+
if (!wantsColor)
|
|
266
|
+
return s;
|
|
267
|
+
if (truecolor)
|
|
268
|
+
return `\x1B[48;2;${r};${g};${b}m${s}\x1B[49m`;
|
|
269
|
+
const q = (v) => Math.round(v / 255 * 5);
|
|
270
|
+
return `\x1B[48;5;${16 + 36 * q(r) + 6 * q(g) + q(b)}m${s}\x1B[49m`;
|
|
271
|
+
}
|
|
264
272
|
function logo(cells = 2) {
|
|
265
273
|
return MARK_GRID.map((row) => row.split("").map((c) => c === "#" ? "█".repeat(cells) : " ".repeat(cells)).join(""));
|
|
266
274
|
}
|
|
@@ -609,6 +617,42 @@ async function week(args) {
|
|
|
609
617
|
}
|
|
610
618
|
return 0;
|
|
611
619
|
}
|
|
620
|
+
async function context(args) {
|
|
621
|
+
const { json } = parseFlags(args);
|
|
622
|
+
const [pillars, series] = await Promise.all([
|
|
623
|
+
request("/api/pillars"),
|
|
624
|
+
request("/api/campaigns")
|
|
625
|
+
]);
|
|
626
|
+
if (json) {
|
|
627
|
+
out(JSON.stringify({ pillars: pillars.pillars, series: series.campaigns }, null, 2));
|
|
628
|
+
return 0;
|
|
629
|
+
}
|
|
630
|
+
out();
|
|
631
|
+
if (pillars.pillars.length) {
|
|
632
|
+
out(` ${bold2("What you post about")}`);
|
|
633
|
+
for (const p of pillars.pillars) {
|
|
634
|
+
out(` ${caramel(p.name)}${typeof p.weight === "number" ? dim2(` ${p.weight}%`) : ""}`);
|
|
635
|
+
}
|
|
636
|
+
} else {
|
|
637
|
+
out(` ${dim2("No content pillars yet. Set them in Settings.")}`);
|
|
638
|
+
}
|
|
639
|
+
out();
|
|
640
|
+
if (series.campaigns.length) {
|
|
641
|
+
out(` ${bold2("Series")}${dim2(" write into one with")} ${caramel('write --series "<name>"')}`);
|
|
642
|
+
for (const c of series.campaigns) {
|
|
643
|
+
const count = typeof c.postCount === "number" && c.postCount > 0 ? dim2(` ${c.postCount} ${c.postCount === 1 ? "post" : "posts"}`) : "";
|
|
644
|
+
out(` ${caramel(c.name)}${count}`);
|
|
645
|
+
if (c.brief)
|
|
646
|
+
out(` ${dim2(oneLine(c.brief, 64))}`);
|
|
647
|
+
if (c.goal)
|
|
648
|
+
out(` ${dim2(`goal: ${oneLine(c.goal, 58)}`)}`);
|
|
649
|
+
}
|
|
650
|
+
} else {
|
|
651
|
+
out(` ${dim2("No series running.")}`);
|
|
652
|
+
}
|
|
653
|
+
out();
|
|
654
|
+
return 0;
|
|
655
|
+
}
|
|
612
656
|
|
|
613
657
|
// src/commands/read.ts
|
|
614
658
|
function parseFlags2(args) {
|
|
@@ -680,20 +724,47 @@ function level(s, t) {
|
|
|
680
724
|
const tri = up <= 1 ? up : 2 - up;
|
|
681
725
|
return 0.18 + tri * 0.82;
|
|
682
726
|
}
|
|
683
|
-
function
|
|
727
|
+
function rampAt(level2) {
|
|
684
728
|
const from = [74, 58, 44];
|
|
685
729
|
const to = [232, 201, 176];
|
|
686
730
|
const c = (i) => Math.round(from[i] + (to[i] - from[i]) * level2);
|
|
687
|
-
return
|
|
731
|
+
return [c(0), c(1), c(2)];
|
|
688
732
|
}
|
|
689
733
|
function frame(t) {
|
|
690
734
|
const grid = logoGrid();
|
|
691
735
|
const lit = new Map;
|
|
692
736
|
for (const s of SPARKS)
|
|
693
737
|
lit.set(`${s.row},${s.col}`, level(s, t));
|
|
694
|
-
|
|
738
|
+
const levelAt = (row, col) => {
|
|
739
|
+
if (row >= grid.length || grid[row][col] !== "#")
|
|
740
|
+
return null;
|
|
741
|
+
return lit.get(`${row},${col}`) ?? 0.18;
|
|
742
|
+
};
|
|
743
|
+
const rows = [];
|
|
744
|
+
for (let top = 0;top < grid.length; top += 2) {
|
|
745
|
+
let line = "";
|
|
746
|
+
for (let col = 0;col < grid[0].length; col++) {
|
|
747
|
+
const upper = levelAt(top, col);
|
|
748
|
+
const lower = levelAt(top + 1, col);
|
|
749
|
+
if (upper == null && lower == null) {
|
|
750
|
+
line += " ";
|
|
751
|
+
} else if (upper != null && lower == null) {
|
|
752
|
+
const [r, g, b] = rampAt(upper);
|
|
753
|
+
line += paintRGB(r, g, b, "▀");
|
|
754
|
+
} else if (upper == null && lower != null) {
|
|
755
|
+
const [r, g, b] = rampAt(lower);
|
|
756
|
+
line += paintRGB(r, g, b, "▄");
|
|
757
|
+
} else {
|
|
758
|
+
const [r, g, b] = rampAt(upper);
|
|
759
|
+
const [br, bg, bb] = rampAt(lower);
|
|
760
|
+
line += paintBgRGB(br, bg, bb, paintRGB(r, g, b, "▀"));
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
rows.push(line.trimEnd());
|
|
764
|
+
}
|
|
765
|
+
return rows;
|
|
695
766
|
}
|
|
696
|
-
var HEIGHT =
|
|
767
|
+
var HEIGHT = 5;
|
|
697
768
|
|
|
698
769
|
class Thinking {
|
|
699
770
|
phases;
|
|
@@ -724,7 +795,7 @@ class Thinking {
|
|
|
724
795
|
this.label = p.text;
|
|
725
796
|
const rows = frame(t);
|
|
726
797
|
const mid = Math.floor(rows.length / 2);
|
|
727
|
-
const out2 = rows.map((r, i) => ` ${r}${i === mid ? `
|
|
798
|
+
const out2 = rows.map((r, i) => ` ${r}${i === mid ? ` \x1B[2m${this.label}\x1B[0m` : ""}`).join(`
|
|
728
799
|
`);
|
|
729
800
|
if (this.drawn)
|
|
730
801
|
process.stderr.write(`\x1B[${HEIGHT}A`);
|
|
@@ -1078,6 +1149,23 @@ async function drop() {
|
|
|
1078
1149
|
note(dim2("`write` to start something, or `drafts` to pick one up"));
|
|
1079
1150
|
return 0;
|
|
1080
1151
|
}
|
|
1152
|
+
async function unqueue(args) {
|
|
1153
|
+
const { json, rest } = parseFlags2(args);
|
|
1154
|
+
const ref = rest[0] ? resolveRef(rest[0]) : null;
|
|
1155
|
+
if (!ref) {
|
|
1156
|
+
fail("Which post?");
|
|
1157
|
+
note(dim2(`${CMD} unqueue <post-id> (\`${CMD} week\` shows what is queued)`));
|
|
1158
|
+
return 1;
|
|
1159
|
+
}
|
|
1160
|
+
const result = await request(`/api/linkedin/schedule/${encodeURIComponent(ref.id)}`, { method: "DELETE" });
|
|
1161
|
+
if (json) {
|
|
1162
|
+
out(JSON.stringify(result, null, 2));
|
|
1163
|
+
return 0;
|
|
1164
|
+
}
|
|
1165
|
+
ok("Pulled back out of the queue. It is a draft again.");
|
|
1166
|
+
note(dim2("`drafts` to find it, `queue` to send it back"));
|
|
1167
|
+
return 0;
|
|
1168
|
+
}
|
|
1081
1169
|
|
|
1082
1170
|
// src/ui.ts
|
|
1083
1171
|
var useColor2 = process.stdout.isTTY === true && !process.env.NO_COLOR && process.env.TERM !== "dumb";
|
|
@@ -1316,6 +1404,18 @@ var COMMANDS = {
|
|
|
1316
1404
|
usage: "innernote week",
|
|
1317
1405
|
detail: "Seven days across, so the gaps are visible before you read a word. Published is filled, scheduled is open."
|
|
1318
1406
|
},
|
|
1407
|
+
unqueue: {
|
|
1408
|
+
summary: "pull a post back out of the queue before it goes live",
|
|
1409
|
+
usage: "innernote unqueue <post-id>",
|
|
1410
|
+
detail: "The undo for queue, while there is still time. The post returns to your drafts and nothing goes live. Once it has been published this refuses, because a live post cannot be unsent this way.",
|
|
1411
|
+
examples: ["innernote unqueue p17abc...", "innernote unqueue 3"]
|
|
1412
|
+
},
|
|
1413
|
+
context: {
|
|
1414
|
+
summary: "what you post about: your pillars and your series",
|
|
1415
|
+
usage: "innernote context",
|
|
1416
|
+
detail: "Your standing context: content pillars with their weights, and every running series with what it is about and what it is for. This is the thing to read before deciding what to write, and the thing an agent should read first for the same reason. --json prints the raw payload for scripts and models.",
|
|
1417
|
+
examples: ["innernote context", "innernote context --json"]
|
|
1418
|
+
},
|
|
1319
1419
|
queue: {
|
|
1320
1420
|
summary: "schedule a post into your next open slot",
|
|
1321
1421
|
usage: "innernote queue <post-id>",
|
|
@@ -1433,7 +1533,7 @@ function suggest(state) {
|
|
|
1433
1533
|
// package.json
|
|
1434
1534
|
var package_default = {
|
|
1435
1535
|
name: "innernote",
|
|
1436
|
-
version: "0.2
|
|
1536
|
+
version: "0.3.2",
|
|
1437
1537
|
description: "Write LinkedIn posts in your voice, from the terminal.",
|
|
1438
1538
|
type: "module",
|
|
1439
1539
|
bin: {
|
|
@@ -1441,6 +1541,7 @@ var package_default = {
|
|
|
1441
1541
|
},
|
|
1442
1542
|
files: [
|
|
1443
1543
|
"dist",
|
|
1544
|
+
"skills",
|
|
1444
1545
|
"README.md"
|
|
1445
1546
|
],
|
|
1446
1547
|
scripts: {
|
|
@@ -1654,6 +1755,18 @@ var COMMANDS2 = {
|
|
|
1654
1755
|
usage: "innernote week",
|
|
1655
1756
|
detail: "Seven days across, so the gaps are visible before you read a word. Published is filled, scheduled is open."
|
|
1656
1757
|
},
|
|
1758
|
+
unqueue: {
|
|
1759
|
+
summary: "pull a post back out of the queue before it goes live",
|
|
1760
|
+
usage: "innernote unqueue <post-id>",
|
|
1761
|
+
detail: "The undo for queue, while there is still time. The post returns to your drafts and nothing goes live. Once it has been published this refuses, because a live post cannot be unsent this way.",
|
|
1762
|
+
examples: ["innernote unqueue p17abc...", "innernote unqueue 3"]
|
|
1763
|
+
},
|
|
1764
|
+
context: {
|
|
1765
|
+
summary: "what you post about: your pillars and your series",
|
|
1766
|
+
usage: "innernote context",
|
|
1767
|
+
detail: "Your standing context: content pillars with their weights, and every running series with what it is about and what it is for. This is the thing to read before deciding what to write, and the thing an agent should read first for the same reason. --json prints the raw payload for scripts and models.",
|
|
1768
|
+
examples: ["innernote context", "innernote context --json"]
|
|
1769
|
+
},
|
|
1657
1770
|
queue: {
|
|
1658
1771
|
summary: "schedule a post into your next open slot",
|
|
1659
1772
|
usage: "innernote queue <post-id>",
|
|
@@ -1914,8 +2027,8 @@ function whatThereIs() {
|
|
|
1914
2027
|
];
|
|
1915
2028
|
const groups = [
|
|
1916
2029
|
["Writing", ["write", "shape", "ask", "save", "capture"]],
|
|
1917
|
-
["Looking", ["show", "ideas", "drafts", "open", "week", "whoami"]],
|
|
1918
|
-
["Shipping", ["queue"]],
|
|
2030
|
+
["Looking", ["show", "ideas", "drafts", "open", "week", "context", "whoami"]],
|
|
2031
|
+
["Shipping", ["queue", "unqueue"]],
|
|
1919
2032
|
["Connection", ["login", "logout"]]
|
|
1920
2033
|
];
|
|
1921
2034
|
for (const [title, cmds] of groups) {
|
|
@@ -1944,8 +2057,8 @@ function commandList() {
|
|
|
1944
2057
|
const groups = [
|
|
1945
2058
|
["Getting connected", ["login", "logout", "whoami"]],
|
|
1946
2059
|
["Writing", ["write", "shape", "ask", "save", "capture"]],
|
|
1947
|
-
["Looking", ["show", "ideas", "drafts", "open", "week"]],
|
|
1948
|
-
["Shipping", ["queue"]]
|
|
2060
|
+
["Looking", ["show", "ideas", "drafts", "open", "week", "context"]],
|
|
2061
|
+
["Shipping", ["queue", "unqueue"]]
|
|
1949
2062
|
];
|
|
1950
2063
|
const lines = [];
|
|
1951
2064
|
for (const [title, names] of groups) {
|
|
@@ -1970,6 +2083,7 @@ var HELP = () => [
|
|
|
1970
2083
|
].join(`
|
|
1971
2084
|
`);
|
|
1972
2085
|
var COMMANDS3 = {
|
|
2086
|
+
context,
|
|
1973
2087
|
login,
|
|
1974
2088
|
logout: () => logout(),
|
|
1975
2089
|
whoami,
|
|
@@ -1984,7 +2098,8 @@ var COMMANDS3 = {
|
|
|
1984
2098
|
drafts,
|
|
1985
2099
|
open,
|
|
1986
2100
|
week,
|
|
1987
|
-
queue
|
|
2101
|
+
queue,
|
|
2102
|
+
unqueue
|
|
1988
2103
|
};
|
|
1989
2104
|
async function main() {
|
|
1990
2105
|
const [, , command, ...args] = process.argv;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "innernote",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Write LinkedIn posts in your voice, from the terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
+
"skills",
|
|
11
12
|
"README.md"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: innernote-cli
|
|
3
|
+
description: Drive the innernote CLI (`npx innernote`) to help someone write, save and schedule LinkedIn posts in their own voice from the terminal. Use this whenever the user mentions innernote, asks to draft or queue a LinkedIn post from the command line, wants their posting week or captured ideas checked, or asks you to capture a thought for later, even if they do not name the CLI. Also use it before touching any `innernote` command in a script.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Driving the innernote CLI
|
|
7
|
+
|
|
8
|
+
innernote holds this person's writing voice: how they write, what they post
|
|
9
|
+
about, and their posting schedule. The CLI is a thin client over the same
|
|
10
|
+
service the app uses, so a draft made here sounds like THEM, not like you,
|
|
11
|
+
and everything you save appears in their app.
|
|
12
|
+
|
|
13
|
+
## The contract, before any command
|
|
14
|
+
|
|
15
|
+
- **stdout is data, stderr is narration.** The post text, JSON and ids go to
|
|
16
|
+
stdout; spinners, notes and errors go to stderr. Pipe stdout with
|
|
17
|
+
confidence, and never parse the human-facing view: every read command takes
|
|
18
|
+
`--json`, which prints the API payload and nothing else.
|
|
19
|
+
- **Exit codes are the protocol.** `0` worked. `1` failed, reason on stderr.
|
|
20
|
+
`2` not connected: stop and ask the user to run `npx innernote login`.
|
|
21
|
+
`3` the account cannot do this right now: a paywall or a spent allowance,
|
|
22
|
+
never a bug. Only `1` is worth debugging.
|
|
23
|
+
- **A refusal is a sentence for the user, not an obstacle for you.** When a
|
|
24
|
+
command refuses (a limit, a missing cadence, no such post), the message is
|
|
25
|
+
already written for the person. Show it to them verbatim and stop. Do not
|
|
26
|
+
retry, and do not work around it.
|
|
27
|
+
|
|
28
|
+
## Connecting
|
|
29
|
+
|
|
30
|
+
Check with `innernote whoami` (exit `2` means not connected). Connecting
|
|
31
|
+
needs a pairing code from the user's Settings page at
|
|
32
|
+
innernote.space/dashboard/settings; you cannot get one yourself. Ask them
|
|
33
|
+
for it, then run `innernote login THEIR-CODE`. The code works once and
|
|
34
|
+
expires in ten minutes. `INNERNOTE_TOKEN` in the environment overrides the
|
|
35
|
+
stored key, which is how CI and scripts authenticate.
|
|
36
|
+
|
|
37
|
+
## Read before you write
|
|
38
|
+
|
|
39
|
+
Suggestions that ignore what this person posts about are generic advice,
|
|
40
|
+
which is the one thing innernote exists to prevent.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
innernote context --json # their content pillars and running series
|
|
44
|
+
innernote week --json # what is scheduled over the next seven days
|
|
45
|
+
innernote ideas --json # thoughts they captured and have not written
|
|
46
|
+
innernote drafts --json # saved posts, newest first, with ids
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Start with `context` and `week` when helping them decide what to write: an
|
|
50
|
+
empty week is a real answer, and a post should land inside a pillar or a
|
|
51
|
+
series they have committed to.
|
|
52
|
+
|
|
53
|
+
## The writing loop
|
|
54
|
+
|
|
55
|
+
**Capture** the moment something is worth posting about later:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
innernote capture "their thought, in their words"
|
|
59
|
+
git log --oneline -20 | innernote capture # stdin works too
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Capture their framing, not your tidied summary. Their phrasing carries their
|
|
63
|
+
voice; a summary throws it away.
|
|
64
|
+
|
|
65
|
+
**Draft and keep** in one command:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
innernote write "their rough thought or topic, in their words" --save
|
|
69
|
+
innernote write "next part of the hiring story" --series "Build in Public" --save
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Pass their OWN WORDS as the argument, as fully as you have them. `write`
|
|
73
|
+
takes a whole messy thought, and any shaping you already know they want
|
|
74
|
+
(shorter, no list, warmer ending) belongs in that ask, phrased plainly.
|
|
75
|
+
`--series` takes the series NAME; a wrong name refuses with the real list,
|
|
76
|
+
so correct from that and retry once. The saved id is printed on stderr and
|
|
77
|
+
`innernote drafts --json` lists it first.
|
|
78
|
+
|
|
79
|
+
**Shaping an already-saved post is not yours to finish here.** Each CLI
|
|
80
|
+
invocation is a fresh process, so the flag form of `shape` transforms
|
|
81
|
+
stdin to stdout without saving:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
innernote shape shorter punchier < draft.txt # transformed text, NOT saved
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Use that for showing the person options. To revise and keep, fold the
|
|
88
|
+
direction into a fresh `write ... --save`, or hand them to the app or the
|
|
89
|
+
interactive session (`innernote` on its own), where reshaping a held draft
|
|
90
|
+
does persist.
|
|
91
|
+
|
|
92
|
+
## Scheduling: the one action that reaches other people
|
|
93
|
+
|
|
94
|
+
`innernote queue <id>` schedules a saved post into their next open slot,
|
|
95
|
+
and it then goes live on LinkedIn on its own. Nobody presses anything
|
|
96
|
+
again, and a live post cannot be unsent.
|
|
97
|
+
|
|
98
|
+
So queue ONLY when the user has clearly told you to queue that specific
|
|
99
|
+
post. Never as a helpful next step, never to tidy up. If they have not said
|
|
100
|
+
so, tell them it is saved and stop. The undo exists while it is still
|
|
101
|
+
pending:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
innernote queue p17abc... # their explicit ask, and only then
|
|
105
|
+
innernote unqueue p17abc... # back to drafts, nothing goes out
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
If `queue` exits `3`, their plan or allowance is the reason; show the
|
|
109
|
+
message, which says where to fix it, and leave the decision with them.
|
|
110
|
+
|
|
111
|
+
## Worked example
|
|
112
|
+
|
|
113
|
+
The user says: "turn what I told you about interview homework into a post
|
|
114
|
+
for my build-in-public series, keep it short, and line it up for this week."
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
innernote context --json # confirm the series name
|
|
118
|
+
innernote week --json # is there an open day?
|
|
119
|
+
innernote write "interview homework filters for free time, not talent. we swapped ours for a paid 40 minute working session and offer accepts went up. keep it short." --series "Build in Public" --save
|
|
120
|
+
innernote drafts --json # take the first id
|
|
121
|
+
innernote queue <that-id> # they said "line it up": that is the go-ahead
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Then tell them what was drafted, where it was queued, and that `unqueue`
|
|
125
|
+
takes it back any time before it goes live.
|