@spunto/design-system 0.12.0 → 0.13.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.
package/README.md CHANGED
@@ -120,7 +120,14 @@ panel are the same concept seen twice, so they share `/projects`.
120
120
  differently: `WorkerStatusDot`/`WorkerStatusPill` (+`resolveWorkerStatus`,
121
121
  `workerStatusConfig`), `SetupProgress` (+`setupProgress`, `phaseLabel`,
122
122
  `setupTotalMs`), `StepIndicator`, `ResourceBars`, `GitBranchChips`/
123
- `GitStatusSummary`, `TagChips` (+`tagColor`), `CreatorAvatar`.
123
+ `GitStatusSummary`/`RequestedBranchChip`, `TagChips` (+`tagColor`),
124
+ `CreatorAvatar`.
125
+ - **What a worker is working on, in two tenses**: `gitStatus` is what it *did*
126
+ check out (a chip per repo) and `worker.branch` is what it was *asked* to
127
+ check out. The live status wins as soon as it exists; until then — during
128
+ setup, and on a stopped worker — the requested branch holds its place as a
129
+ lone chip (`RequestedBranchChip`), in the same shell so it reads as the same
130
+ kind of information.
124
131
  - **Types are structural**, never the apps' OpenAPI types: the dashboard and
125
132
  Spunto Lite model a worker differently, so `WorkerCardWorker` asks for the
126
133
  minimum, everything optional but `id`, and an unknown state falls back to
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spunto/design-system",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Spunto's shared design system — warm/flame tokens, color constants, and UI primitives.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -35,6 +35,14 @@ export function repoName(repo: GitRepoStatus): string {
35
35
  return repo.name ?? repo.path.split("/").filter(Boolean).pop() ?? repo.path
36
36
  }
37
37
 
38
+ /**
39
+ * `max-w-full` is what keeps a chip inside the card: without it a long
40
+ * "repo · branch" is a single unbreakable row that runs under the card's
41
+ * rounded edge and gets clipped.
42
+ */
43
+ const CHIP =
44
+ "inline-flex min-w-0 max-w-full items-center gap-1 rounded-md border border-border bg-muted/40 px-2 py-0.5 font-mono text-[11px] text-muted-foreground"
45
+
38
46
  /** One chip per checked-out repository, wrapping onto as many lines as needed. */
39
47
  export function GitBranchChips({ repos, repoHref, className }: GitBranchChipsProps) {
40
48
  if (!repos.length) return null
@@ -52,13 +60,7 @@ export function GitBranchChips({ repos, repoHref, className }: GitBranchChipsPro
52
60
  key={repo.path}
53
61
  {...(href ? { href, target: "_blank", rel: "noopener noreferrer" } : {})}
54
62
  title={repo.path}
55
- // `max-w-full` is what keeps a chip inside the card: without it a
56
- // long "repo · branch" is a single unbreakable row that runs under
57
- // the card's rounded edge and gets clipped.
58
- className={cn(
59
- "inline-flex min-w-0 max-w-full items-center gap-1 rounded-md border border-border bg-muted/40 px-2 py-0.5 font-mono text-[11px] text-muted-foreground",
60
- href && "transition-colors hover:border-border/80 hover:bg-muted/70"
61
- )}
63
+ className={cn(CHIP, href && "transition-colors hover:border-border/80 hover:bg-muted/70")}
62
64
  >
63
65
  <span className="shrink-0 font-medium text-foreground/70">{repoName(repo)}</span>
64
66
  <span className="mx-0.5 shrink-0 text-muted-foreground/40">·</span>
@@ -75,6 +77,27 @@ export function GitBranchChips({ repos, repoHref, className }: GitBranchChipsPro
75
77
  )
76
78
  }
77
79
 
80
+ export interface RequestedBranchChipProps {
81
+ branch: string
82
+ className?: string
83
+ }
84
+
85
+ /**
86
+ * The branch a worker was *asked* to check out, as a lone chip — no repo name,
87
+ * because at that point nothing is cloned yet and there is none to show. Same
88
+ * shell as the chips above on purpose: it's the placeholder they replace once
89
+ * the live status arrives, and a different-looking chip would read as a
90
+ * different kind of information.
91
+ */
92
+ export function RequestedBranchChip({ branch, className }: RequestedBranchChipProps) {
93
+ return (
94
+ <span data-slot="requested-branch-chip" className={cn(CHIP, className)} title={`Requested branch: ${branch}`}>
95
+ <GitBranchIcon className="h-2.5 w-2.5 shrink-0" />
96
+ <span className="min-w-0 truncate">{branch}</span>
97
+ </span>
98
+ )
99
+ }
100
+
78
101
  /** Amber for local work not yet committed/pushed, muted for what's merely behind. */
79
102
  function RepoCounters({ repo }: { repo: GitRepoStatus }) {
80
103
  return (
@@ -18,8 +18,8 @@ export type { SetupProgressProps, StepState } from "./setup-progress"
18
18
  export { ResourceBars } from "./resource-bars"
19
19
  export type { ResourceBarsProps, WorkerStats } from "./resource-bars"
20
20
 
21
- export { GitBranchChips, GitStatusSummary, repoName } from "./git-branch-chips"
22
- export type { GitBranchChipsProps, GitRepoStatus, GitStatusSummaryProps } from "./git-branch-chips"
21
+ export { GitBranchChips, GitStatusSummary, RequestedBranchChip, repoName } from "./git-branch-chips"
22
+ export type { GitBranchChipsProps, GitRepoStatus, GitStatusSummaryProps, RequestedBranchChipProps } from "./git-branch-chips"
23
23
 
24
24
  export { TagChips } from "./tag-chips"
25
25
  export type { TagChipsProps } from "./tag-chips"
@@ -31,6 +31,12 @@ export interface WorkerCardWorker {
31
31
  /** Docker-level state: `running` | `stopped` | `exited` | `created` | `not_found` | `error`. */
32
32
  dockerState?: string | null
33
33
  createdAt?: string | null
34
+ /**
35
+ * Branch asked for at creation — what the worker is *going to* check out. The
36
+ * live per-repo status (`gitStatus`) says what it *did* check out, and takes
37
+ * over as soon as it exists.
38
+ */
39
+ branch?: string | null
34
40
  projectVersion?: number | null
35
41
  tags?: string[] | null
36
42
  setupStatus?: WorkerSetupStatus | null
@@ -14,7 +14,7 @@ import {
14
14
  import { cn, formatDuration, formatRelativeTime } from "../../utils"
15
15
  import { buttonVariants } from "../button-variants"
16
16
  import { CreatorAvatar } from "./creator-avatar"
17
- import { GitBranchChips, type GitRepoStatus } from "./git-branch-chips"
17
+ import { GitBranchChips, RequestedBranchChip, type GitRepoStatus } from "./git-branch-chips"
18
18
  import { ResourceBars, type WorkerStats } from "./resource-bars"
19
19
  import { SetupProgress, setupTotalMs } from "./setup-progress"
20
20
  import { TagChips } from "./tag-chips"
@@ -209,10 +209,16 @@ export function WorkerCard({
209
209
  </div>
210
210
  )}
211
211
 
212
- {repos.length > 0 && (
212
+ {repos.length > 0 ? (
213
213
  <div className="px-4 pb-3">
214
214
  <GitBranchChips repos={repos} repoHref={repoHref} />
215
215
  </div>
216
+ ) : (
217
+ worker.branch && (
218
+ <div className="px-4 pb-3">
219
+ <RequestedBranchChip branch={worker.branch} />
220
+ </div>
221
+ )
216
222
  )}
217
223
 
218
224
  {settled && stats && (