k0-board 0.6.0 → 0.7.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.
@@ -240,12 +240,12 @@ the Log records as merged is ever done twice.
240
240
 
241
241
  ## 10. Close
242
242
 
243
- To the user, in his language, and nothing after it:
243
+ To the user, in his language — the two headings too — and nothing after it:
244
244
 
245
- **Cosa ho fatto** — what is different now, story by story: whether the tests were green, what the
245
+ **What I did** — what is different now, story by story: whether the tests were green, what the
246
246
  fresh pair of eyes said, how the counter-check came out.
247
247
 
248
- **Cosa resta a te** — the assumptions taken alone, so he can overturn any of them with
248
+ **What is left for you** — the assumptions taken alone, so he can overturn any of them with
249
249
  `/k0-discuss`; the assignments left out and what they needed; whatever the repairs did not fix; and
250
250
  that the stories are sitting in `Review` waiting for him to press `Done`, which is his and nobody
251
251
  else's.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,34 @@ All notable changes to this project are documented here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+
10
+ ## [0.7.0]
11
+
12
+ k0 gets a public home at k0-board.com, where you can read what it does and ask for an early-access
13
+ account, and asking now sends you an email that says you are on the list. On your own machine, the
14
+ terminals k0 opens keep a margin at the edge of the screen in every mode again, Driving included.
15
+
16
+ ### Added
17
+
18
+ - **k0-board.com has a home page.** What k0 does, how to start, the plans it is heading for —
19
+ nothing is charged during early access — and a form to ask for an account, which says you are on
20
+ the list the moment you send it. Privacy and terms pages say plainly what is stored and where. It
21
+ follows the light or dark setting of your system, and reads on a phone.
22
+ - **Asking for early access sends an email.** The person who asked gets a line saying they are on the
23
+ list, and whoever runs k0 is told — about that, and about anybody who signs in and is waiting to be
24
+ let in. Mail to the address on the site reaches a person. Tried for real: the notice and a
25
+ forwarded message both arrived.
26
+
27
+ ### Changed
28
+
29
+ - **Terminals keep a margin in every mode, Driving included.** A terminal k0 opens or rearranges
30
+ takes 90% of the free screen, centred, so there is always a strip at the edge to click on. Driving
31
+ still makes the text large, but no longer stretches the window across the whole screen.
32
+ - **The last Italian leftovers are gone.** The board no longer answers to `#nuovo` (`#new` still
33
+ opens a new story), and a document's title is read from `title` or `name` only, no longer from
34
+ `titolo` or `nome`.
35
+
36
+
9
37
  ## [0.6.0]
10
38
 
11
39
  k0 gets an account and a cloud. The board still runs on your machine and keeps working with no
@@ -761,7 +789,8 @@ here is everything that had to change for it to be somebody else's tool as well.
761
789
  - The personal fixtures k0 grew up on. `test/clean.test.mjs` now fails the build if any of them
762
790
  come back.
763
791
 
764
- [Unreleased]: https://github.com/alessio-ragni/k0-board/compare/v0.6.0...HEAD
792
+ [Unreleased]: https://github.com/alessio-ragni/k0-board/compare/v0.7.0...HEAD
793
+ [0.7.0]: https://github.com/alessio-ragni/k0-board/compare/v0.6.0...v0.7.0
765
794
  [0.6.0]: https://github.com/alessio-ragni/k0-board/compare/v0.5.0...v0.6.0
766
795
  [0.5.0]: https://github.com/alessio-ragni/k0-board/compare/v0.4.0...v0.5.0
767
796
  [0.4.0]: https://github.com/alessio-ragni/k0-board/compare/v0.3.0...v0.4.0
package/README.md CHANGED
@@ -346,8 +346,8 @@ are still one counter for the whole board rather than one per repository, kept o
346
346
  work and check keep a task per step — so without it they would be asking for a tool that is not
347
347
  there.
348
348
 
