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.
@@ -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', 'sub-provider-heading', a.__providerHeading));
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', 'sub-matrix-group', entry.__providerHeading);
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.createElement('tr');
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.1286",
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": "4c0019f5f7019a607696ddeaa4422711ade3c81d4cd69135e2a9640dda4e90ba",
2
+ "sha256": "df1053d2818e9f17380b047970f345813ee788eedfeaf13b135c750177dd97ff",
3
3
  "registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
4
- "packageVersion": "1.3.1286"
4
+ "packageVersion": "1.3.1287"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
3
3
  "articleCount": 92,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1286"
5
+ "packageVersion": "1.3.1287"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.1286",
3
+ "version": "1.3.1287",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-09-25T20:15:27.730Z",
5
- "instarVersion": "1.3.1286",
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.1286",
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": "4c0019f5f7019a607696ddeaa4422711ade3c81d4cd69135e2a9640dda4e90ba",
2
+ "sha256": "df1053d2818e9f17380b047970f345813ee788eedfeaf13b135c750177dd97ff",
3
3
  "registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
4
- "packageVersion": "1.3.1286"
4
+ "packageVersion": "1.3.1287"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
3
3
  "articleCount": 92,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1286"
5
+ "packageVersion": "1.3.1287"
6
6
  }
@@ -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.