@nanocollective/roster 0.1.0-alpha.33 → 0.1.0-alpha.34

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanocollective/roster",
3
- "version": "0.1.0-alpha.33",
3
+ "version": "0.1.0-alpha.34",
4
4
  "description": "An agent-run org, powered by GitHub. Scaffold AI staff members whose brain is a repo.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,8 +58,17 @@
58
58
  extra room is put on the row. General sibling, not adjacent: labels can sit between them. */
59
59
  .tconflict ~ .tacts{margin-top:24px}
60
60
  .tlabels{margin-top:10px}
61
- .cmt{border-top:1px solid var(--line);padding:16px 0}
62
- .cmt.first{border-top:0}
61
+ /* A comment is a card with a header strip, so each message has a clear start and end. */
62
+ .cmt{border:1px solid var(--line);border-radius:var(--r-lg);margin:14px 0;background:var(--panel);overflow:hidden}
63
+ .cmt.human{border-color:color-mix(in srgb,var(--accent) 40%,var(--line))}
64
+ .chead{display:flex;align-items:center;gap:8px;padding:9px 14px;background:var(--panel-2);
65
+ border-bottom:1px solid var(--line);font:13px var(--sans);color:var(--ink-dim)}
66
+ .cmt.human .chead{background:color-mix(in srgb,var(--accent) 8%,var(--panel-2))}
67
+ .chead .ic{--ic:14px;color:var(--ink-faint)}
68
+ .chead b{color:var(--ink);font-weight:600}
69
+ .chead .clogin{font:11.5px var(--mono);color:var(--ink-faint)}
70
+ .chead .cwhen{margin-left:auto;font-size:12px;color:var(--ink-faint);white-space:nowrap}
71
+ .cbodywrap{padding:12px 16px 14px}
63
72
  /* The header already draws a line under itself. Whatever the reversed thread puts first must
64
73
  not draw a second one right under it. */
65
74
  .lead{border-top:0}
@@ -138,7 +147,8 @@ textarea.dropping{border-color:var(--accent);background:color-mix(in srgb,var(--
138
147
  /* ---------- timeline events ----------
139
148
  Not comments, so not comment-shaped: a marker, a line of prose, and whatever it points at.
140
149
  These carry the half of a thread that is agents referring to each other's work. */
141
- .tev{display:flex;gap:10px;align-items:flex-start;padding:9px 0 9px 2px;
150
+ .tev{display:flex;gap:10px;align-items:flex-start;padding:6px 0 6px 12px;margin-left:18px;
151
+ border-left:2px solid var(--line);
142
152
  font:12.5px/1.5 var(--sans);color:var(--ink-dim)}
143
153
  .tev .tico{flex:none;display:inline-flex;align-items:center;justify-content:center;
144
154
  width:16px;height:19px;color:var(--ink-faint);--ic:14px}
@@ -3,7 +3,7 @@
3
3
  import { getLabels, getPr, getThread, post, upload } from "../api.js";
4
4
  import { askText, askYes } from "../dialog.js";
5
5
  import { ago, el, esc, markCurrent, skeleton } from "../dom.js";
6
- import { icon, iconHTML } from "../icons.js";
6
+ import { icon, iconHTML, staffIcon } from "../icons.js";
7
7
  import { mdlite } from "../md.js";
8
8
  import { attachMentions } from "../mention.js";
9
9
  import { ensureInbox, refreshAll, stampCounts } from "../refresh.js";
@@ -1047,15 +1047,36 @@ function xref(source, item, openThread) {
1047
1047
  return b;
1048
1048
  }
1049
1049
 
1050
+ /* Who wrote something, as a person would say it: a staff member by their role, with their
1051
+ icon; one of the humans by name; anyone else by their login. */
1052
+ function whoWrote(login) {
1053
+ const s = (S.data?.staff ?? []).find((x) => (x.soloBots ?? []).includes(login));
1054
+ if (s) return { name: s.name, glyph: staffIcon(s), kind: "staff" };
1055
+ if (isHuman(login)) {
1056
+ const h = humansOf().find((x) => x.github === login);
1057
+ return { name: h?.name ?? login, glyph: "person", kind: "human" };
1058
+ }
1059
+ return { name: login || "?", glyph: "person", kind: "other" };
1060
+ }
1061
+
1062
+ /* A comment is a card: a header strip saying who and when, then what they said. As text
1063
+ between thin rules, it was hard to see where one message ended and the next began. */
1050
1064
  function comment({ author, when, body, first, repo, badge, reactions }) {
1051
- const d = el("div", { className: "cmt" + (first ? " first" : "") });
1052
- const meta = el("div", { className: "meta" });
1053
- meta.append((author || "?") + " · " + new Date(when).toLocaleString());
1054
- if (badge) meta.append(el("span", { className: "pill", style: "margin-left:8px", textContent: badge }));
1055
- d.append(meta);
1056
- d.append(el("div", { className: "md cbody", innerHTML: mdlite(body || "_no description_", { repo }) }));
1065
+ const who = whoWrote(author);
1066
+ const d = el("div", { className: "cmt " + who.kind + (first ? " first" : "") });
1067
+ const head = el("div", { className: "chead" });
1068
+ head.append(icon(who.glyph, "ic"), el("b", { textContent: who.name }));
1069
+ if (who.name !== author && author) head.append(el("span", { className: "clogin", textContent: author }));
1070
+ if (badge) head.append(el("span", { className: "pill", textContent: badge }));
1071
+ head.append(
1072
+ el("span", { className: "cwhen", title: new Date(when).toLocaleString(), textContent: ago(when) }),
1073
+ );
1074
+ d.append(head);
1075
+ const bodyEl = el("div", { className: "cbodywrap" });
1076
+ bodyEl.append(el("div", { className: "md cbody", innerHTML: mdlite(body || "_no description_", { repo }) }));
1057
1077
  const marks = reactionRow(reactions);
1058
- if (marks) d.append(marks);
1078
+ if (marks) bodyEl.append(marks);
1079
+ d.append(bodyEl);
1059
1080
  return d;
1060
1081
  }
1061
1082