349
- The window is born **centred on the screen you are using**, at 86% of the free space: the same
350
- margin on all four sides, never under a menu bar or a dock. Open more than one and they stack
349
+ The window is born **centred on the screen you are using**, at 90% of the free space, in every mode:
350
+ the same margin on all four sides, never under a menu bar or a dock. Open more than one and they stack
351
351
  in the middle — double click brings the one underneath back.
352
352
 
353
353
  **If the screen changes** — you plug a monitor in or out, or change resolution — the windows put
@@ -1521,7 +1521,7 @@ one again does nothing — you leave a mode, you do not switch it off.
1521
1521
  | two **z** | **Sleep** | sleeps as it normally would | goes off | normal |
1522
1522
  | a **palm tree** | **Away** | does not sleep, not even with the lid closed | may sleep and lock | normal |
1523
1523
  | a **nerd face** with glasses | **Nerd** | does not sleep | **stays on** | normal |
1524
- | a **car** | **Driving** | does not sleep | **stays on** | **large**: the text here and in the terminals, and the terminals fill the screen |
1524
+ | a **car** | **Driving** | does not sleep | **stays on** | **large**: the text here and in the terminals |
1525
1525
 
1526
1526
  The four icons do not describe the machine: they describe **where you are**. Asleep, away, at the
1527
1527
  desk, watching from across the room. That is where the order comes from, and it is why the second
@@ -1569,17 +1569,22 @@ they reorder by urgency, reddest to the left. On a screen you glance at, two or
1569
1569
  visible at a time and the most urgent one has to come to you. Full screen you have them all in
1570
1570
  front of you already, and a board that reshuffles itself while you work only loses your place.
1571
1571
 
1572
- **The windows grow with the text.** In Driving a terminal takes the whole free screen; leave
1573
- Driving and it goes back to the usual 86% centred, with the text back at the profile's size. It is
1574
- one gesture and not two, and it lands on the terminals **already open**, not only on the ones you
1575
- open next.
1572
+ **The windows keep their margin.** In every mode, Driving included, a terminal takes 90% of the
1573
+ free screen, centred, with the same strip left free on all four sides — that strip is where you
1574
+ click to reach whatever is behind it. Driving changes the text, not the share: switch it on and the
1575
+ terminals get 22 point text and are put back at 90% centred; switch it off and the text goes back
1576
+ to the profile's size. It is one gesture and not two, and it lands on the terminals **already
1577
+ open**, not only on the ones you open next.
1578
+
1579
+ For a while Driving took the whole free screen instead, which left nothing at the edge to click on;
1580
+ the margin is worth more than the last tenth of the screen.
1576
1581
 
1577
1582
  It used to be the opposite, and the reason is worth keeping in mind: Terminal.app holds rows and
1578
1583
  columns when the font changes and resizes the window to match — going from 12 to 22 turns a 700×500
1579
1584
  window into 1378×856, measured — so k0 read each window's own bounds first and put them back, and
1580
1585
  nothing moved. What that left behind was a window holding 22 point text in a box measured for 12.
1581
- Half a gesture is worse than none, so the size of the text and the size of the window now travel
1582
- together, and the price is said plainly: **a window you had dragged onto another screen comes back
1586
+ Half a gesture is worse than none, so the text is set first and the window put back at its share
1587
+ right after, and the price is said plainly: **a window you had dragged onto another screen comes back
1583
1588
  to the middle of the main one.**
1584
1589
 
1585
1590
  **All of them, every time.** k0 asks Terminal once for the windows it has open and changes those
@@ -1849,8 +1854,10 @@ web/ the four pages (html, css, js served exactly as they are)
1849
1854
  supabase/ k0 Cloud's own side: migrations/ is its database (accounts, workspaces, the
1850
1855
  rows of every board, the counter), config.toml its sign-in settings. The secrets
1851
1856
  are in ~/.config/k0-cloud/.env, never in the repository
