@ajaykumarnpm/talea 0.2.0 → 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the versions follow
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.2.2] - 2026-09-21
8
+
9
+ ### Documentation
10
+ - the skip marker is read from the commit body too
11
+
12
+ ### Chores
13
+ - publish before pushing the tag
14
+ - the pipeline cuts the release, not a laptop
15
+
16
+ ## [0.2.1] - 2026-09-21
17
+
18
+ ### Fixed
19
+ - The live block no longer repeats itself down the screen. A row wider than the
20
+ terminal wrapped onto a second line, which threw off the cursor arithmetic the
21
+ block redraws with, so every frame landed a line lower than the last. Rows are
22
+ now cut to the window width.
23
+
24
+ ### Chores
25
+ - Releases are published by a GitHub release rather than by pushing a tag, and
26
+ npm authenticates with trusted publishing instead of a stored token.
27
+
28
+ ## [0.2.0] - 2026-09-21
29
+
30
+ ### Added
31
+ - `ignore: true` in the catalogue marks a checkout that another tool owns. No
32
+ command touches it — not `sync`, not `adopt`, not an explicit selection.
33
+
34
+ ### Fixed
35
+ - `init` defaults to `~/Workspace` and refuses to turn your home directory into
36
+ a workspace.
37
+ - `adopt` moves a repo's worktrees with it and repairs their links, instead of
38
+ leaving them stranded.
39
+ - A repo that matches only by name is never moved unattended. Say `--loose`, or
40
+ name it with `-r`, to move one anyway.
41
+
42
+ ## [0.1.0] - 2026-09-21
43
+
44
+ ### Added
45
+ - First published release: `discover`, `clone`, `sync`, `adopt`, `add`, `rm`,
46
+ `where`, `status` and `doctor`, the live progress block, and the shared
47
+ catalogue with a per-machine selection that never travels with it.
48
+ - Published as `@ajaykumarnpm/talea` — npm's typo-squatting filter refused the
49
+ bare name.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ajaykumarnpm/talea",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "One folder structure for every machine. Clone, adopt and sync your GitHub repos from a manifest you own.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,8 @@
17
17
  "src",
18
18
  "manifest",
19
19
  "templates",
20
- "README.md"
20
+ "README.md",
21
+ "CHANGELOG.md"
21
22
  ],
22
23
  "scripts": {
23
24
  "test": "node --test"
package/src/live.js CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  paint,
20
20
  spinner,
21
21
  statusLine,
22
+ truncVisible,
22
23
  visibleWidth,
23
24
  } from './log.js';
24
25
 
@@ -95,10 +96,18 @@ export function board(items, { live = process.stdout.isTTY } = {}) {
95
96
  drawn = 0;
96
97
  };
97
98
 
99
+ // One line, one row. A line wider than the window wraps, and then `drawn` —
100
+ // a count of lines, not of rows — climbs back too few rows and the next frame
101
+ // is drawn below the last one instead of over it. That is how the block ends
102
+ // up repeating itself down the screen with half-cleared remnants in between.
103
+ // The last column is left empty: a line filling the row exactly leaves some
104
+ // terminals in a deferred-wrap state that the following newline then spends.
105
+ const fitRow = (l) => truncVisible(l, Math.max(1, (process.stdout.columns || 80) - 1));
106
+
98
107
  const draw = () => {
99
108
  const body = lines();
100
109
  let s = (drawn ? ansi.up(drawn) : '') + ansi.cr;
101
- for (const l of body) s += ansi.clearLine + l + '\n';
110
+ for (const l of body) s += ansi.clearLine + fitRow(l) + '\n';
102
111
  // The previous block may have been taller — clear what is left of it, then
103
112
  // put the cursor back under the new one.
104
113
  const extra = Math.max(0, drawn - body.length);
package/src/log.js CHANGED
@@ -17,11 +17,12 @@ import {
17
17
  padEndVisible,
18
18
  spinner,
19
19
  stripAnsi,
20
+ truncVisible,
20
21
  useColor,
21
22
  visibleWidth,
22
23
  } from './theme.js';
23
24
 
24
- export { ansi, glyph, padEndVisible, paint, spinner, useColor, visibleWidth };
25
+ export { ansi, glyph, padEndVisible, paint, spinner, truncVisible, useColor, visibleWidth };
25
26
 
26
27
  /**
27
28
  * Named colours, kept because every command's `help` string and most inline
package/src/theme.js CHANGED
@@ -136,3 +136,37 @@ export function centerVisible(s, width) {
136
136
 
137
137
  /** Terminal width, clamped to something a human can read across. */
138
138
  export const columns = () => Math.max(40, Math.min(process.stdout.columns || 80, 120));
139
+
140
+ /**
141
+ * Cut a string to `width` visible columns, leaving its escape codes intact.
142
+ *
143
+ * The live block redraws by counting the lines it wrote and climbing back up
144
+ * that many. A line wider than the window wraps onto two rows, so the count is
145
+ * short by one and every redraw lands a row lower — the block duplicates itself
146
+ * down the screen. Truncating keeps one line to one row.
147
+ */
148
+ export function truncVisible(s, width) {
149
+ const str = String(s);
150
+ if (width <= 0) return '';
151
+ if (visibleWidth(str) <= width) return str;
152
+ let left = width;
153
+ let out = '';
154
+ // eslint-disable-next-line no-control-regex
155
+ for (const part of str.split(/(\x1b\[[0-9;?]*[A-Za-z])/)) {
156
+ if (!part) continue;
157
+ if (part.startsWith('\x1b[')) {
158
+ out += part;
159
+ continue;
160
+ }
161
+ const chars = [...part];
162
+ if (chars.length <= left) {
163
+ out += part;
164
+ left -= chars.length;
165
+ } else {
166
+ out += chars.slice(0, left).join('');
167
+ left = 0;
168
+ }
169
+ }
170
+ // Cut mid-colour, so close it — otherwise the colour bleeds down the screen.
171
+ return out + (useColor ? '\x1b[0m' : '');
172
+ }