heyquilt 0.3.141 → 0.3.142

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/RELEASES.md CHANGED
@@ -11,6 +11,10 @@ Format: `## <version> — <YYYY-MM-DD>`, an optional one-line summary, then bull
11
11
  Lead each bullet with a short bold phrase. Inline `code` and **bold** are rendered;
12
12
  nothing else is.
13
13
 
14
+ ## 0.3.142 — 2026-11-01
15
+
16
+ - **The source control button names your square by its branch.** It said `sq:09a100d0`, which meant nothing to anyone; it now says `main` (or whichever branch your folder is on), and so do its panel and the Squares list. The panel also says plainly that the files waiting to be committed are everyone's edits on that branch, not only yours.
17
+
14
18
  ## 0.3.141 — 2026-11-01
15
19
 
16
20
  - **A new, empty folder joining a session that is already in Seam takes the square as it is.** Its first files come from the session's old copy of the branch, and before, a folder without git could start following its square while that old copy was still being written to it, so every older file went into the square as its own edits (an agent's new folder put 166 stale files into main's square). Now the folder's own syncing stops before it follows the square, and nothing it got from the session is ever counted as its edits.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyquilt",
3
- "version": "0.3.141",
3
+ "version": "0.3.142",
4
4
  "description": "Real-time, tool-agnostic pair vibe coding: sync a project folder live between collaborators using any AI coding tool.",