1852
- site/ k0-board.com: static pages, no build. app/ is the read-only web board and the
1853
- page where accounts are approved — both coming with the site
1857
+ site/ k0-board.com: static pages, no build, deployed as they are. index.html is the
1858
+ home page with the early-access form (waitlist.js), privacy, terms and 404
1859
+ beside it, one site.css; app/ is the read-only web board and the page where
1860
+ accounts are approved
1854
1861
  docs/
1855
1862
  database.md the shape of the database as it is now, table by table, column by column
1856
1863
  method.md why a decision has to be an object, what a round of questions is for, and
@@ -1860,6 +1867,11 @@ test/ npm test — Node's own runner, no framework. See docs/testing.
1860
1867
  harness.mjs check(label, got, want), and the sections the labels are grouped under
1861
1868
  ```
1862
1869
 
1870
+
1871
+ Two small pieces live outside the app because they run in the cloud, not on your machine:
1872
+ `supabase/functions/notify` sends the emails k0 Cloud sends (an early-access request, an account
1873
+ waiting to be let in), and `infra/mail-forward` forwards mail sent to the site's contact address.
1874
+ Neither ships in the npm package. Where each one runs and how it is put online: `docs/cloud.md`.
1863
1875
  ### How the board reaches the cloud
1864
1876
 
1865
1877
  The board's rules live on the machine, in SQLite, and they stay there: states, decisions, rounds,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k0-board",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "A board of sticky notes that drives your Claude Code sessions",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -17,8 +17,11 @@ const PBPASTE = () => which('pbpaste', ['/usr/bin/pbpaste'])
17
17
  /** Escape for an AppleScript string literal. */
18
18
  const asq = (s) => String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"')
19
19
 
20
- /** How much of the free screen area a window takes unless somebody asks for more. */
21
- const COVERAGE = 0.86
20
+ /**
21
+ * How much of the free screen area a window takes, in every mode: the rest is margin, and the
22
+ * margin is where you click to reach whatever is behind it.
23
+ */
24
+ const COVERAGE = 0.9
22
25
 
23
26
  /**
24
27
  * How long a pass over the open windows may take. The five seconds `run` gives every other
@@ -28,9 +31,6 @@ const COVERAGE = 0.86
28
31
  */
29
32
  const PASS_TIMEOUT = 20000
30
33
 
31
- /** In driving mode the terminal has to be readable from across the room. */
32
- export const DRIVING_FONT_SIZE = 22
33
-
34
34
  /**
35
35
  * The profile's font size, asked once and then remembered. It is what we go back to when
36
36
  * driving mode is switched off; hard-coding a 12 here would be right today and wrong the
@@ -51,8 +51,7 @@ export async function defaultFontSize() {
51
51
  * same for all of them: otherwise the first time a monitor is unplugged every window would
52
52
  * change size for no reason.
53
53
  *
54
- * `coverage` is how much of the free area the window takes: the usual share, or all of it when
55
- * the mode wants windows readable from across the room.
54
+ * `coverage` is how much of the free area the window takes; left out, it is the usual share.
56
55
  *
57
56
  * Leaves `x1`, `y1`, `w` and `h` behind, which is what `bounds` needs.
58
57
  */
@@ -36,8 +36,8 @@ const EMULATORS = [
36
36
  { bin: 'xterm', args: (cmd) => ['-e', ...cmd] },
37
37
  ]
38
38
 
39
- /** How much of the work area a window takes unless the mode asks for more. */
40
- const COVERAGE = 0.86
39
+ /** How much of the work area a window takes, in every mode: the rest is margin. */
40
+ const COVERAGE = 0.9
41
41
 
42
42
  /**
43
43
  * Which emulator to open. `K0_TERMINAL` wins, because no list of ours will ever cover every
@@ -26,8 +26,8 @@ import { ps, psJson, psq } from './powershell.js'
26
26
  const WT = () => which('wt')
27
27
  const POWERSHELL_BIN = () => which('pwsh') || which('powershell')
28
28
 
29
- /** How much of the work area a window takes unless the mode asks for more. */
30
- const COVERAGE = 0.86
29
+ /** How much of the work area a window takes, in every mode: the rest is margin. */
30
+ const COVERAGE = 0.9
31
31
 
32
32
  /** The user32 declarations every window operation here needs, added once per PowerShell run. */
33
33
  const USER32 = `
