@ai-matrx/agents 0.8.0 → 0.9.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/CHANGELOG.md +135 -0
- package/dist/catalog/index.cjs +50 -3
- package/dist/catalog/index.cjs.map +1 -1
- package/dist/catalog/index.d.cts +11 -615
- package/dist/catalog/index.d.ts +11 -615
- package/dist/catalog/index.js +50 -3
- package/dist/catalog/index.js.map +1 -1
- package/dist/catalog/native/index.cjs +2806 -0
- package/dist/catalog/native/index.cjs.map +1 -0
- package/dist/catalog/native/index.d.cts +655 -0
- package/dist/catalog/native/index.d.ts +655 -0
- package/dist/catalog/native/index.js +2802 -0
- package/dist/catalog/native/index.js.map +1 -0
- package/dist/catalog/react/index.cjs +470 -394
- package/dist/catalog/react/index.cjs.map +1 -1
- package/dist/catalog/react/index.d.cts +64 -26
- package/dist/catalog/react/index.d.ts +64 -26
- package/dist/catalog/react/index.js +354 -278
- package/dist/catalog/react/index.js.map +1 -1
- package/dist/orchestra-BWJM2MWP.d.cts +643 -0
- package/dist/orchestra-BWJM2MWP.d.ts +643 -0
- package/package.json +22 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,140 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0 — 2026-09-08
|
|
4
|
+
|
|
5
|
+
**THE ONE PICKER NOW RENDERS ON REACT NATIVE — `@ai-matrx/agents/catalog/native`.**
|
|
6
|
+
|
|
7
|
+
Matrx Mobile (Expo 54 / RN 0.81) was the last client still hand-rolling its
|
|
8
|
+
agent list. Its sheet showed four HARDCODED agents plus a Supabase read of a
|
|
9
|
+
`prompts` table that **does not exist in the platform database** — a read whose
|
|
10
|
+
PostgREST error was swallowed into an empty array, so the list silently never
|
|
11
|
+
had anything but the four constants. Three of those four constants named the
|
|
12
|
+
WRONG agent: the ids behind "General Chat", "Deep Research" and "Code Helper"
|
|
13
|
+
resolve in `agent.definition` to *Agent Ledger*, *Knowledge Search Test* and
|
|
14
|
+
*Balanced News Analysis*. A label lying on screen, with nothing anywhere that
|
|
15
|
+
could notice — the same class the mandate default row was built to end.
|
|
16
|
+
|
|
17
|
+
React Native could not adopt the picker before this release for two concrete
|
|
18
|
+
reasons, and both are fixed here rather than worked around in the app.
|
|
19
|
+
|
|
20
|
+
### Consumer action (C28)
|
|
21
|
+
|
|
22
|
+
**Web hosts: none.** `@ai-matrx/agents/catalog` and `/catalog/react` keep every
|
|
23
|
+
export, every name and every behaviour. The provider, the store subscription
|
|
24
|
+
and the two list hooks moved to `catalog/shared/*` so both platforms run one
|
|
25
|
+
implementation; `catalog/react` re-exports all of them unchanged, and the
|
|
26
|
+
`"use client"` banner is still stamped on the react build and still absent from
|
|
27
|
+
the pure ones (the tarball canary now judges eight artefacts instead of four).
|
|
28
|
+
|
|
29
|
+
**React Native hosts:**
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
33
|
+
import { createAgentCatalog } from "@ai-matrx/agents/catalog";
|
|
34
|
+
import { AgentCatalogProvider, AgentListSheet } from "@ai-matrx/agents/catalog/native";
|
|
35
|
+
|
|
36
|
+
const catalog = createAgentCatalog({
|
|
37
|
+
client: supabase,
|
|
38
|
+
identity: { requireUserId: () => requireUserId() },
|
|
39
|
+
storage: AsyncStorage, // NEW — the async storage seam
|
|
40
|
+
transport, // only when a picker passes defaultMandateKey
|
|
41
|
+
errorSink: reportToDiagnostics,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
<AgentCatalogProvider catalog={catalog} navigate={(href) => router.push(href)}>
|
|
45
|
+
<AgentListSheet consumerId="chat" onSelect={setAgentId} activeAgentId={agentId} />
|
|
46
|
+
</AgentCatalogProvider>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `react-native` and `react-native-svg` are OPTIONAL peers. Install
|
|
50
|
+
`react-native-svg` (`npx expo install react-native-svg`) for the real glyphs;
|
|
51
|
+
without it the icons fall back to text glyphs and **say so once** through the
|
|
52
|
+
`errorSink`, with the remedy. Nothing goes blank and nothing goes quiet.
|
|
53
|
+
- Bind `navigate` if your rows should be able to open an agent. Unbound, the
|
|
54
|
+
default is a no-op that REPORTS through the `errorSink` — never a control
|
|
55
|
+
that silently does nothing.
|
|
56
|
+
- `@ai-matrx/agents/catalog/styles.css` is a WEB artefact; the native entry
|
|
57
|
+
needs no stylesheet.
|
|
58
|
+
|
|
59
|
+
### What is new
|
|
60
|
+
|
|
61
|
+
- **`@ai-matrx/agents/catalog/native`** — the picker in React Native
|
|
62
|
+
primitives over the SAME headless kernel and the SAME hooks:
|
|
63
|
+
`AgentCatalogProvider`, `AgentListSheet` (the body of a bottom sheet — the
|
|
64
|
+
host keeps its own sheet chrome, so no gesture library is forced on anyone),
|
|
65
|
+
`AgentListInlinePicker`, and every part beneath them (`AgentListContent`,
|
|
66
|
+
`AgentListTabs`, `AgentFilterBar`, `AgentRow`, `AgentDetailCard`,
|
|
67
|
+
`AgentSubView`, `FavoriteAgentButton`, the five primitives, `AgentIcon`).
|
|
68
|
+
The shells take the web shells' prop surface name for name: `onSelect`,
|
|
69
|
+
`activeAgentId`, `consumerId`, `initialTab`, `includeSystemInAll`,
|
|
70
|
+
`visibleTabs`, `systemTabLabel`, `showPinnedAgent`, `excludeAgentIds`,
|
|
71
|
+
`defaultMandateKey`, `compact`.
|
|
72
|
+
- **The async storage seam** — `AgentCatalogAsyncStorage` /
|
|
73
|
+
`AgentCatalogStorageLike`, plus `readCachedDefaultRowAsync` and
|
|
74
|
+
`writeCachedDefaultRowAsync`. `createAgentCatalog({ storage })` now accepts an
|
|
75
|
+
`AsyncStorage`-shaped store verbatim. React Native has no `localStorage`, so
|
|
76
|
+
before this a native host could only hand the catalog a store that answered
|
|
77
|
+
`null` synchronously (a lie) or lose the default row's first paint entirely.
|
|
78
|
+
**The web path is unchanged**: `AgentCatalogStorage` is still synchronous,
|
|
79
|
+
`readCachedDefaultRow`/`writeCachedDefaultRow` still have their synchronous
|
|
80
|
+
signatures, `defaultStorage()` still prefers `localStorage`, and the async
|
|
81
|
+
helpers over a synchronous store produce byte-identical cache payloads
|
|
82
|
+
(proven in `catalog/__tests__/storage-seam.test.ts`).
|
|
83
|
+
- **`AgentCatalogNativeTheme`** (C26 on a platform with no CSS) — the native
|
|
84
|
+
twin of the `--matrx-agent-*` sheet: every token ships a DEFAULT VALUE so the
|
|
85
|
+
picker renders correctly unthemed, and a host re-brands by passing `theme` to
|
|
86
|
+
the provider. `DEFAULT_AGENT_CATALOG_NATIVE_THEME` (dark) and
|
|
87
|
+
`LIGHT_AGENT_CATALOG_NATIVE_THEME` ship; `resolveAgentCatalogNativeTheme`
|
|
88
|
+
merges an override and keeps every value it omits. No native component
|
|
89
|
+
contains a colour literal.
|
|
90
|
+
- **`catalog/shared/icon-paths.ts`** — the glyph geometry, once. The web icons
|
|
91
|
+
now read it too, so a shape can never differ between the two platforms; the
|
|
92
|
+
native entry draws the same paths through `react-native-svg` (C19: still no
|
|
93
|
+
icon-library dependency, on either platform).
|
|
94
|
+
- **`AgentListTabCounts` moved** to `catalog/shared/useAgentListCore` beside the
|
|
95
|
+
code that computes it. `catalog/react/AgentListTabs` re-exports it unchanged.
|
|
96
|
+
|
|
97
|
+
### Behavioural deltas on native, recorded rather than hidden
|
|
98
|
+
|
|
99
|
+
1. **No hover preview.** The web picker's side panel opens on hover; a touch
|
|
100
|
+
screen has no hover, so the detail card is reached by the row's chevron —
|
|
101
|
+
the same three-view stack (`list → detail → sort/categories/tags`) the web
|
|
102
|
+
`AgentListInlinePicker` already used on mobile widths.
|
|
103
|
+
2. **No cmd-click link.** `AgentRow`'s anchor exists on the web so a person can
|
|
104
|
+
open an agent in a new tab. React Native has neither, so the row is an
|
|
105
|
+
ordinary `Pressable`; the `LinkComponent` port still exists and still ships
|
|
106
|
+
a working native default.
|
|
107
|
+
3. **`autoFocusSearch` defaults to `false`** (the web inline picker defaults to
|
|
108
|
+
`true`): a keyboard that opens with the sheet covers the list it was meant
|
|
109
|
+
to filter.
|
|
110
|
+
|
|
111
|
+
### Proof
|
|
112
|
+
|
|
113
|
+
- **The 293-case ordering matrix, re-measured through the RENDERED native
|
|
114
|
+
list** (`catalog/native/__tests__/parity.test.tsx`): every case's ids, in
|
|
115
|
+
order, read back out of the mounted native tree — not out of the selectors a
|
|
116
|
+
second time. Sharing a kernel is an architecture claim; this is the
|
|
117
|
+
measurement. It carries a falsifiability leg.
|
|
118
|
+
- **The tarball canary imports AND requires `./catalog/native`**, checks every
|
|
119
|
+
documented export, proves the theme override merges over the PACKED build,
|
|
120
|
+
proves the icon degradation announces exactly once with its remedy, and
|
|
121
|
+
compiles a native usage (including an `AsyncStorage`-shaped `storage`) against
|
|
122
|
+
the packed types under `exactOptionalPropertyTypes` + `noUncheckedIndexedAccess`.
|
|
123
|
+
- **The banner canary now judges eight artefacts**: the `"use client"` prologue
|
|
124
|
+
must be present on both `catalog/react` builds and ABSENT from all four
|
|
125
|
+
`catalog/index.*` and all four `catalog/native/index.*` files.
|
|
126
|
+
|
|
127
|
+
### Known limits, stated plainly
|
|
128
|
+
|
|
129
|
+
There is still **no React Native canary harness** in this workspace (campaign
|
|
130
|
+
decision C7 schedules it for Phase 2), and the real `react-native` package
|
|
131
|
+
cannot be loaded by vitest — it ships Flow-typed source only Metro parses. The
|
|
132
|
+
native tests therefore render against a minimal RN stand-in
|
|
133
|
+
(`catalog/native/__tests__/react-native.stub.tsx`) that maps RN primitives onto
|
|
134
|
+
DOM nodes. That proves rows, order, labels, counts, handlers and every
|
|
135
|
+
announced degradation. It does **not** prove pixel layout, gestures or Hermes —
|
|
136
|
+
those are proven by the consuming Expo app's own build and device smoke.
|
|
137
|
+
|
|
3
138
|
## 0.8.0 — 2026-09-08
|
|
4
139
|
|
|
5
140
|
**THE ORCHESTRA BADGE IS BACK, in every client at once.**
|
package/dist/catalog/index.cjs
CHANGED
|
@@ -69,6 +69,7 @@ __export(catalog_exports, {
|
|
|
69
69
|
parseMandateResolution: () => parseMandateResolution,
|
|
70
70
|
readAgentCatalogRows: () => readAgentCatalogRows,
|
|
71
71
|
readCachedDefaultRow: () => readCachedDefaultRow,
|
|
72
|
+
readCachedDefaultRowAsync: () => readCachedDefaultRowAsync,
|
|
72
73
|
readSingleAgentRow: () => readSingleAgentRow,
|
|
73
74
|
resolveDefaultRow: () => resolveDefaultRow,
|
|
74
75
|
searchAgentsOnServer: () => searchAgentsOnServer,
|
|
@@ -87,7 +88,8 @@ __export(catalog_exports, {
|
|
|
87
88
|
sortFilteredAgents: () => sortFilteredAgents,
|
|
88
89
|
toAgentSummary: () => toAgentSummary,
|
|
89
90
|
writeAgentFavorite: () => writeAgentFavorite,
|
|
90
|
-
writeCachedDefaultRow: () => writeCachedDefaultRow
|
|
91
|
+
writeCachedDefaultRow: () => writeCachedDefaultRow,
|
|
92
|
+
writeCachedDefaultRowAsync: () => writeCachedDefaultRowAsync
|
|
91
93
|
});
|
|
92
94
|
module.exports = __toCommonJS(catalog_exports);
|
|
93
95
|
|
|
@@ -430,6 +432,51 @@ function writeCachedDefaultRow(storage, resolved) {
|
|
|
430
432
|
} catch {
|
|
431
433
|
}
|
|
432
434
|
}
|
|
435
|
+
function parseCachedDefaultRow(mandateKey, raw) {
|
|
436
|
+
try {
|
|
437
|
+
if (!raw) return null;
|
|
438
|
+
const parsed = JSON.parse(raw);
|
|
439
|
+
if (!isRecord2(parsed)) return null;
|
|
440
|
+
const holderId = parsed["holderId"];
|
|
441
|
+
const holderName = parsed["holderName"];
|
|
442
|
+
if (typeof holderId !== "string" || typeof holderName !== "string") {
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
const description = parsed["holderDescription"];
|
|
446
|
+
const provenance = parsed["provenance"];
|
|
447
|
+
const at = parsed["at"];
|
|
448
|
+
return {
|
|
449
|
+
mandateKey,
|
|
450
|
+
holderId,
|
|
451
|
+
holderName,
|
|
452
|
+
holderDescription: typeof description === "string" ? description : null,
|
|
453
|
+
provenance: typeof provenance === "string" ? provenance : "system",
|
|
454
|
+
at: typeof at === "number" ? at : 0
|
|
455
|
+
};
|
|
456
|
+
} catch {
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
async function readCachedDefaultRowAsync(storage, mandateKey) {
|
|
461
|
+
let raw;
|
|
462
|
+
try {
|
|
463
|
+
raw = await storage.getItem(
|
|
464
|
+
CACHE_PREFIX + mandateKey
|
|
465
|
+
);
|
|
466
|
+
} catch {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
return parseCachedDefaultRow(mandateKey, raw);
|
|
470
|
+
}
|
|
471
|
+
async function writeCachedDefaultRowAsync(storage, resolved) {
|
|
472
|
+
try {
|
|
473
|
+
await storage.setItem(
|
|
474
|
+
CACHE_PREFIX + resolved.mandateKey,
|
|
475
|
+
JSON.stringify(resolved)
|
|
476
|
+
);
|
|
477
|
+
} catch {
|
|
478
|
+
}
|
|
479
|
+
}
|
|
433
480
|
function defaultRowFromResolution(resolved) {
|
|
434
481
|
return {
|
|
435
482
|
id: mandateAgentId(resolved.mandateKey),
|
|
@@ -469,7 +516,7 @@ function detectDefaultRowDrift(cached, live) {
|
|
|
469
516
|
}
|
|
470
517
|
async function resolveDefaultRow(args) {
|
|
471
518
|
const { mandateKey, transport, client, storage, lookupRow } = args;
|
|
472
|
-
const cached =
|
|
519
|
+
const cached = await readCachedDefaultRowAsync(storage, mandateKey);
|
|
473
520
|
const verdict = await askTheServer(transport, mandateKey);
|
|
474
521
|
if (verdict.holderType !== "agent") {
|
|
475
522
|
throw new MandateDefaultRowError({
|
|
@@ -506,7 +553,7 @@ async function resolveDefaultRow(args) {
|
|
|
506
553
|
at: Date.now()
|
|
507
554
|
};
|
|
508
555
|
const drift = detectDefaultRowDrift(cached, resolved);
|
|
509
|
-
|
|
556
|
+
await writeCachedDefaultRowAsync(storage, resolved);
|
|
510
557
|
return { resolved, row: defaultRowFromResolution(resolved), drift };
|
|
511
558
|
}
|
|
512
559
|
|