shraga 0.1.127 → 0.1.128

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.
@@ -13,8 +13,8 @@
13
13
  <link rel="preconnect" href="https://fonts.googleapis.com" />
14
14
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15
15
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
16
- <script type="module" crossorigin src="/assets/index-DRTvNKXl.js"></script>
17
- <link rel="stylesheet" crossorigin href="/assets/index-_XEpjgJO.css">
16
+ <script type="module" crossorigin src="/assets/index-deXgTuFO.js"></script>
17
+ <link rel="stylesheet" crossorigin href="/assets/index-BLAQpfJ9.css">
18
18
  </head>
19
19
  <body>
20
20
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shraga",
3
- "version": "0.1.127",
3
+ "version": "0.1.128",
4
4
  "description": "The teammate you delegate coding to — a self-hostable, multi-user AI coding agent web UI (Claude Code, with a pluggable engine seam).",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -54,35 +54,41 @@ export function ClaudeAccountSection({ getToken }: { getToken: () => Promise<str
54
54
  ? !accounts?.me?.connected || !!accounts.me.useShared
55
55
  : !!accounts?.me?.connected && !accounts.me.useShared;
56
56
 
57
- const row = (target: Target, title: string, s: AccountStatus | null, canManage = true) => (
58
- <div className="flex items-center justify-between gap-2 flex-wrap">
59
- <div className="text-sm min-w-0">
60
- <div className="font-medium flex items-center gap-2">
61
- {title}
62
- {active(target) && <span className="text-[10px] uppercase tracking-wide text-emerald-500">active</span>}
63
- <UsageMetric usage={accounts?.usage?.[target] ?? null} />
64
- </div>
65
- <div className="text-xs text-muted-foreground truncate">
66
- {s?.connected ? `${s.account ?? 'Connected'}${s.subscriptionType ? ` · ${s.subscriptionType}` : ''}` : target === 'me' ? 'Not connected — using the shared subscription' : canManage ? 'Not connected' : ''}
57
+ const row = (target: Target, title: string, s: AccountStatus | null, canManage = true) => {
58
+ const usage = accounts?.usage?.[target] ?? null;
59
+ const identity = s?.connected ? [s.account ?? 'Connected', s.subscriptionType].filter(Boolean).join(' · ')
60
+ : target === 'me' ? 'Not connected' : canManage ? 'Not connected' : null;
61
+ return (
62
+ <div className="flex items-center justify-between gap-3">
63
+ <div className="min-w-0 space-y-0.5">
64
+ <div className="flex items-center gap-2 text-sm font-medium">
65
+ {title}
66
+ {active(target) && <span className="rounded-full bg-emerald-500/15 px-1.5 py-px text-[10px] font-medium text-emerald-500">Active</span>}
67
+ </div>
68
+ <div className="flex items-center gap-1.5 text-xs text-muted-foreground min-w-0">
69
+ {identity && <span className="truncate">{identity}</span>}
70
+ {identity && usage && <span aria-hidden>·</span>}
71
+ <UsageMetric usage={usage} compact />
72
+ </div>
67
73
  </div>
74
+ {canManage && (
75
+ <div className="flex shrink-0 gap-2">
76
+ {target === 'me' && s?.connected && (
77
+ <>
78
+ <Button size="sm" variant="outline" disabled={busy} onClick={() => useShared(!s.useShared)}>{s.useShared ? 'Use mine' : 'Use shared'}</Button>
79
+ <Button size="sm" variant="outline" disabled={busy} onClick={() => disconnect(target)}>Sign out</Button>
80
+ </>
81
+ )}
82
+ <Button size="sm" variant="outline" disabled={busy} onClick={() => connect(target)}>{s?.connected ? 'Replace' : 'Connect'}</Button>
83
+ </div>
84
+ )}
68
85
  </div>
69
- {canManage && (
70
- <div className="flex gap-2">
71
- <Button size="sm" variant="outline" disabled={busy} onClick={() => connect(target)}>{s?.connected ? 'Replace' : 'Connect'}</Button>
72
- {target === 'me' && s?.connected && (
73
- <>
74
- <Button size="sm" variant="ghost" disabled={busy} onClick={() => useShared(!s.useShared)}>{s.useShared ? 'Use mine' : 'Use shared'}</Button>
75
- <Button size="sm" variant="ghost" disabled={busy} onClick={() => disconnect(target)}>Sign out</Button>
76
- </>
77
- )}
78
- </div>
79
- )}
80
- </div>
81
- );
86
+ );
87
+ };
82
88
 
83
89
  if (!accounts) return error ? <p className="text-xs text-destructive">{error}</p> : null;
84
90
  return (
85
- <div className="space-y-3">
91
+ <div className="space-y-4">
86
92
  <label className="text-sm font-medium block">Claude subscription</label>
87
93
  {accounts.me ? row('me', 'Your subscription', accounts.me) : (
88
94
  <p className="text-xs text-muted-foreground">Personal subscription unavailable: you are not a contact on this agent.</p>
@@ -136,7 +136,7 @@ function ClaudeUsageMetric({ getToken }: { getToken: () => Promise<string | null
136
136
 
137
137
  /** Pure render — null usage (204, or any failure) renders NOTHING. Split from the fetching shell so
138
138
  * the gate and the labelling are testable without a network or a DOM. */
139
- export function UsageMetric({ usage }: { usage: Usage | null }) {
139
+ export function UsageMetric({ usage, compact }: { usage: Usage | null; /** Inline text trigger (settings rows) instead of the strip gauge. */ compact?: boolean }) {
140
140
  const top = usage && binding(usage.limits);
141
141
  const [state, setState] = useState<CardState>(CLOSED);
142
142
  const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
@@ -169,7 +169,9 @@ export function UsageMetric({ usage }: { usage: Usage | null }) {
169
169
  onPointerEnter={e => send({ type: 'pointerenter', pointerType: e.pointerType }, HOVER_OPEN_MS)}
170
170
  onPointerLeave={e => send({ type: 'pointerleave', pointerType: e.pointerType }, HOVER_CLOSE_MS)}
171
171
  >
172
- <Metric label="usage" value={top.percent} severity={top.severity} />
172
+ {compact
173
+ ? <span className={cn('tabular-nums', level(top.percent, top.severity))}>{top.percent}% used</span>
174
+ : <Metric label="usage" value={top.percent} severity={top.severity} />}
173
175
  </button>
174
176
  </PopoverTrigger>
175
177
  <PopoverContent