@lamemind/loom-deck 0.65.0 → 0.65.1

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/dist/layout.js CHANGED
@@ -3,6 +3,7 @@
3
3
  // da scalare va tolta in un posto solo, o due chiamanti tolgono cose diverse
4
4
  // dalla stessa larghezza e il bordo viene mangiato.
5
5
  import { stripProjectCore } from './session-list.js';
6
+ import { SID_CHARS } from './glyphs.js';
6
7
  /**
7
8
  * Lunghezza in CODE POINT. Il caret ci indicizza sopra: `.length` conterebbe le
8
9
  * code unit UTF-16 e un'emoji nel titolo varrebbe 2 posizioni, cioè un cursore
@@ -96,6 +97,22 @@ export function assignTextWidth(columns) {
96
97
  export function previewTextWidth(columns) {
97
98
  return Math.max(10, (columns || 80) - 8);
98
99
  }
100
+ /**
101
+ * I tre pezzi della riga d'apertura del blocco preview di una conversazione —
102
+ * sid, nota, titolo — ognuno col proprio separatore in coda, pronti per
103
+ * `cutParts` sul budget di `previewTextWidth`.
104
+ *
105
+ * Esistono come funzione, e il taglio passa da `cutParts`, per l'invariante ③
106
+ * (§`assignTextWidth` sopra): lasciare la riga a `wrap="truncate-end"` la fa
107
+ * tagliare da `cli-truncate`, che sfora di una colonna per emoji e mangia il
108
+ * bordo destro del box. Due dei tre pezzi portano testo libero — la nota la
109
+ * scrive l'utente, e un titolo di conversazione auto-generato apre col prefisso
110
+ * `[ <emoji> ]` — quindi le emoji su questa riga sono il caso normale, non il
111
+ * limite.
112
+ */
113
+ export function previewTitleParts(sessionId, note, title) {
114
+ return [`${sessionId.slice(0, SID_CHARS)} `, note ? `${note} ` : '', title];
115
+ }
99
116
  /**
100
117
  * Larghezza del TESTO dentro un pane al 50%: box esterno (2 bordi + 2 padding)
101
118
  * → metà → bordo + padding del pane.
@@ -2,9 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  // Blocco preview a piena larghezza sotto i due pane: mostra la task o la
3
3
  // conversazione selezionata a seconda del pane a fuoco.
4
4
  import { Box, Text } from 'ink';
5
- import { cut, wrapLines } from '../width.js';
6
- import { previewTextWidth } from '../layout.js';
7
- import { LIVE_BUSY, LIVE_IDLE, META_KEYS, SID_CHARS, fmtDateTime, fmtSize, modelAlias, } from '../glyphs.js';
5
+ import { cut, cutParts, wrapLines } from '../width.js';
6
+ import { previewTextWidth, previewTitleParts } from '../layout.js';
7
+ import { LIVE_BUSY, LIVE_IDLE, META_KEYS, fmtDateTime, fmtSize, modelAlias, } from '../glyphs.js';
8
8
  import { NATURA_SHORT, inboxMark } from '../inbox.js';
9
9
  import { ChoiceRow } from './fields.js';
10
10
  import { MODELS } from '../spawn.js';
@@ -64,7 +64,12 @@ export function SessionPreview({ s, firstLines, lastLines, columns, origin, note
64
64
  // non c'è una provenienza vera da dichiarare.
65
65
  const originAlias = modelAlias(s.model);
66
66
  const originIndex = originAlias ? MODELS.indexOf(originAlias) : undefined;
67
- return (_jsxs(_Fragment, { children: [_jsxs(Text, { bold: true, wrap: "truncate-end", children: [_jsx(Text, { color: "cyan", children: s.sessionId.slice(0, SID_CHARS) }), ' ', note ? _jsxs(Text, { color: "yellow", children: [note, " "] }) : null, _jsx(Text, { dimColor: Boolean(note), children: s.title })] }), _jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [fmtSize(s.sizeBytes), " \u00B7 ", s.turns, " turni \u00B7 ", fmtDateTime(s.ts), " \u00B7 ", s.gitBranch || '-', s.model ? ` · ${s.model}` : '', origin ? ` · ⑂ da ${origin.slice(0, 8)}` : '', live ? (_jsx(Text, { color: live.status === 'busy' ? 'yellow' : 'green', children: ` · ${live.status === 'busy' ? LIVE_BUSY : LIVE_IDLE} viva pid ${live.pid} (${live.status})` })) : null] }), _jsx(ChoiceRow, { label: "modello", values: MODELS, index: Math.max(0, MODELS.indexOf(resumeModel)), focused: false, width: previewTextWidth(columns), originIndex: originIndex }), first.map((line, i) => (_jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [i === 0 ? '» ' : ' ', line] }, `f${i}`))), last.map((line, i) => (_jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [i === 0 ? '« ' : ' ', line] }, `l${i}`)))] }));
67
+ // La riga del titolo si taglia QUI, con la contabilità del deck, invece di
68
+ // lasciarla a `wrap="truncate-end"`: Ink taglia con `cli-truncate`, che sfora
69
+ // di una colonna per emoji (invariante ③ di width.ts) e mangia il bordo del
70
+ // box. Pezzi e ragione stanno in `previewTitleParts`.
71
+ const [sidPart, notePart, titlePart] = cutParts(previewTitleParts(s.sessionId, note, s.title), previewTextWidth(columns));
72
+ return (_jsxs(_Fragment, { children: [_jsxs(Text, { bold: true, wrap: "truncate-end", children: [_jsx(Text, { color: "cyan", children: sidPart }), notePart ? _jsx(Text, { color: "yellow", children: notePart }) : null, _jsx(Text, { dimColor: Boolean(note), children: titlePart })] }), _jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [fmtSize(s.sizeBytes), " \u00B7 ", s.turns, " turni \u00B7 ", fmtDateTime(s.ts), " \u00B7 ", s.gitBranch || '-', s.model ? ` · ${s.model}` : '', origin ? ` · ⑂ da ${origin.slice(0, 8)}` : '', live ? (_jsx(Text, { color: live.status === 'busy' ? 'yellow' : 'green', children: ` · ${live.status === 'busy' ? LIVE_BUSY : LIVE_IDLE} viva pid ${live.pid} (${live.status})` })) : null] }), _jsx(ChoiceRow, { label: "modello", values: MODELS, index: Math.max(0, MODELS.indexOf(resumeModel)), focused: false, width: previewTextWidth(columns), originIndex: originIndex }), first.map((line, i) => (_jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [i === 0 ? '» ' : ' ', line] }, `f${i}`))), last.map((line, i) => (_jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [i === 0 ? '« ' : ' ', line] }, `l${i}`)))] }));
68
73
  }
69
74
  /**
70
75
  * Righe non-wrappabili del dettaglio (titolo + meta + commit) e loro conteggio.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lamemind/loom-deck",
3
- "version": "0.65.0",
3
+ "version": "0.65.1",
4
4
  "description": "Deck TUI Ink per-progetto della famiglia loom: legge tasks.md e spawna sessioni Claude Code bound via LOOM_TASK",
5
5
  "type": "module",
6
6
  "bin": {