innernote 0.1.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.
Files changed (3) hide show
  1. package/README.md +241 -0
  2. package/dist/index.js +1969 -0
  3. package/package.json +25 -0
package/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # innernote CLI
2
+
3
+ Write LinkedIn posts in your voice, from the terminal.
4
+
5
+ ```bash
6
+ innernote capture "the thing you just thought of"
7
+ innernote write "why most onboarding asks for too much upfront" --save
8
+ innernote week
9
+ ```
10
+
11
+ ## Install
12
+
13
+ Needs [Node](https://nodejs.org) 20 or newer. Nothing else.
14
+
15
+ ```bash
16
+ npx innernote
17
+ ```
18
+
19
+ Run it without installing anything, or put it on your PATH for good:
20
+
21
+ ```bash
22
+ npm install -g innernote
23
+ ```
24
+
25
+ Then connect the machine to your account:
26
+
27
+ ```bash
28
+ innernote login
29
+ ```
30
+
31
+ It asks for a pairing code, which you get from
32
+ [Settings](https://www.innernote.space/dashboard/settings). The key it saves
33
+ lasts 90 days and can be revoked from the same page.
34
+
35
+ ### Working on it
36
+
37
+ The source is TypeScript and runs on [Bun](https://bun.sh):
38
+
39
+ ```bash
40
+ bun run src/index.ts
41
+ ```
42
+
43
+ `bun run build` produces the published bundle in `dist/`, which is what npm
44
+ ships and what `bun test` exercises in `dist.test.ts`. The published file runs
45
+ on node; the source does not.
46
+
47
+ ## The session
48
+
49
+ Typing `innernote` on its own opens a session you stay in, the way `claude` or
50
+ `psql` do. Your week, then a prompt:
51
+
52
+ ```
53
+ ▍ week
54
+ ▍ write "hiring your first engineer" --save
55
+ ▍ capture the thing that just came up
56
+ ▍ exit
57
+ ```
58
+
59
+ Up arrow for history, tab to complete a command, `help` for what there is.
60
+ **Ctrl-C once cancels what you are typing; twice leaves.**
61
+
62
+ Piped or redirected it prints your week and exits instead, so it never hangs a
63
+ script waiting for input nobody is going to type.
64
+
65
+ ## Connect
66
+
67
+ ```bash
68
+ innernote login
69
+ ```
70
+
71
+ It prints a URL. Open it in a browser where you are already signed in, copy the
72
+ eight-character pairing code, and paste it back. The code works once and expires
73
+ in ten minutes.
74
+
75
+ The token it gives you is stored at `~/.innernote/config.json`, owner-read-only.
76
+ It is opaque, it is not your password, and you can revoke it from Settings at
77
+ any time.
78
+
79
+ ## Commands
80
+
81
+ | Command | What it does |
82
+ | --- | --- |
83
+ | `login [code]` | connect this machine |
84
+ | `logout` | forget the token stored here |
85
+ | `whoami` | show which account is connected |
86
+ | `capture <text>` | save an idea to your inbox |
87
+ | `write [topic]` | draft a post in your voice |
88
+ | `ideas [status]` | list what you have captured |
89
+ | `drafts [status]` | list your posts, with their ids |
90
+ | `week` | what is scheduled for the next seven days |
91
+ | `shape <shape...>` | push a post shorter, punchier, warmer (reads stdin) |
92
+ | `queue <post-id>` | schedule a post into your next open slot |
93
+
94
+ ### write
95
+
96
+ ```bash
97
+ innernote write # picks the pillar you have covered least
98
+ innernote write "hiring your first engineer"
99
+ innernote write --thought "$(cat notes/monday.md)"
100
+ innernote write "shipping fast" --format story --save
101
+ cat brief.md | innernote write
102
+ ```
103
+
104
+ Without `--save` the post is printed and nothing is stored, so you can pipe it:
105
+
106
+ ```bash
107
+ innernote write "onboarding" | pbcopy
108
+ ```
109
+
110
+ The draft comes from the same generation the app runs: same voice, same craft
111
+ rules, same check against what you have already published. It is not a lighter
112
+ version.
113
+
114
+ ### shape
115
+
116
+ The same twelve moves the app's editor has. It reads the post from stdin, so it
117
+ composes:
118
+
119
+ ```bash
120
+ pbpaste | innernote shape shorter punchier | pbcopy
121
+ innernote write "onboarding" --json | jq -r .content | innernote shape deslop
122
+ ```
123
+
124
+ Shapes: `hook` `example` `specific` `punchier` `shorter` `ending` `warmer`
125
+ `deslop` `mobile` `question` `takeaway` `jargon`
126
+
127
+ The names are the server's. The CLI never writes the instruction itself, so
128
+ "shorter" means the same thing here as it does in the editor and inside a chat.
129
+
130
+ ### queue
131
+
132
+ ```bash
133
+ innernote queue p17a1yk936ywnan10643efjtc58dhkah
134
+ ```
135
+
136
+ **A queued post goes live on its own** at your next cadence slot. Nobody presses
137
+ anything again. So it needs a connection you explicitly allowed to publish: tick
138
+ "Let it queue posts" in Settings when you generate the pairing code. Without it
139
+ you get a clear refusal, not a mystery.
140
+
141
+ innernote inside a chat can queue too, if you tick the same box for that
142
+ connection. It can only queue a post you already saved and read, and your chat
143
+ client asks you before it runs. Publish is in nobody's default grant, so every
144
+ connection that can schedule was one you deliberately allowed.
145
+
146
+ ## Piping
147
+
148
+ Every command takes `--json` and prints the API's own payload, nothing else.
149
+ Human output and errors go to stderr, so stdout stays clean:
150
+
151
+ ```bash
152
+ innernote ideas --json | jq -r '.[].content'
153
+ innernote week --json | jq 'length'
154
+ pbpaste | innernote capture
155
+ ```
156
+
157
+ ## Exit codes
158
+
159
+ | Code | Meaning |
160
+ | --- | --- |
161
+ | 0 | it worked |
162
+ | 1 | it failed; the reason is on stderr |
163
+ | 2 | not connected, run `innernote login` |
164
+ | 3 | your account cannot do this right now |
165
+
166
+ Code 3 is separate on purpose. A scheduled job should be able to tell "innernote
167
+ is broken" from "your trial ended", because only one of those is worth waking
168
+ someone up for.
169
+
170
+ ## Environment
171
+
172
+ | Variable | Effect |
173
+ | --- | --- |
174
+ | `INNERNOTE_TOKEN` | use this token, ignore the stored one |
175
+ | `INNERNOTE_API_URL` | talk to another host, for development |
176
+ | `NO_COLOR` | plain output |
177
+
178
+ Both token variables override the config file and are never written back, which
179
+ is what makes the CLI usable in CI without a second config format.
180
+
181
+ ## How it works
182
+
183
+ The CLI is a thin client over the same HTTP API the web app uses. It holds no
184
+ database credentials and implements no product logic. Everything it can do is
185
+ something the API already lets your account do, so entitlement, limits and voice
186
+ all behave exactly as they do in the app, because the work happens server-side
187
+ in one place.
188
+
189
+ ## The writer, here
190
+
191
+ ```
192
+ ▍ drafts
193
+ ▍ open 3
194
+ ▍ ask cut the second half and land it harder
195
+ ▍ save
196
+ ```
197
+
198
+ `shape` covers the twelve named moves. `ask` covers everything else, in your own
199
+ words: it is the same assistant the app's composer runs, so it can change the
200
+ post, answer a question about it, or say it would rather not.
201
+
202
+ `show` reprints whatever you are holding, and the prompt says whether it is
203
+ saved, so you always know where you are. `drop` puts it down.
204
+
205
+ ## Checking the whole flow
206
+
207
+ ```bash
208
+ bun run cli/e2e.ts
209
+ ```
210
+
211
+ Runs the real user journey against a real server: connect, read pillars and
212
+ series, capture an idea, draft a post, reshape it, save it, then delete
213
+ everything it made. It reports what passed and cleans up after itself.
214
+
215
+ **It never publishes.** There is no queue step and there will not be one. A test
216
+ that can publish eventually will, on a real account, to real people. Queueing is
217
+ verified by asserting the refusal on a key that was not granted publish, which
218
+ proves the gate without touching it.
219
+
220
+ Point it anywhere:
221
+
222
+ ```bash
223
+ INNERNOTE_API_URL=http://localhost:3000 bun run cli/e2e.ts
224
+ ```
225
+
226
+ ## Development
227
+
228
+ ```bash
229
+ bun run src/index.ts --help
230
+ bun test
231
+ bun run typecheck
232
+ ```
233
+
234
+ Point it at a local server:
235
+
236
+ ```bash
237
+ INNERNOTE_API_URL=http://localhost:3000 bun run src/index.ts whoami
238
+ ```
239
+
240
+ This package is deliberately outside the app's workspace and has no runtime
241
+ dependencies, so it cannot affect the web build.