instar 1.3.1286 → 1.3.1287
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/dashboard/index.html +14 -0
- package/dashboard/subscriptions.js +14 -5
- package/dist/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/upgrades/1.3.1287.md +21 -0
- package/upgrades/side-effects/subscriptions-provider-colors.md +44 -0
- package/upgrades/subscriptions-provider-colors.eli16.md +9 -0
package/dashboard/index.html
CHANGED
|
@@ -3720,6 +3720,20 @@
|
|
|
3720
3720
|
.sub-provider-heading { font-size:12px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
|
|
3721
3721
|
opacity:.6; margin:14px 0 8px; padding-bottom:6px; border-bottom:1px solid var(--border,#2a2a2a); }
|
|
3722
3722
|
.sub-provider-heading:first-child { margin-top:0; }
|
|
3723
|
+
/* Provider colors (operator request 2026-09-25): Claude and Codex are told apart
|
|
3724
|
+
at a glance — a colored band on each group heading and a colored edge on every
|
|
3725
|
+
account card and grid row. Claude = clay orange, Codex = blue. */
|
|
3726
|
+
.sub-prov-claude { --prov:#e07a4f; --prov-tint:rgba(224,122,79,.12); }
|
|
3727
|
+
.sub-prov-codex { --prov:#4f8ff0; --prov-tint:rgba(79,143,240,.12); }
|
|
3728
|
+
.sub-prov-other { --prov:#9ca3af; --prov-tint:rgba(156,163,175,.10); }
|
|
3729
|
+
.sub-provider-heading.sub-prov-claude, .sub-provider-heading.sub-prov-codex, .sub-provider-heading.sub-prov-other {
|
|
3730
|
+
opacity:1; color:var(--prov); font-size:15px; background:var(--prov-tint); border-bottom:none;
|
|
3731
|
+
border-left:6px solid var(--prov); border-radius:6px; padding:8px 12px; margin:20px 0 10px; }
|
|
3732
|
+
.sub-account.sub-prov-claude, .sub-account.sub-prov-codex, .sub-account.sub-prov-other { border-left:6px solid var(--prov); }
|
|
3733
|
+
.sub-matrix-group.sub-prov-claude, .sub-matrix-group.sub-prov-codex, .sub-matrix-group.sub-prov-other {
|
|
3734
|
+
color:var(--prov); background:var(--prov-tint); font-size:14px; opacity:1; border-left:6px solid var(--prov); padding:10px 12px; }
|
|
3735
|
+
.sub-matrix tr.sub-prov-claude > .sub-matrix-acct, .sub-matrix tr.sub-prov-codex > .sub-matrix-acct, .sub-matrix tr.sub-prov-other > .sub-matrix-acct {
|
|
3736
|
+
border-left:6px solid var(--prov); background:var(--prov-tint); }
|
|
3723
3737
|
.sub-account { border:1px solid var(--border,#2a2a2a); border-radius:10px; padding:14px 16px; margin-bottom:12px; }
|
|
3724
3738
|
.sub-account-inuse { border-color:#16a34a; box-shadow:0 0 0 1px #16a34a44; }
|
|
3725
3739
|
.sub-account-inuse-badge { font-size:11px; font-weight:600; color:#22c55e; margin-right:auto; }
|
|
@@ -282,6 +282,15 @@ export function quotaBar(doc, label, pct, resetIso, now = Date.now()) {
|
|
|
282
282
|
* pinned by a test, because "we grouped everything" would quietly add a redundant
|
|
283
283
|
* heading to the common case.
|
|
284
284
|
*/
|
|
285
|
+
/** CSS class that colors a provider's group at a glance (operator request 2026-09-25:
|
|
286
|
+
* Claude and Codex must be distinguishable without reading). Closed mapping, so a
|
|
287
|
+
* provider string never reaches a class name raw. */
|
|
288
|
+
export function providerClass(provider) {
|
|
289
|
+
if (provider === 'anthropic') return 'sub-prov-claude';
|
|
290
|
+
if (provider === 'openai') return 'sub-prov-codex';
|
|
291
|
+
return 'sub-prov-other';
|
|
292
|
+
}
|
|
293
|
+
|
|
285
294
|
export function groupAccountsByProvider(accounts) {
|
|
286
295
|
if (!Array.isArray(accounts)) return [];
|
|
287
296
|
const groups = new Map(); // provider key (raw) → accounts, in first-appearance order
|
|
@@ -298,7 +307,7 @@ export function groupAccountsByProvider(accounts) {
|
|
|
298
307
|
// else, so an unrecognised or hostile provider string cannot reach the DOM raw.
|
|
299
308
|
// An absent provider has no honest name, so say so rather than invent one.
|
|
300
309
|
const label = friendlyProvider(key) || 'Other';
|
|
301
|
-
out.push({ __providerHeading: label });
|
|
310
|
+
out.push({ __providerHeading: label, __providerKey: key });
|
|
302
311
|
}
|
|
303
312
|
for (const m of members) out.push(m);
|
|
304
313
|
}
|
|
@@ -322,11 +331,11 @@ export function renderAccounts(doc, target, accounts, now = Date.now(), inUseAcc
|
|
|
322
331
|
// accounts mixed together with only a small per-card meta line to tell them
|
|
323
332
|
// apart. The heading is what makes the split scannable.)
|
|
324
333
|
if (a && a.__providerHeading) {
|
|
325
|
-
target.appendChild(el(doc, 'div',
|
|
334
|
+
target.appendChild(el(doc, 'div', `sub-provider-heading ${providerClass(a.__providerKey)}`, a.__providerHeading));
|
|
326
335
|
continue;
|
|
327
336
|
}
|
|
328
337
|
const inUse = !!(inUseAccountId && a && a.id === inUseAccountId);
|
|
329
|
-
const card = el(doc, 'div', inUse ? 'sub-account sub-account-inuse' : 'sub-account');
|
|
338
|
+
const card = el(doc, 'div', `${inUse ? 'sub-account sub-account-inuse' : 'sub-account'} ${providerClass(a && a.provider)}`);
|
|
330
339
|
const head = el(doc, 'div', 'sub-account-head');
|
|
331
340
|
head.appendChild(el(doc, 'span', 'sub-account-nick', sanitizeForDisplay(a && a.nickname, 'label')));
|
|
332
341
|
if (inUse) head.appendChild(el(doc, 'span', 'sub-account-inuse-badge', '● In use now'));
|
|
@@ -924,7 +933,7 @@ export function renderAccountMatrix(doc, target, poolScope, pendingScope, transi
|
|
|
924
933
|
for (const entry of groupMatrixRowsByProvider(model.rows)) {
|
|
925
934
|
if (entry && entry.__providerHeading) {
|
|
926
935
|
const gtr = doc.createElement('tr');
|
|
927
|
-
const gth = el(doc, 'th',
|
|
936
|
+
const gth = el(doc, 'th', `sub-matrix-group ${providerClass(entry.__providerKey)}`, entry.__providerHeading);
|
|
928
937
|
// Span the account column + every machine column so the heading reads as a band
|
|
929
938
|
// across the grid rather than a stray cell.
|
|
930
939
|
gth.setAttribute('colspan', String(model.machines.length + 1));
|
|
@@ -934,7 +943,7 @@ export function renderAccountMatrix(doc, target, poolScope, pendingScope, transi
|
|
|
934
943
|
continue;
|
|
935
944
|
}
|
|
936
945
|
const row = entry.__row;
|
|
937
|
-
const tr = doc
|
|
946
|
+
const tr = el(doc, 'tr', providerClass(row && row.account && row.account.provider));
|
|
938
947
|
tr.appendChild(el(doc, 'th', 'sub-matrix-acct', sanitizeForDisplay(row.account.email, 'label')));
|
|
939
948
|
for (const c of row.cells) {
|
|
940
949
|
const repairCandidate = Array.isArray(reloginEpisodes)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"generatedFrom": "source-tree",
|
|
4
4
|
"registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
|
|
5
|
-
"packageVersion": "1.3.
|
|
5
|
+
"packageVersion": "1.3.1287",
|
|
6
6
|
"guards": [
|
|
7
7
|
{
|
|
8
8
|
"ref": "docs/audits/phase-b/f10-triage.md",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sha256": "
|
|
2
|
+
"sha256": "df1053d2818e9f17380b047970f345813ee788eedfeaf13b135c750177dd97ff",
|
|
3
3
|
"registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
|
|
4
|
-
"packageVersion": "1.3.
|
|
4
|
+
"packageVersion": "1.3.1287"
|
|
5
5
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-09-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-09-25T21:14:00.636Z",
|
|
5
|
+
"instarVersion": "1.3.1287",
|
|
6
6
|
"entryCount": 203,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"generatedFrom": "source-tree",
|
|
4
4
|
"registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
|
|
5
|
-
"packageVersion": "1.3.
|
|
5
|
+
"packageVersion": "1.3.1287",
|
|
6
6
|
"guards": [
|
|
7
7
|
{
|
|
8
8
|
"ref": "docs/audits/phase-b/f10-triage.md",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sha256": "
|
|
2
|
+
"sha256": "df1053d2818e9f17380b047970f345813ee788eedfeaf13b135c750177dd97ff",
|
|
3
3
|
"registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
|
|
4
|
-
"packageVersion": "1.3.
|
|
4
|
+
"packageVersion": "1.3.1287"
|
|
5
5
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The Subscriptions dashboard colors each provider so Claude and Codex are told apart at a glance: Claude in clay orange, Codex in blue. Each group heading in the account-by-machine grid and in the account list becomes a wide tinted band in its provider color. Each grid row's account cell and each account card gets a thick left edge in that color. A new closed mapping, `providerClass()` (anthropic → `sub-prov-claude`, openai → `sub-prov-codex`, anything else → `sub-prov-other`), is the only path from a provider string to a class name. Grouping, ordering and the single-provider "no heading" rule are unchanged.
|
|
9
|
+
|
|
10
|
+
## What to Tell Your User
|
|
11
|
+
|
|
12
|
+
On the Subscriptions page, Claude accounts now show in orange and Codex accounts in blue, both in the grid and in the list below, so you can see which is which without reading the labels.
|
|
13
|
+
|
|
14
|
+
## Summary of New Capabilities
|
|
15
|
+
|
|
16
|
+
- Provider color-coding on the Subscriptions dashboard (grid bands, row edges, card edges).
|
|
17
|
+
|
|
18
|
+
## Evidence
|
|
19
|
+
|
|
20
|
+
- Operator request 2026-09-25: "make the various claude/codex sections MUCH more differentiated/apparent so its much easier to at-a-glance know which accounts I'm looking at".
|
|
21
|
+
- Tests: `tests/unit/subscriptions-render.test.ts` (+3: card and heading classes, grid band and row classes, closed mapping for unknown or hostile provider strings); 100/100 pass. A visual mockup was rendered from the real CSS and renderer.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Side-Effects Review — provider colors on the Subscriptions dashboard
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `subscriptions-provider-colors`
|
|
4
|
+
**Date:** 2026-09-25
|
|
5
|
+
**Author:** Echo
|
|
6
|
+
|
|
7
|
+
## Summary of the change
|
|
8
|
+
|
|
9
|
+
`dashboard/subscriptions.js`: new exported `providerClass()` (closed mapping). The provider group entries carry `__providerKey`. Headings, cards, grid band cells and grid rows add the provider class. `dashboard/index.html`: CSS for the three classes (tinted band, colored left edges). There are no data, route or state changes.
|
|
10
|
+
|
|
11
|
+
## Decision-point inventory
|
|
12
|
+
|
|
13
|
+
None. This is presentation only.
|
|
14
|
+
|
|
15
|
+
## 1. Over-block
|
|
16
|
+
None.
|
|
17
|
+
|
|
18
|
+
## 2. Under-block
|
|
19
|
+
None. Providers other than Claude and Codex fall back to a neutral grey.
|
|
20
|
+
|
|
21
|
+
## 3. Level-of-abstraction fit
|
|
22
|
+
Styling lives in the dashboard CSS, and the class choice sits beside the existing grouping helper.
|
|
23
|
+
|
|
24
|
+
## 4. Signal vs authority compliance
|
|
25
|
+
Not applicable. No decision logic.
|
|
26
|
+
|
|
27
|
+
## 5. Interactions
|
|
28
|
+
`groupAccountsByProvider`'s order and single-provider rules are untouched (their tests still pass). Existing classes stay in place, so the existing selectors still match.
|
|
29
|
+
|
|
30
|
+
## 6. External surfaces
|
|
31
|
+
The dashboard's look only. A provider string cannot reach a class name raw; `providerClass` is a closed mapping, and a test covers a hostile string.
|
|
32
|
+
|
|
33
|
+
## 7. Multi-machine posture
|
|
34
|
+
Unchanged. It renders the same pool-scope data.
|
|
35
|
+
|
|
36
|
+
## 8. Rollback cost
|
|
37
|
+
Revert the PR.
|
|
38
|
+
|
|
39
|
+
## Conclusion
|
|
40
|
+
Presentation-only and safe to ship.
|
|
41
|
+
|
|
42
|
+
## Class-Closure Declaration (display-only mirror)
|
|
43
|
+
|
|
44
|
+
`{defectClass: "unbounded-self-action", closure: "n/a", reason: "presentation-only dashboard styling"}`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Claude and Codex get their own colors on the Subscriptions page (plain-English version)
|
|
2
|
+
|
|
3
|
+
The Subscriptions page lists every Claude and Codex account twice: once in the grid that shows which machine each account is signed in on, and once as a list of account cards with usage bars. Both places already grouped Claude accounts together and Codex accounts together, but the only thing marking each group was a small grey word. Many accounts use the same email for both Claude and Codex, so it was easy to lose track of which group you were looking at.
|
|
4
|
+
|
|
5
|
+
Now each provider has its own color. Claude is orange and Codex is blue. Each group starts with a wide colored band that names it. Every account row in the grid and every account card has a thick colored stripe on its left edge. You can tell at a glance, without reading, whether you're looking at a Claude account or a Codex account.
|
|
6
|
+
|
|
7
|
+
Nothing else about the page changes. The order is the same, the buttons are the same, and an install with only one provider still shows no group heading at all. Providers other than Claude and Codex get a neutral grey.
|
|
8
|
+
|
|
9
|
+
Nothing needs deciding.
|