k0-board 0.1.1 → 0.2.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/.claude/skills/k0-changelog/SKILL.md +96 -0
- package/CHANGELOG.md +163 -1
- package/README.md +223 -20
- package/bin/k0-board.js +37 -3
- package/menubar/K0MenuBar.swift +105 -22
- package/menubar/build.sh +7 -1
- package/package.json +6 -3
- package/platform/contract.js +30 -0
- package/platform/darwin/index.js +18 -3
- package/platform/darwin/servers.js +16 -0
- package/platform/index.js +9 -1
- package/platform/linux/index.js +18 -1
- package/platform/linux/servers.js +41 -0
- package/platform/linux/tray.py +42 -2
- package/platform/shared/listeners.js +121 -0
- package/platform/shared/servers.js +111 -0
- package/platform/win32/index.js +15 -1
- package/platform/win32/servers.js +73 -0
- package/platform/win32/tray.ps1 +11 -0
- package/server/changelog.js +242 -0
- package/server/db.js +58 -0
- package/server/git.js +135 -0
- package/server/guard.js +31 -0
- package/server/index.js +122 -35
- package/server/machine.js +9 -0
- package/server/servers.js +481 -0
- package/server/watcher.js +8 -1
- package/server/writer.js +128 -0
- package/web/board.css +162 -12
- package/web/board.js +278 -10
- package/web/changelog.css +185 -0
- package/web/changelog.html +43 -0
- package/web/changelog.js +298 -0
- package/web/index.html +9 -7
- package/web/recency.js +86 -0
- package/web/view.js +3 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: k0-changelog
|
|
3
|
+
description: Writes the summary of a stretch of work — what got committed, what is already online, what is still sitting on this machine — from the facts k0 hands over on standard input. k0 calls it by itself when somebody opens the ChangeLog page, and it is what turns a list of commits into something a person can read. Use this skill when the user types "/k0-changelog", or asks "what did I do yesterday", "write up my week", "summarise what I shipped". Do not use it to look the facts up: they arrive on standard input already, and this skill never runs git itself.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /k0-changelog
|
|
7
|
+
|
|
8
|
+
You are handed, on standard input, a JSON description of everything that happened in a stretch
|
|
9
|
+
of time across somebody's repositories. Write it up so they can read it over a coffee and know
|
|
10
|
+
where they stand.
|
|
11
|
+
|
|
12
|
+
Your entire reply is the summary. It is printed as it is, so there is no room for a preamble,
|
|
13
|
+
no "here is your summary", no closing offer of further help, and no code fence around the
|
|
14
|
+
whole thing. Markdown, starting at the first word that belongs to the summary.
|
|
15
|
+
|
|
16
|
+
## What arrives
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"period": "yesterday",
|
|
21
|
+
"from": "…", "to": "…",
|
|
22
|
+
"totals": { "repositories": 3, "commits": 11, "online": 9, "local": 2, "dirty": 4, … },
|
|
23
|
+
"repositories": [
|
|
24
|
+
{
|
|
25
|
+
"name": "k0",
|
|
26
|
+
"commits": [{ "at": "…", "subject": "…", "body": "…", "online": true }],
|
|
27
|
+
"unpushed_total": 2,
|
|
28
|
+
"uncommitted_files": ["web/board.js"],
|
|
29
|
+
"unreleased_changelog": ["### Fixed", "- the board stays pinned to the bar"],
|
|
30
|
+
"cards": [{ "title": "…", "description": "…", "status": "IDLE", "done": false }]
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`online: true` means that commit has left this machine. `online: false` means it is done but
|
|
37
|
+
still only here. `unpushed_total` counts those from before this window too — a commit made on
|
|
38
|
+
Tuesday and still sitting here on Friday is worth a mention.
|
|
39
|
+
|
|
40
|
+
## What to write
|
|
41
|
+
|
|
42
|
+
**One opening paragraph**, no heading above it. Two or three sentences: how many repositories
|
|
43
|
+
were touched, what actually got out, and what did not. Write the sentence you would say out
|
|
44
|
+
loud if somebody asked how yesterday went — not a table read aloud.
|
|
45
|
+
|
|
46
|
+
**Then one block per repository**, in the order they arrive:
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
## k0
|
|
50
|
+
|
|
51
|
+
**The zoom moves ten per cent at a time, and the button that puts a column away stays put.**
|
|
52
|
+
|
|
53
|
+
Two touches to the board. The zoom used to jump in steps too wide to land on 90%, and the
|
|
54
|
+
button that folds a column away appeared and disappeared depending on the session: now it is
|
|
55
|
+
always there.
|
|
56
|
+
|
|
57
|
+
- The zoom goes down ten per cent a click, so 90% is one click away
|
|
58
|
+
- The button that puts a column away no longer blinks with the session
|
|
59
|
+
- The `Old` column now reads like `Others`
|
|
60
|
+
|
|
61
|
+
**Done, not online yet:** two commits still on this machine, and three changelog lines written
|
|
62
|
+
but not yet closed into a version.
|
|
63
|
+
**Still half-done:** three files changed and never committed.
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The bold first line is the point of the whole thing: it says **what is different now**, not
|
|
67
|
+
what was modified. Not "the zoom step was made configurable" but "the zoom moves ten per cent
|
|
68
|
+
at a time". If you cannot say what is different, the commit subjects will usually say it for
|
|
69
|
+
you — they were written by the same person you are writing for.
|
|
70
|
+
|
|
71
|
+
Keep a block short. A paragraph, a handful of bullets, and the two closing lines when there is
|
|
72
|
+
something to put in them. This is a summary somebody reads standing up.
|
|
73
|
+
|
|
74
|
+
## Rules
|
|
75
|
+
|
|
76
|
+
- **Write in the language of the facts.** The commit subjects and the card titles tell you what
|
|
77
|
+
language this person works in: write in that one, and do not translate anything. The headings,
|
|
78
|
+
the bold lines, the bullets — all of it in their language.
|
|
79
|
+
- **Leave the words of the trade alone.** *commit*, *push*, *branch*, *changelog* are what these
|
|
80
|
+
things are called in every language, and they do not decline: six commits, not *sei commessi*.
|
|
81
|
+
Translate the sentence around them, never the word itself.
|
|
82
|
+
- **Do not invent.** If a commit subject does not say what it did, say what it says and leave
|
|
83
|
+
it there. A summary that guesses is worse than a summary that is short.
|
|
84
|
+
- **What changed for whoever uses the thing, not which function moved.** No file paths, no
|
|
85
|
+
function names, no jargon, unless the repository itself is a tool for programmers and the
|
|
86
|
+
commit already speaks that way.
|
|
87
|
+
- **Never print commit hashes.** They are not in what you are given, and they should not be in
|
|
88
|
+
what you write.
|
|
89
|
+
- **Leave out the two closing lines when they are empty.** No "nothing left half-done": an
|
|
90
|
+
absent line already says that, and a line saying nothing is one more line to read.
|
|
91
|
+
- **No emoji and no exclamation marks.** Nothing is exciting; things happened.
|
|
92
|
+
- **If a repository has only uncommitted files and nothing else**, that is still worth a block —
|
|
93
|
+
it just says work is in progress there, and what it is about.
|
|
94
|
+
- **If `repositories` is empty**, write one line saying so and stop. Do not pad it out, do not
|
|
95
|
+
encourage anybody, do not suggest what they might do next. Nothing happened, and saying that
|
|
96
|
+
plainly is the whole job.
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,167 @@ All notable changes to this project are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.0]
|
|
10
|
+
|
|
11
|
+
k0 could always tell you how the work stood. This version lets it tell you whether the work is
|
|
12
|
+
*running*: a globe in each column heading says whether that repository's site is up, and switches
|
|
13
|
+
it on or off from the board. The server it starts belongs to nobody and outlives everything —
|
|
14
|
+
the session that asked for it, the other sessions, and k0 itself — which is the one thing a dev
|
|
15
|
+
server started inside a session could never do.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **A globe next to every repository: is the site up, and one click to change it.** Last on a
|
|
20
|
+
column's heading, after the git mark. Grey is off, green is up, it breathes while it is coming
|
|
21
|
+
up, and red means it was started and did not come up — with the reason and the log a hover
|
|
22
|
+
away. **One click switches it, two restart it**, and while it is green the repository's **name
|
|
23
|
+
is underlined with a green dashed line** and becomes a link that opens the site in another tab,
|
|
24
|
+
on the port it is really listening on. The line is the same green as the globe and stays for as
|
|
25
|
+
long as the server does, so a repository that is up can be told apart from across the board
|
|
26
|
+
without going near it. A
|
|
27
|
+
repository gets one when its `package.json` has a `dev` script, or failing that a `serve` one:
|
|
28
|
+
nothing to configure, nothing to fill in. The point of it is where the server lives: k0 starts
|
|
29
|
+
it **detached and owned by nobody**, so it survives the session that asked for it, every other
|
|
30
|
+
session, and k0 restarting under it. A dev server started inside a session belongs to that
|
|
31
|
+
session and dies with it, which is what made "is the site up" a question nobody could answer
|
|
32
|
+
from the board. k0 also **never asks the server whether it is up** — it makes no network
|
|
33
|
+
requests, here as everywhere else — so "up" means the process is alive and the system says it
|
|
34
|
+
is holding a TCP port open, which is both stronger evidence and where the real port in the
|
|
35
|
+
tooltip comes from. And a server **you** started by hand in a terminal turns the globe green on
|
|
36
|
+
its own within a few seconds, and switches off from the board like any other: a globe that only
|
|
37
|
+
knew about its own servers would sit grey next to a site that is plainly running. On Windows
|
|
38
|
+
that last part is missing, because nothing there can read another process's working directory,
|
|
39
|
+
and k0 says so instead of drawing those servers as off. Tried on a real board, against a
|
|
40
|
+
repository that had a `server-restart` skill to compare with: the globe went green on port
|
|
41
|
+
4321 — read off the running process, not off the port written in the skill — the name opened
|
|
42
|
+
the site, a double click brought it back on a new process with nothing orphaned behind it, and
|
|
43
|
+
a server started by hand in a terminal was picked up and then switched off from the board. And
|
|
44
|
+
the one that matters: after `k0-board restart` the globe was still green and the site still
|
|
45
|
+
answering on the same process.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- **A column's heading is two groups now, and the count of post-its is gone.** What you press is
|
|
50
|
+
on the left — the `+` and the fold — and what tells you how things stand is on the right: the
|
|
51
|
+
git mark, and the globe after it. The number that used to follow the repository name has been
|
|
52
|
+
taken out. It sat in the middle of the row taking up the room the name now uses, and it was
|
|
53
|
+
never the answer to a question anybody had: the post-its are right there to be counted, and
|
|
54
|
+
the number moved every time a filter did. Long repository names now give up characters to an
|
|
55
|
+
ellipsis instead of pushing the marks off the end of the row.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
59
|
+
- **A tab left open no longer shows you the old interface.** k0 sent its own pages and stylesheets
|
|
60
|
+
with no instruction about keeping them, so the browser decided for itself — and a board left
|
|
61
|
+
open all day went on using the stylesheet it loaded that morning. It showed up the first time
|
|
62
|
+
the globe arrived: the servers switched on and off correctly and the board redrew every second,
|
|
63
|
+
but the heading kept the shape it had before, because the page redraws itself and the stylesheet
|
|
64
|
+
does not. After an update it is worse than confusing: the new k0 on disk, the old one on screen.
|
|
65
|
+
They are a few kilobytes over a connection to your own machine, so nothing is kept now.
|
|
66
|
+
|
|
67
|
+
- **`Close` gives the memory back without closing the work.** A link at the end of a card's row,
|
|
68
|
+
after `Done` and quieter than it: it stops the session and shuts its terminal — which is where
|
|
69
|
+
the memory was going — and leaves the card exactly where it is, with the colour it had. The one
|
|
70
|
+
asking you something stays red, the one holding a plan up stays amber, the one at your turn
|
|
71
|
+
stays yellow, and `Resume` picks the conversation up where it left off. Until now the only way
|
|
72
|
+
to give a machine its memory back was `Done`, which also declares the work finished, so a dozen
|
|
73
|
+
windows open meant choosing between a struggling computer and a board that lies. It is not there
|
|
74
|
+
while a session is working: stopping one mid-thought is not memory saved, it is work lost. Tried
|
|
75
|
+
on a real board, on a session weighing 380 MB: the window and the process were gone in a second
|
|
76
|
+
and a bit, the card stayed where it was, and `Resume` came back to the same conversation.
|
|
77
|
+
- **A ChangeLog page that tells you what you have been doing.** The list-shaped button next to
|
|
78
|
+
the `+` opens a page of its own that reads like a release note: an opening paragraph on how the
|
|
79
|
+
day went, then one block per repository saying what is different now — and, underneath it, what
|
|
80
|
+
is **done but not out yet**. A commit still sitting on your machine, changelog lines written
|
|
81
|
+
but never closed into a version, files never committed. Four windows across the top — Today,
|
|
82
|
+
Yesterday, Week, Month — and it opens on none of them: it opens on the last day you actually
|
|
83
|
+
worked, so on a Monday you get Friday instead of an empty page. Only repositories you touched
|
|
84
|
+
in that window appear, so the one that has been dirty since March stops turning up every
|
|
85
|
+
morning as if it were news, and only your own commits are counted, so a repository shared with
|
|
86
|
+
other people still tells you about your day. The facts sit folded under each block, one line to
|
|
87
|
+
open them, with every commit marked green if it is online and amber if it is still only here.
|
|
88
|
+
The words are written by the Claude Code already on your machine — no key to paste, no account
|
|
89
|
+
to configure, nothing leaving the machine — and they come out in the language you commit in,
|
|
90
|
+
because they are written out of your own commit messages. Nothing is stored: the page is
|
|
91
|
+
written again every time you open it. Without Claude Code it still opens, with the facts and a
|
|
92
|
+
line saying why the rest is missing.
|
|
93
|
+
- **The board keeps itself down to what you are working on.** A repository you have not touched
|
|
94
|
+
since the day before your last piece of work folds away by itself: its column leaves the board
|
|
95
|
+
and its name appears in `Old`, the new column next to `Others` and built exactly like it — a
|
|
96
|
+
`+`, a name and the git mark. Click that row and the column comes back at full width for the
|
|
97
|
+
rest of the visit, with everything that was in it. There is nothing to switch on — with a dozen
|
|
98
|
+
repositories open, you arrive in the morning and the three or four you are actually on are the
|
|
99
|
+
ones standing there, side by side. The day is counted back from your last piece of work rather
|
|
100
|
+
than from the clock, so on Monday you find Friday's work instead of an empty board. A column
|
|
101
|
+
with something going on in it — working, planning, asking you something, holding a plan up for
|
|
102
|
+
approval — never folds, whatever its age; a terminal simply left open at *Your turn* folds like
|
|
103
|
+
anything else, and folding closes nothing. And nothing folds while you are looking at it: the
|
|
104
|
+
board tidies itself on the next reload, never out from under your hands.
|
|
105
|
+
- **A column can be put away now.** Next to a column's `+`, a button that folds it immediately
|
|
106
|
+
instead of waiting for it to go quiet — for a repository you are finished with for the day. It
|
|
107
|
+
goes faint and refuses on a column with something going on in it, and says why if you hover it.
|
|
108
|
+
It is remembered across reloads, until you fetch the column back or something in it wakes up.
|
|
109
|
+
It closes nothing: no session is stopped and no terminal is shut. What closes a session is
|
|
110
|
+
`Close` or `Done` on a card.
|
|
111
|
+
- **The installation ends on the board.** `npx k0-board` now opens it in your browser once
|
|
112
|
+
everything is in place, after the cards have been imported, so the first thing you see is your
|
|
113
|
+
own work and there is no address to copy out of the terminal. `--no-open` finishes without it,
|
|
114
|
+
for installing over SSH. Where the name `k0.localhost` does not resolve, k0 falls back to
|
|
115
|
+
`127.0.0.1` rather than leaving you on a blank page.
|
|
116
|
+
|
|
117
|
+
### Changed
|
|
118
|
+
|
|
119
|
+
- **The zoom goes ten per cent at a time.** `+` and `−` used to jump from 100% straight to 80%,
|
|
120
|
+
or up to 125%: the steps in between simply did not exist, and the only way to a size like 90%
|
|
121
|
+
was a pinch on the trackpad — if you knew to try it. Now every click is ten points — 90%, 80%,
|
|
122
|
+
70% and so on, still stopping at 30% and 200% — so where the next one lands is something you
|
|
123
|
+
can guess before you press it. The pinch still gets you to anything in between, and from there
|
|
124
|
+
the next click picks the nearest step.
|
|
125
|
+
- **Nothing here changes what you see using k0.** The work went underneath, and it was worth doing
|
|
126
|
+
for two reasons. The tests now run on the machinery Node already ships with rather than on a loop
|
|
127
|
+
written by hand, which turns seven pass-or-fail files into five hundred and twenty-one named
|
|
128
|
+
checks — still a quarter of a second, still nothing to install, but a failure now names the one
|
|
129
|
+
thing that broke instead of the file it was in. And two parts that had never been tested at all
|
|
130
|
+
are: the one that decides whether a request reaching k0 may be answered, which is what stands
|
|
131
|
+
between a web page you happen to have open and a program that opens terminals on your machine,
|
|
132
|
+
and the one that keeps your cards, which is where a mistake loses work you cannot get back.
|
|
133
|
+
Every build from now on refuses to go backwards on how much of k0 is covered.
|
|
134
|
+
- **The reasoning behind k0 is now written down where it can be found.** Two documents for whoever
|
|
135
|
+
works on it: the shape of what k0 remembers, and how its tests are put together and what they
|
|
136
|
+
deliberately leave alone. Neither is shipped with the package.
|
|
137
|
+
- **Nothing changes for you here either.** Putting out a new version of k0 — the documents brought
|
|
138
|
+
up to date, the tests run, and the version that reaches the registry — is now one road written
|
|
139
|
+
down rather than a sequence somebody has to remember, with a single stop to ask before the step
|
|
140
|
+
that cannot be undone. Like the two documents above, it is for whoever works on k0 and is not in
|
|
141
|
+
the package.
|
|
142
|
+
|
|
143
|
+
## [0.1.2]
|
|
144
|
+
|
|
145
|
+
Two things that were in the way every day: a field nobody needed, and a notification that opened
|
|
146
|
+
the wrong application.
|
|
147
|
+
|
|
148
|
+
### Fixed
|
|
149
|
+
|
|
150
|
+
- **Clicking a notification opens that session's terminal**, on all three platforms. On macOS it
|
|
151
|
+
used to open **Script Editor** with a file dialog: when the Mac would not deliver k0's own
|
|
152
|
+
notifications, k0 fell back to posting one through `osascript`, and a banner posted that way
|
|
153
|
+
belongs to Script Editor rather than to k0 — no card, no click, wrong application. The fallback
|
|
154
|
+
is gone. When macOS refuses the permission, k0 now says so in the menu bar and takes you to the
|
|
155
|
+
Notifications pane — and switch it on there and the menu says so on the next pass, a couple of
|
|
156
|
+
seconds later, instead of leaving you looking at a message that reads as stuck. It writes what
|
|
157
|
+
the answer was in its log, and asks again rather than giving up on the first refusal. On Linux
|
|
158
|
+
the notification carries an action, on Windows the balloon finally has a click.
|
|
159
|
+
|
|
160
|
+
### Changed
|
|
161
|
+
|
|
162
|
+
- **A new card asks for three things**: the repository, a title, and what Claude should do when it
|
|
163
|
+
starts — which can be left empty and typed straight into Claude Code. The *Description* field is
|
|
164
|
+
gone: it never went anywhere except onto the note. Imported sessions keep theirs, which is the
|
|
165
|
+
one place it says something, and `/k0-import` still writes it.
|
|
166
|
+
- **A note is never taller than it is wide.** Long text used to push a card down the column until
|
|
167
|
+
it stopped looking like a note. The repository, the title, the age and the buttons always show;
|
|
168
|
+
the text in the middle is what gets clipped.
|
|
169
|
+
|
|
9
170
|
## [0.1.1]
|
|
10
171
|
|
|
11
172
|
Documentation, and how a release is made. Nothing about k0 itself changed.
|
|
@@ -65,6 +226,7 @@ here is everything that had to change for it to be somebody else's tool as well.
|
|
|
65
226
|
- The personal fixtures k0 grew up on. `test/clean.test.mjs` now fails the build if any of them
|
|
66
227
|
come back.
|
|
67
228
|
|
|
68
|
-
[Unreleased]: https://github.com/alessio-ragni/k0-board/compare/v0.1.
|
|
229
|
+
[Unreleased]: https://github.com/alessio-ragni/k0-board/compare/v0.1.2...HEAD
|
|
230
|
+
[0.1.2]: https://github.com/alessio-ragni/k0-board/compare/v0.1.1...v0.1.2
|
|
69
231
|
[0.1.1]: https://github.com/alessio-ragni/k0-board/compare/v0.1.0...v0.1.1
|
|
70
232
|
[0.1.0]: https://github.com/alessio-ragni/k0-board/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -40,7 +40,8 @@ npx k0-board
|
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
That is the whole thing. It tells you everything it is about to change, asks, and only then does
|
|
43
|
-
it
|
|
43
|
+
it — and when it is finished it opens the board in your browser, so there is no address to write
|
|
44
|
+
down anywhere. `k0-board uninstall` undoes all of it.
|
|
44
45
|
|
|
45
46
|
k0 is published on npm as [`k0-board`](https://www.npmjs.com/package/k0-board): one package, no
|
|
46
47
|
dependencies, nothing to compile. `npx` fetches it, runs the installer once and leaves nothing
|
|
@@ -69,8 +70,9 @@ that and went out from a laptop.)
|
|
|
69
70
|
| `k0-board doctor` | what this machine can and cannot do, and why |
|
|
70
71
|
|
|
71
72
|
`--yes` does not ask. `--from-source` points the service at the directory you are in instead of
|
|
72
|
-
copying it, which is what you want while working on k0 itself. `--no
|
|
73
|
-
|
|
73
|
+
copying it, which is what you want while working on k0 itself. `--no-open` finishes without
|
|
74
|
+
opening a browser, which is what you want over SSH. `--no-<name>` skips one optional change —
|
|
75
|
+
`--no-lid-sleep`, `--no-shift-enter`. `K0_PORT` moves the board off 4319.
|
|
74
76
|
|
|
75
77
|
From a clone, if you would rather look first:
|
|
76
78
|
|
|
@@ -83,7 +85,10 @@ node bin/k0-board.js start
|
|
|
83
85
|
That runs the server in the foreground and opens the board. Nothing is installed and nothing
|
|
84
86
|
outside the directory is touched.
|
|
85
87
|
|
|
86
|
-
The board lives at <http://k0.localhost:4319
|
|
88
|
+
The board lives at <http://k0.localhost:4319>, which is the address both `install` and `start`
|
|
89
|
+
open for you. If that name does not resolve on your machine — which happens on Windows, because
|
|
90
|
+
only browsers are obliged to know that `.localhost` means this computer — k0 opens
|
|
91
|
+
<http://127.0.0.1:4319> instead, and says so.
|
|
87
92
|
|
|
88
93
|
### Requirements
|
|
89
94
|
|
|
@@ -108,6 +113,7 @@ The board lives at <http://k0.localhost:4319>.
|
|
|
108
113
|
| Keep the machine awake | ✅ | ✅ | ✅ |
|
|
109
114
|
| Keep working with the lid closed | ✅ | ❌ system setting | ❌ system setting |
|
|
110
115
|
| Tray icon and notifications | ✅ | ✅ GNOME/KDE | ✅ |
|
|
116
|
+
| Clicking a notification takes you to that terminal | ✅ needs the permission | ✅ if the desktop honours actions | ✅ |
|
|
111
117
|
|
|
112
118
|
**macOS is the only platform the author has.** Linux and Windows are written from the
|
|
113
119
|
documentation and reviewed carefully, and the logic they share with macOS is tested on all three
|
|
@@ -146,8 +152,9 @@ k0 makes **no network requests**. Not one, not even for a font.
|
|
|
146
152
|
### The board
|
|
147
153
|
|
|
148
154
|
- **+** — at the left, next to k0, and next to every repository name on the board: that one opens
|
|
149
|
-
a card with the repository already chosen.
|
|
150
|
-
should do when it starts. The prompt can be left empty
|
|
155
|
+
a card with the repository already chosen. Three fields and no more: the repository, a title,
|
|
156
|
+
and what Claude should do when it starts. The prompt can be left empty — nothing stops you from
|
|
157
|
+
starting the session and typing straight into Claude Code.
|
|
151
158
|
|
|
152
159
|
The repository has to be **picked from the list** (searchable, most used at the top; arrow keys
|
|
153
160
|
to move, Enter takes the highlighted row): a name typed by hand does not count. On leaving the
|
|
@@ -203,6 +210,16 @@ k0 makes **no network requests**. Not one, not even for a font.
|
|
|
203
210
|
still inside it makes macOS put up the "terminate running processes" dialog, and the window does
|
|
204
211
|
not close at all.
|
|
205
212
|
|
|
213
|
+
- **Close** — a link at the end of the row, quieter than the buttons because it is the one you
|
|
214
|
+
reach for least: it closes the terminal and **not the work**. The session is stopped, its window
|
|
215
|
+
goes, and the machine gets the memory back; the card stays exactly where it is, with the colour
|
|
216
|
+
it had — the one asking you something stays red, the one holding a plan up stays amber, the one
|
|
217
|
+
at your turn stays yellow — and **Resume** takes it from there. It is what a dozen windows open
|
|
218
|
+
and a computer running out of air are answered with.
|
|
219
|
+
|
|
220
|
+
It is **not there while the session is working**: stopping one mid-thought is not memory saved,
|
|
221
|
+
it is work lost. Wait for it to come back to you, and then close it.
|
|
222
|
+
|
|
206
223
|
The only thing that asks for confirmation is throwing a card away.
|
|
207
224
|
|
|
208
225
|
Cards reorder themselves inside a column: first the ones waiting for you, then the ones grinding
|
|
@@ -216,17 +233,53 @@ right, left, up, down, and diagonally in the corners — faster the closer you a
|
|
|
216
233
|
where the board ends. The thin shadow along one side says there is still something over there.
|
|
217
234
|
Holding a mouse button keeps the board still, so a click near the edge lands.
|
|
218
235
|
|
|
219
|
-
Bottom right there is the **zoom
|
|
236
|
+
Bottom right there is the **zoom**: + and − move it ten per cent at a time — 90%, 80%, 70% and so
|
|
237
|
+
on, between 30% and 200% — and the percentage between them, clicked, goes back to 100%. The button
|
|
220
238
|
next to it shrinks just enough to fit the whole board on the screen. On a trackpad, two fingers
|
|
221
|
-
move the view and a pinch zooms
|
|
239
|
+
move the view and a pinch zooms to anything in between; the next click of + or − picks the nearest
|
|
240
|
+
step from there. Where you were is still there after a reload.
|
|
222
241
|
|
|
223
242
|
The pills at the top are both legend and filter: click one and that status leaves the board. They
|
|
224
243
|
stay as you left them.
|
|
225
244
|
|
|
226
|
-
**The
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
245
|
+
**The board keeps itself down to what you are working on.** A repository you have not touched
|
|
246
|
+
since the day before your last piece of work folds away by itself: its column leaves the board
|
|
247
|
+
and its name appears in `Old`, over on the right. There is nothing to switch on and nothing to
|
|
248
|
+
tidy up — with a dozen repositories open, you arrive in the morning and the three or four you are
|
|
249
|
+
actually on are the ones standing there, side by side.
|
|
250
|
+
|
|
251
|
+
The day is counted back from **your last piece of work, not from the clock**, and that is what
|
|
252
|
+
makes it survive a weekend: on Monday the freshest thing on the board is Friday evening, so what
|
|
253
|
+
you find is Friday — not an empty board on the one morning you most need to see where you left
|
|
254
|
+
off. The moment you start something on Monday the line moves with you.
|
|
255
|
+
|
|
256
|
+
Two things never fold. **A column with something going on in it** — working, planning, asking you
|
|
257
|
+
something, holding a plan up for approval — stays where it is however old it is: hiding the one
|
|
258
|
+
that is waiting for you is the opposite of what the board is for. A terminal simply left open at
|
|
259
|
+
**Your turn** is not one of those: it is the resting state of every window you have not closed,
|
|
260
|
+
and a session you finished with three weeks ago would otherwise hold its column at full width for
|
|
261
|
+
ever. It folds like anything else — and folding closes nothing, so the terminal is still open and
|
|
262
|
+
the card is still exactly where you left it. And **nothing folds while you are looking at it**: within one visit the set of columns can only grow, and the board tidies itself
|
|
263
|
+
on the next reload, so a column never disappears out from under your hands.
|
|
264
|
+
|
|
265
|
+
**The last two columns on the right are `Old` and `Others`**, and they are the same list twice
|
|
266
|
+
over: a `+`, a name and the git mark, in alphabetical order. `Old` is the repositories that have
|
|
267
|
+
work on the board, just not lately; `Others` is the ones that have no column because they have no
|
|
268
|
+
cards at all. **Click a row in `Old` and the column comes back** at full width for the rest of the
|
|
269
|
+
visit — with everything that was in it, which is why the row itself says nothing about how much
|
|
270
|
+
that is or how long it has been there. Both columns are also there for the same two things:
|
|
271
|
+
getting into the files of a directory you are not working on, and giving birth to the first card
|
|
272
|
+
there with the `+`.
|
|
273
|
+
|
|
274
|
+
Next to a column's `+` there is one more button, which **puts that column away now** instead of
|
|
275
|
+
waiting for it to go quiet on its own — for when you are finished with a repository for the day
|
|
276
|
+
and would rather not look at it. On a column with something going on in it the button goes faint
|
|
277
|
+
and refuses, and says why if you hover it — it does not disappear, because a column runs and goes
|
|
278
|
+
back to your turn every few seconds and it would spend the session blinking.
|
|
279
|
+
Unlike the automatic fold, this one is remembered across reloads, until you fetch the column back
|
|
280
|
+
or something in it wakes up. It **closes nothing**: no session is stopped and no terminal is
|
|
281
|
+
shut. It is the board that gets smaller, not the work — what closes a session is `Close` or `Done`
|
|
282
|
+
on a card.
|
|
230
283
|
|
|
231
284
|
### The git mark
|
|
232
285
|
|
|
@@ -246,6 +299,93 @@ k0 **never runs `git fetch`**. It only looks at what your git already knows abou
|
|
|
246
299
|
itself; a push made by somebody else does not show until you fetch. On a repository with no
|
|
247
300
|
remote, pushing is not mentioned at all.
|
|
248
301
|
|
|
302
|
+
### The globe: is the site up
|
|
303
|
+
|
|
304
|
+
Last on a column's heading, after the git mark, a small **globe** says whether that repository's
|
|
305
|
+
dev server is running. **Grey** is off, **green** is up, and it **breathes** while it is coming
|
|
306
|
+
up. **Red** means it was started and did not come up — hover it for the reason and the log.
|
|
307
|
+
|
|
308
|
+
**One click switches it on or off. Two restart it.** And when it is green the repository's
|
|
309
|
+
**name is underlined with a green dashed line** and becomes a link: click it and the site opens
|
|
310
|
+
in another tab, on the port it is really listening on. The line is the same green as the globe
|
|
311
|
+
and stays for as long as the server does, so a repository that is up is one you can tell apart
|
|
312
|
+
at a glance, from across the board, without going near it. Hover the globe to read the rest — the port, the command it was
|
|
313
|
+
started with, and where its log is.
|
|
314
|
+
|
|
315
|
+
A repository gets a globe when its `package.json` has a **`dev`** script, or failing that a
|
|
316
|
+
**`serve`** one. Nothing to configure and nothing to fill in. `start` is deliberately not on that
|
|
317
|
+
list: by convention it runs what has been *built*, which is not what this is for.
|
|
318
|
+
|
|
319
|
+
Three things are worth knowing, because they are the point.
|
|
320
|
+
|
|
321
|
+
**The server outlives the session.** k0 starts it detached and owned by nobody. Close the session
|
|
322
|
+
that asked for it, close every session, restart k0 itself — the server stays up and the globe
|
|
323
|
+
stays green. This is the whole reason it exists: a dev server started inside a session belongs to
|
|
324
|
+
that session, and dies with it.
|
|
325
|
+
|
|
326
|
+
**k0 never asks the server whether it is up.** It makes no network requests, here as everywhere
|
|
327
|
+
else. "Up" means the process is alive *and* the operating system says it is holding a TCP port
|
|
328
|
+
open. That is stronger evidence than a reply would be, and it is where the port in the tooltip
|
|
329
|
+
comes from — k0 never guesses a port, it reads the one your server actually chose.
|
|
330
|
+
|
|
331
|
+
**A server you started yourself is recognised.** Start one by hand in a terminal and the globe
|
|
332
|
+
goes green on its own within a few seconds, with the right port, and switches it off if you ask
|
|
333
|
+
it to. A globe that only knew about its own servers would sit grey next to a site that is plainly
|
|
334
|
+
running, which is worse than no globe at all. On Windows this one part is missing — nothing there
|
|
335
|
+
can read another process's working directory — and k0 says so rather than showing those servers
|
|
336
|
+
as off.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## The ChangeLog
|
|
341
|
+
|
|
342
|
+
The git mark answers "is this safe" for one repository, right now. The **ChangeLog** answers a
|
|
343
|
+
different question — *what have I actually been doing* — across all of them at once. It is the
|
|
344
|
+
list-shaped button next to the `+`, and it opens in a page of its own.
|
|
345
|
+
|
|
346
|
+
It reads like a release note rather than a report. An opening paragraph saying how the day went,
|
|
347
|
+
then one block per repository: a line saying what is different now, a short paragraph, a few
|
|
348
|
+
points, and — the part that matters most — **what is done but not out yet**. A commit sitting on
|
|
349
|
+
your machine, three changelog lines written but not closed into a version, four files never
|
|
350
|
+
committed. That is the distinction the whole page is built on: what left here, and what only
|
|
351
|
+
looks finished.
|
|
352
|
+
|
|
353
|
+
Four windows across the top: **Today**, **Yesterday**, **Week**, **Month**. It opens on none of
|
|
354
|
+
them: it opens on **the last day you actually worked**. On a Monday that is Friday, because a
|
|
355
|
+
page that comes up empty after every weekend is a page you stop opening.
|
|
356
|
+
|
|
357
|
+
**Only what you touched in that window appears.** A repository that has been dirty since March
|
|
358
|
+
and that you have not opened since is not news, and a summary that repeats it every morning is
|
|
359
|
+
one nobody is still reading by Thursday. Something has to have happened there — a commit, a file
|
|
360
|
+
saved, a card moved — before k0 will tell you what is still outstanding in it. And only **your**
|
|
361
|
+
commits are counted: k0 asks git which email you commit with in that repository and shows that
|
|
362
|
+
person's day, so a repository shared with other people still tells you about yours.
|
|
363
|
+
|
|
364
|
+
Below every block the facts are folded away, one line to open them: the commits themselves, each
|
|
365
|
+
marked green if it is online and amber if it is still only here. That is what to open when you do
|
|
366
|
+
not believe the paragraph above it.
|
|
367
|
+
|
|
368
|
+
### Who writes it
|
|
369
|
+
|
|
370
|
+
k0 does not. **k0 makes no network requests**, and that is worth more than a better paragraph: a
|
|
371
|
+
model of its own would mean a key to keep, an account to configure, and your commit messages
|
|
372
|
+
leaving this machine.
|
|
373
|
+
|
|
374
|
+
It does not need one. If you are running k0 you already have Claude Code installed, signed in and
|
|
375
|
+
paid for — that is the whole point of the board — so the model is already here. k0 works out the
|
|
376
|
+
facts, hands them to Claude Code, and shows what comes back. No terminal opens, nothing appears
|
|
377
|
+
on the board, and there is nothing to set up: the skill that does the writing ships inside the
|
|
378
|
+
package, the same way `/k0-import` does.
|
|
379
|
+
|
|
380
|
+
It is written **in your language**, without a setting anywhere, because it is written out of your
|
|
381
|
+
own commit messages and card titles.
|
|
382
|
+
|
|
383
|
+
Nothing is saved. Every time you open the page it is written again, and changing the window
|
|
384
|
+
writes it again — which is why there is no stale summary to clear and no history to prune.
|
|
385
|
+
"Today" changes while you are reading it, so keeping a copy would be wrong more often than it
|
|
386
|
+
helped. If Claude Code is not on the machine the page still opens: you get the facts, and a line
|
|
387
|
+
saying why the rest is missing.
|
|
388
|
+
|
|
249
389
|
---
|
|
250
390
|
|
|
251
391
|
## The files of a session
|
|
@@ -364,6 +504,10 @@ which on an old session says nothing about this minute. And summing the memory o
|
|
|
364
504
|
counts shared memory twice, so the total is a little generous: it is the usual approximation, and
|
|
365
505
|
it is the right one for the question that matters — which one do I close to feel better.
|
|
366
506
|
|
|
507
|
+
And once you have decided, **`Close` on that card is how you give the memory back**: the session
|
|
508
|
+
is stopped and its window goes, the work stays on the board as it was, and `Resume` picks the
|
|
509
|
+
conversation up where it left off. Nothing has to be declared finished to stop weighing.
|
|
510
|
+
|
|
367
511
|
Reading the process table costs little on a calm machine and a lot on a struggling one, which is
|
|
368
512
|
exactly when you look at it. So it is sampled every three seconds, and **only while the board is
|
|
369
513
|
open**.
|
|
@@ -380,7 +524,9 @@ numbers.
|
|
|
380
524
|
|
|
381
525
|
The difference between the two is the writing. The installer uses the name the session already
|
|
382
526
|
had, or the first few words of the first prompt. `/k0-import` has Claude read the conversation and
|
|
383
|
-
write a title and a description in the language it was held in.
|
|
527
|
+
write a title and a description in the language it was held in. That description is the line in
|
|
528
|
+
italics under the title on the note, and importing is the only thing that writes one: a card you
|
|
529
|
+
write yourself has a title and a prompt, which is all it needs.
|
|
384
530
|
|
|
385
531
|
Imported cards are born yellow — *Your turn*: **Resume** reopens the conversation where it was,
|
|
386
532
|
**Done** clears it away. Being dead sessions they do not light the tray icon. Running it again
|
|
@@ -588,33 +734,60 @@ platform/
|
|
|
588
734
|
contract.js the line between k0 and the operating system, and what an adapter must fill in
|
|
589
735
|
index.js picks the adapter, and reports what this machine can and cannot do
|
|
590
736
|
darwin/ AppleScript and Terminal.app, pmset and caffeinate, launchd, the Swift icon
|
|
737
|
+
(menubar/, which is also what posts the notifications and reads the permission)
|
|
591
738
|
linux/ tmux and any emulator, systemd-inhibit, systemd user units, a GTK tray
|
|
592
739
|
win32/ PowerShell and Windows Terminal, execution state, Task Scheduler, a WinForms tray
|
|
593
|
-
shared/ what more than one of them needs: tmux, running commands, reading a process
|
|
740
|
+
shared/ what more than one of them needs: tmux, running commands, reading a process
|
|
741
|
+
table, and reading who is holding which port
|
|
594
742
|
server/
|
|
595
743
|
index.js the http server, the API, and the watching loop that runs every second
|
|
596
|
-
|
|
744
|
+
guard.js who is allowed to talk to this server at all: the Host and the Origin
|
|
745
|
+
db.js SQLite (node:sqlite): the card, session_event, pref and dev_server tables —
|
|
746
|
+
docs/database.md
|
|
597
747
|
paths.js where the board, the logs and the cache live
|
|
598
748
|
watcher.js reads Claude Code's own files and derives the statuses; also renames a session
|
|
599
|
-
git.js the only one that talks to git: what is committed, what is pushed, whose it is
|
|
749
|
+
git.js the only one that talks to git: what is committed, what is pushed, whose it is,
|
|
750
|
+
and — for the ChangeLog — what the commits actually said
|
|
751
|
+
changelog.js gathers what happened in a window, out of git and out of session_event. Decides
|
|
752
|
+
which repositories are worth mentioning at all, and stores nothing
|
|
753
|
+
writer.js hands those facts to the Claude Code already on this machine and gets the words
|
|
754
|
+
back. The only place k0 starts a model, and it never leaves the machine to do it
|
|
600
755
|
launcher.js starts and resumes sessions, through the platform's terminal
|
|
756
|
+
servers.js the dev server of a repository: what starts it, whether it is up, and on what
|
|
757
|
+
port. The only thing k0 starts that is meant to outlive k0
|
|
601
758
|
mode.js the four modes: how awake to keep the machine, and whether the text goes large
|
|
602
759
|
projects.js the repositories, in the order you last used them
|
|
603
760
|
sessions.js digs already-lived sessions out of the transcripts, to import as cards
|
|
604
761
|
files.js the only one that reads the projects' disk: what is there, what changed, what it says
|
|
605
762
|
machine.js the only one that looks at processes and memory: what it all costs, and who is costing it
|
|
606
763
|
pdf.js the document on paper, printed by a headless browser
|
|
607
|
-
web/ the
|
|
608
|
-
index.html the board — board.js, board.css, view.js
|
|
764
|
+
web/ the three pages (html, css, js served exactly as they are)
|
|
765
|
+
index.html the board — board.js, board.css, view.js. A note is never taller than it is
|
|
766
|
+
wide: the title, the age and the buttons always show, the text in the middle is
|
|
767
|
+
what gets clipped
|
|
609
768
|
files.html the file viewer — files.js, files.css
|
|
610
|
-
|
|
769
|
+
changelog.html what you have been doing — changelog.js, changelog.css. The only page in k0 you
|
|
770
|
+
read top to bottom instead of looking at, so it is the only one that scrolls
|
|
771
|
+
base.css colours, fonts and scale: the house variables, shared by all three pages
|
|
611
772
|
md.js markdown laid out, written by hand because nothing here is compiled
|
|
773
|
+
recency.js which repositories are still warm, and which fold away into `Old`
|
|
612
774
|
fuzzy.js searching the names: the letters you type, in the order you type them
|
|
613
775
|
mentions.js which of a repository's files a piece of text names
|
|
614
776
|
refs.js what a name written inside a document points at, and which of the nine READMEs
|
|
615
777
|
.claude/skills/
|
|
616
778
|
k0-import/ the skill that fills the board with sessions you have already had
|
|
617
|
-
|
|
779
|
+
k0-changelog/ the one that turns the facts of a stretch of work into something readable. k0
|
|
780
|
+
calls it by itself when the ChangeLog is opened, so it is in the package too
|
|
781
|
+
changelog/ the one that writes the changelog and the documentation when work is finished.
|
|
782
|
+
For whoever works on k0, not for whoever uses it: it is not in the package
|
|
783
|
+
commit-push-deploy/
|
|
784
|
+
the road out: the documents, the tests, the commit, the push, and the tag that
|
|
785
|
+
publishes. Also for whoever works on k0, and also not in the package
|
|
786
|
+
docs/
|
|
787
|
+
database.md the shape of the database as it is now: the four tables, column by column
|
|
788
|
+
testing.md how the tests are written, run and measured, and what is left untested on purpose
|
|
789
|
+
test/ npm test — Node's own runner, no framework. See docs/testing.md
|
|
790
|
+
harness.mjs check(label, got, want), and the sections the labels are grouped under
|
|
618
791
|
```
|
|
619
792
|
|
|
620
793
|
### What it reads, and what it never does
|
|
@@ -630,10 +803,23 @@ writes for itself:
|
|
|
630
803
|
Sessions are launched with `--session-id` (k0 chooses the id, so the card ↔ session link is
|
|
631
804
|
certain), `-n` for the name, `--resume` to pick one up, and `--permission-mode plan` on new ones.
|
|
632
805
|
|
|
806
|
+
The ChangeLog runs Claude Code a second way: `claude -p /k0-changelog`, with the facts on
|
|
807
|
+
standard input and no terminal at all. It is the one time k0 starts a model, and it still opens
|
|
808
|
+
no socket of its own — the request is Claude Code's, made with your own account, from your own
|
|
809
|
+
machine. Those runs cannot come back as cards: `sessions.js` drops `claude -p` when it looks for
|
|
810
|
+
sessions to import, which is also how it tells a hundred and forty real sessions from eight
|
|
811
|
+
hundred automated ones.
|
|
812
|
+
|
|
633
813
|
### The traps
|
|
634
814
|
|
|
635
815
|
Field notes the code takes for granted.
|
|
636
816
|
|
|
817
|
+
- **A notification posted by `osascript` belongs to Script Editor.** `display notification` is the
|
|
818
|
+
one-line way to put a banner on screen from a script, and it works — but the banner is not
|
|
819
|
+
yours: it carries nothing, it has no delegate, and clicking it opens Script Editor with its file
|
|
820
|
+
dialog. It was in here as a fallback for when macOS would not deliver k0's own notifications,
|
|
821
|
+
and every click on it went to the wrong application. There is now one way to notify, and where
|
|
822
|
+
macOS refuses it the menu says so and takes you to the Notifications pane instead of pretending.
|
|
637
823
|
- **`--dangerously-skip-permissions` switches off plan mode.** No error, no warning, and the order
|
|
638
824
|
of the two flags changes nothing — the session starts in `bypassPermissions` and there is no
|
|
639
825
|
trace of a plan. It looks like it works, which is what makes it a trap. The only way to really
|
|
@@ -652,6 +838,23 @@ Field notes the code takes for granted.
|
|
|
652
838
|
- **The session file appears before the interface is ready to receive.** Writing at that moment
|
|
653
839
|
loses the first characters and swallows the Enter. So k0 waits until it can see the input box —
|
|
654
840
|
and where a platform cannot read a terminal's screen, it waits a fixed moment and says so.
|
|
841
|
+
- **A service's PATH is not a shell's PATH.** Under launchd it is barely more than
|
|
842
|
+
`/usr/bin:/bin`, and `npm` and `node` usually arrive from a version manager whose PATH only
|
|
843
|
+
exists inside a shell. So a dev server is started through a **login shell** — which is the same
|
|
844
|
+
reason `findClaude` ends up asking one, and it is also what puts the project's own `.nvmrc` in
|
|
845
|
+
force.
|
|
846
|
+
- **`npm run dev` is not the server, it is the thing that starts it.** SIGTERM to npm alone leaves
|
|
847
|
+
`vite` holding the port, which is why the old per-repo skills all ended up reaching for
|
|
848
|
+
`pkill -f`. k0 starts the server **detached**, so it leads a process group of its own, and
|
|
849
|
+
stops the *group*. But only when the process it was told about really is that group's leader:
|
|
850
|
+
a server somebody started by hand in a shell without job control can share its group with the
|
|
851
|
+
**shell**, and signalling that would close the user's terminal to stop a dev server. Where the
|
|
852
|
+
leader is somebody else, the processes are signalled one at a time instead.
|
|
853
|
+
- **A remembered pid is only a number, and the system hands numbers out again.** A row written
|
|
854
|
+
before a reboot can point at a stranger's process — and that row is what a click on the globe
|
|
855
|
+
would kill. So a remembered server is only believed while the process at that pid is still
|
|
856
|
+
running the command it was started with, and `stop` reads the machine before it signals
|
|
857
|
+
anything rather than trusting what it stored.
|
|
655
858
|
- **`do script … in tab 1 of window id N`** writes into the interface with no simulated keystrokes
|
|
656
859
|
and no permissions, but it **always adds the Enter**. You can hold the Enter back with a
|
|
657
860
|
trailing backslash, but the backslash stays on screen and forces two presses: tried and rejected.
|