@@ -100,25 +100,23 @@ export async function renameLive(story) {
100
100
  /** In driving mode the terminal has to be readable from across the room. */
101
101
  const DRIVING_FONT_SIZE = 22
102
102
 
103
- /** And a window worth glancing at from there takes the whole screen, not its usual share of it. */
104
- const DRIVING_COVERAGE = 1
105
-
106
- /** How big the text has to be right now: it depends only on the mode in force. */
103
+ /**
104
+ * How big the text has to be right now: it depends only on the mode in force. The window does
105
+ * not: it keeps its usual share of the screen in every mode, because the margin around it is
106
+ * where you click to get past it.
107
+ */
107
108
  const fontSize = () => (isDriving() ? Promise.resolve(DRIVING_FONT_SIZE) : terminal.defaultFontSize())
108
109
 
109
- /** And how much screen the window takes. Undefined means "your usual share", whatever it is. */
110
- const coverage = () => (isDriving() ? DRIVING_COVERAGE : undefined)
111
-
112
110
  /**
113
111
  * Puts every window k0 owns the way the mode in force wants it, text and size in one gesture.
114
112
  * It runs on every mode change and once more at startup, which is what repairs the windows a
115
113
  * server restart left behind at the wrong size.
116
114
  */
117
115
  export async function applyModeToWindows(handles) {
118
- return terminal.applyMode(handles, { fontSize: await fontSize(), coverage: coverage() })
116
+ return terminal.applyMode(handles, { fontSize: await fontSize() })
119
117
  }
120
118
 
121
- export const relayoutWindows = (handles) => terminal.relayout(handles, { coverage: coverage() })
119
+ export const relayoutWindows = (handles) => terminal.relayout(handles)
122
120
  export const setWindowTitle = (handle, title) => terminal.setTitle(handle, title)
123
121
  export const focusWindow = (handle, title) => terminal.focus(handle, title)
124
122
  export const closeTerminal = ({ winId, pid }) => terminal.close({ handle: winId, pid })
@@ -209,7 +207,7 @@ export async function launch({ story, sessionId, mode = 'start' }) {
209
207
  if (autoSend) args.push(story.prompt.trim())
210
208
 
211
209
  const command = terminal.buildCommand({ cwd: story.project_path, bin, args, env: SESSION_ENV })
212
- const winId = await terminal.open({ command, title: name, fontSize: await fontSize(), coverage: coverage() })
210
+ const winId = await terminal.open({ command, title: name, fontSize: await fontSize() })
213
211
  const up = await waitForSession(sessionId)
214
212
 
215
213
  if (autoSend) return { name, up, winId, pasted: true, autoSent: true }
package/web/board.js CHANGED
@@ -2077,7 +2077,7 @@ async function boot() {
2077
2077
  whileVisible(refresh, 1000, 4000)
2078
2078
 
2079
2079
  // A direct link: k0 opened with the new story already in front of you.
2080
- if (location.hash === '#new' || location.hash === '#nuovo') openEditor(null)
2080
+ if (location.hash === '#new') openEditor(null)
2081
2081
  // And the other direct link, the one the Usage page makes: a session's story, already open.
2082
2082
  const wanted = /^#story-(\d+)$/.exec(location.hash)
2083
2083
  if (wanted) {
package/web/files.js CHANGED
@@ -956,7 +956,7 @@ function plate(data) {
956
956
  </div>`
957
957
  }
958
958
 
959
- const TITLE_KEYS = new Set(['title', 'titolo', 'name', 'nome'])
959
+ const TITLE_KEYS = new Set(['title', 'name'])
960
960
 
961
961
  /**
962
962
  * Hand a path to the file manager. The same call for a file and for a folder: which of the two