5
5
  "author": {
6
6
  "name": "Daniel Carmichael",
@@ -17,12 +17,22 @@ const quiltName = (st) => (st.quilt && (st.quilt.slug || st.quilt.id)) || 'the q
17
17
  /** The square this folder follows, as Seam names it (`sq:` and the end of its id), or ''. */
18
18
  export const squareName = (st) => (st && st.square && st.square.short ? `sq:${st.square.short}` : '')
19
19
 
20
+ /** The branch whose square this folder follows (`st.squares` is branch -> square name), or ''. */
21
+ export function squareBranch (st) {
22
+ const name = squareName(st)
23
+ const hit = name && Object.entries(st.squares || {}).find(([, sq]) => sq === name)
24
+ return hit ? hit[0] : (name && st.branch) || ''
25
+ }
26
+
27
+ /** The square as a person reads it: its branch (a square's id means nothing to anyone), or its id when no branch is known. */
28
+ const squareWords = (st) => squareBranch(st) || squareName(st)
29
+
20
30
  /**
21
31
  * The source control button at layout 3: { label, title, aria } for the square this folder follows, or
22
32
  * why it follows none yet. `label` '' leaves the button with its icon and count only.
23
33
  */
24
34
  export function seamChip (st) {
25
- const name = squareName(st)
35
+ const name = squareWords(st)
26
36
  const s = st.square
27
37
  const label = name
28
38
  const title = st.moving ? movingCard(st).text
@@ -30,13 +40,13 @@ export function seamChip (st) {
30
40
  : st.readOnly && !(s && !s.opening && !s.problem)
31
41
  ? `Your edits here are not reaching anyone: ${st.readOnly.why}`
32
42
  : !s ? `This session's code is committed and merged in Seam (${quiltName(st)}), and this folder is not following a square yet.`
33
- : s.problem ? `This folder's work belongs in square ${name}, but it can't follow it yet: ${s.problem}`
34
- : s.opening ? `This folder is starting to follow square ${name}.`
35
- : [`This folder's work is live in square ${name} of ${quiltName(st)}. Click to commit it or merge it onto main.`, ...catchUpWords(s)].join(' ')
36
- // The number is the square's work not committed yet (everyone's on it): what a commit takes.
43
+ : s.problem ? `This folder's work belongs on ${name}, but it can't follow it yet: ${s.problem}`
44
+ : s.opening ? `This folder is starting to follow ${name}.`
45
+ : [`This folder's work is live on ${name} in ${quiltName(st)}, with everyone else's there. Click to commit it or merge it onto main.`, ...catchUpWords(s)].join(' ')
46
+ // The number is the square's work not committed yet (everyone's on it, not only yours): what a commit takes.
37
47
  const count = s && s.work ? s.work.count : 0
38
- const countLine = count ? `${files(count)} not committed in this square.` : ''
39
- return { label, title, aria: `Source control: ${name ? `square ${name}` : 'Seam'}${count ? `, ${files(count)} not committed` : ''}`, count, countLine }
48
+ const countLine = count ? `${files(count)} changed on ${name} and not committed yet, by everyone on it.` : ''
49
+ return { label, title, aria: `Source control: ${name || 'Seam'}${count ? `, ${files(count)} not committed` : ''}`, count, countLine }
40
50
  }
41
51
 
42
52
  const files = (n) => `${n} file${n === 1 ? '' : 's'}`
@@ -98,10 +108,10 @@ export function squareCard (st) {
98
108
  */
99
109
  export function squarePanelHtml (st, { busy = '' } = {}) {
100
110
  const s = st.square
101
- const name = squareName(st)
111
+ const name = squareWords(st)
102
112
  const following = s && !s.opening && !s.problem
103
113
  const viewer = !!(st.access && st.access.role === 'viewer')
104
- const head = `<div class="br-here sq-here"><div class="br-title">${name ? `Square <b>${esc(name)}</b> of ${esc(quiltName(st))}` : `Code committed and merged in Seam: <b>${esc(quiltName(st))}</b>`}</div>`
114
+ const head = `<div class="br-here sq-here"><div class="br-title"${squareName(st) ? ` title="Seam's square ${esc(squareName(st))}"` : ''}>${name ? `Live work on <b>${esc(name)}</b> in ${esc(quiltName(st))}` : `Code committed and merged in Seam: <b>${esc(quiltName(st))}</b>`}</div>`
105
115
  // While the session moves, nothing is committed or merged from here: the move is what it waits for.
106
116
  if (st.moving) return `${head}<div class="br-sub warn">${esc(movingCard(st).text)}</div></div>`
107
117
  if (st.squareless) {
@@ -112,13 +122,13 @@ export function squarePanelHtml (st, { busy = '' } = {}) {
112
122
  const why = st.readOnly ? st.readOnly.why : s ? s.line : 'This folder is not following a square yet: Quilt opens it by itself once the session says which.'
113
123
  return `${head}<div class="br-sub${st.readOnly || (s && s.problem) ? ' warn' : ''}">${esc(why)}</div></div>`
114
124
  }
115
- const sub = '<div class="br-sub">Every edit here is live for everyone on this square. Commit it to keep a version; merge it to put it on main (GitHub gets main from Seam by itself).</div>'
125
+ const sub = `<div class="br-sub">Everyone on ${esc(name)} edits this together, live: the files below are everyone's edits, not only yours. Commit them to keep a version; merge them to put them on main (GitHub gets main from Seam by itself).</div>`
116
126
  const caught = catchUpWords(s)
117
127
  const work = (caught.length ? `<div class="br-sub${s.conflicted ? ' warn' : ''}">${esc(caught.join(' '))}</div>` : '') + workHtml(s.work)
118
128
  if (viewer) return `${head}${sub}${work}</div>`
119
129
  return `${head}${sub}${work}
120
130
  <form class="cp-commit" data-square-commit><input class="input" name="message" placeholder="What this commit is" aria-label="Commit message" maxlength="2000" required autocomplete="off"${busy ? ' disabled' : ''}><button type="submit" class="btn sm primary"${busy ? ' disabled' : ''}>${busy === 'commit' ? 'Committing…' : 'Commit'}</button></form>
121
- <div class="sq-acts"><button type="button" class="btn sm" data-square-merge${busy ? ' disabled' : ''} title="Commits what is not committed yet, then merges ${esc(name)} onto main once its checks pass">${busy === 'merge' ? 'Merging…' : 'Merge onto main'}</button></div>
131
+ <div class="sq-acts"><button type="button" class="btn sm" data-square-merge${busy ? ' disabled' : ''} title="Commits what is not committed yet, then merges it onto main once its checks pass">${busy === 'merge' ? 'Merging…' : 'Merge onto main'}</button></div>
122
132
  </div>`
123
133
  }
124
134
 
@@ -201,7 +211,7 @@ export function squaresSideHtml (st) {
201
211
  add(mine, 'you')
202
212
  for (const p of st.peers || []) if (p && p.name && p.branch && squares[p.branch] && !(p.persona && p.of === (st.me && st.me.name))) add(squares[p.branch], p.mine ? 'your AI' : p.name)
203
213
  const n = st.square && st.square.work ? st.square.work.count : 0
204
- const rows = [...groups].map(([sq, who]) => `<li class="sq-side-row${sq === mine ? ' on' : ''}"><div><b>${esc(sq)}</b>${branchOf[sq] ? ` <span class="hint">${esc(branchOf[sq])}</span>` : ''}</div><div class="hint">${esc(who.join(', '))}${sq === mine ? ` · ${n ? `${files(n)} not committed` : 'all committed'}` : ''}</div></li>`).join('')
214
+ const rows = [...groups].map(([sq, who]) => `<li class="sq-side-row${sq === mine ? ' on' : ''}"><div title="Seam's square ${esc(sq)}"><b>${esc(branchOf[sq] || sq)}</b></div><div class="hint">${esc(who.join(', '))}${sq === mine ? ` · ${n ? `${files(n)} not committed` : 'all committed'}` : ''}</div></li>`).join('')
205
215
  // The pane's own title says Squares already (session.js, as it says Boxes outside Seam): no second heading.
206
216
  return rows ? `<ul class="sq-side">${rows}</ul>` : ''
207
217
  }