altitude-design 0.5.0 → 0.5.1
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/dist/guidance/components/AgentFleet/README.md +1 -1
- package/dist/guidance/components/CommentThread/README.md +3 -1
- package/dist/guidance/components/InlineEdit/README.md +1 -1
- package/dist/guidance/components/SaveBar/README.md +3 -1
- package/dist/guidance/index.json +13 -13
- package/dist/guidance/llms.txt +1 -1
- package/dist/guidance/manifest.json +19 -19
- package/dist/guidance/references/build/checks/agent-action-pattern.mjs +2 -0
- package/dist/guidance/references/build/checks/assistant-conversation-pattern.mjs +2 -0
- package/dist/guidance/references/build/checks/members-pattern.mjs +2 -0
- package/dist/guidance/references/build/checks/settings-pattern.mjs +2 -0
- package/dist/guidance/references/build/fixtures/patterns/agent-action.jsx +34 -30
- package/dist/guidance/references/build/fixtures/patterns/assistant-conversation.jsx +8 -6
- package/dist/guidance/references/build/fixtures/patterns/members.jsx +28 -24
- package/dist/guidance/references/build/fixtures/patterns/settings.jsx +34 -30
- package/dist/guidance/visual/ActionsInPlace.md +8 -11
- package/dist/guidance/visual/Distinctiveness.md +1 -1
- package/dist/guidance/visual/Research.md +1 -1
- package/dist/guidance/visual/Theming.md +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AgentFleet
|
|
2
2
|
|
|
3
|
-
Every agent working on one job, as a roster: grouped by what they need from you (needs you, working, done), each row saying the agent's state in words, what it's doing in one line, how long it has waited or run, where it is in its plan and what it has spent, with warnings for trouble that's coming (two agents changing one file, an agent making no progress). For supervising several agents at once; see [the research](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
3
|
+
Every agent working on one job, as a roster: grouped by what they need from you (needs you, working, done), each row saying the agent's state in words, what it's doing in one line, how long it has waited or run, where it is in its plan and what it has spent, with warnings for trouble that's coming (two agents changing one file, an agent making no progress). For supervising several agents at once; see [the research](https://github.com/richlaconte/altitude/blob/v0.5.1/docs/research/agent-orchestration/README.md).
|
|
4
4
|
|
|
5
5
|
**Elevation: a record of agents, with live rows.**
|
|
6
6
|
- **Rows** are the record: flush at rest, lifting one level when pointed at because selecting one opens it. The open agent is selected, as a table's row is: `accent-soft`, raised one level, `aria-current`.
|
|
@@ -73,7 +73,9 @@ export default function App() {
|
|
|
73
73
|
onDelete={(id) => setComments((xs) => xs.map((x) => (x.id === id ? { ...x, deleted: true } : x)))}
|
|
74
74
|
onUndoDelete={(id) => setComments((xs) => xs.map((x) => (x.id === id ? { ...x, deleted: false } : x)))}
|
|
75
75
|
mentionable={(q) => people.filter((p) => p.name.toLowerCase().includes(q.toLowerCase()))} typing={resolved ? [] : ['Ada Obi']} />
|
|
76
|
-
<
|
|
76
|
+
<details className="preview-fixtures"><summary>Example fixtures</summary>
|
|
77
|
+
<Switch label="Make the next post fail" checked={failNext} onCheckedChange={setFailNext} />
|
|
78
|
+
</details>
|
|
77
79
|
</div>
|
|
78
80
|
);
|
|
79
81
|
}
|
|
@@ -130,7 +130,7 @@ Optional labels are `editLabel` (default `Edit ${label}`), `saveLabel` (“Save
|
|
|
130
130
|
|
|
131
131
|
The canonical `InlineEdit` section in `build/previews.txt` renders a task title (in its heading font), a multiline description, the task's status (Select, on choose, with a rejected “Blocked”), assignee (Combobox, on choose) and estimate (a numeric Input), an independent filename table cell with this component, and “Ways to open”: a pencil and two fields on hover, with seams. A collapsed documentation harness selects deterministic fixtures before mounting, resets records and counters, delays validation, applies external updates, removes the filename consumer during work and opens a dialog comparison using the same validation and persistence adapter. Fixture controls and operation logs stay outside the product scene.
|
|
132
132
|
|
|
133
|
-
Run `node checks/inline-edit.mjs` from `build/` after generating preview fixtures. `ALT_FIXTURE_ROOT=test/react19` selects the React 19 source fixtures. The checks cover editing in place (the value's text doesn't move, the control takes its font, the pencil and the field move nothing on hover, the caret lands where clicked, the seam, the announcement that clears itself), multiline (newline on Enter, Ctrl/Cmd+Enter, IME, Escape, caret at the end, growth to `maxRows`, line breaks in read mode), custom editors (focus, Escape layering, on-choose saves and rejections, unchanged choices, numeric validation), lifecycle races, retained input, uncertainty reconciliation, conflict latching, keyboard/IME, focus, disabled behavior and the four-scheme responsive/accessibility matrix. Automated checks do not replace the human screen-reader, touch, magnification or formative comparisons recorded in [Actions in place validation](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
133
|
+
Run `node checks/inline-edit.mjs` from `build/` after generating preview fixtures. `ALT_FIXTURE_ROOT=test/react19` selects the React 19 source fixtures. The checks cover editing in place (the value's text doesn't move, the control takes its font, the pencil and the field move nothing on hover, the caret lands where clicked, the seam, the announcement that clears itself), multiline (newline on Enter, Ctrl/Cmd+Enter, IME, Escape, caret at the end, growth to `maxRows`, line breaks in read mode), custom editors (focus, Escape layering, on-choose saves and rejections, unchanged choices, numeric validation), lifecycle races, retained input, uncertainty reconciliation, conflict latching, keyboard/IME, focus, disabled behavior and the four-scheme responsive/accessibility matrix. Automated checks do not replace the human screen-reader, touch, magnification or formative comparisons recorded in [Actions in place validation](https://github.com/richlaconte/altitude/blob/v0.5.1/project/ActionsInPlaceValidation.md).
|
|
134
134
|
|
|
135
135
|
<!-- example: generated from build/previews.txt by build/previews.mjs. Edit the preview, not this section. -->
|
|
136
136
|
## Example
|
|
@@ -55,9 +55,11 @@ export default function App() {
|
|
|
55
55
|
return (
|
|
56
56
|
<div className="col">
|
|
57
57
|
<div className="sb">{f('name', 'Workspace name')}{f('domain', 'Domain')}{f('seats', 'Seats')}{f('region', 'Region')}</div>
|
|
58
|
-
<Switch label="Make the next save fail" checked={failNext} onCheckedChange={setFailNext} />
|
|
59
58
|
<p className="cap">Change a field: once the change settles, the bar rises from the bottom edge. ⌘S or Save hovers while saving and lowers away when saved; a failed save drops into a trench and keeps your changes.</p>
|
|
60
59
|
<SaveBar record={record} />
|
|
60
|
+
<details className="preview-fixtures"><summary>Example fixtures</summary>
|
|
61
|
+
<Switch label="Make the next save fail" checked={failNext} onCheckedChange={setFailNext} />
|
|
62
|
+
</details>
|
|
61
63
|
</div>
|
|
62
64
|
);
|
|
63
65
|
}
|
package/dist/guidance/index.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": "altitude-design",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.1",
|
|
5
5
|
"entry": "README.md",
|
|
6
6
|
"design": "visual/README.md",
|
|
7
7
|
"patterns": [
|
|
@@ -1087,16 +1087,16 @@
|
|
|
1087
1087
|
"scripts/build-framework-fixture.mjs": "references/scripts/build-framework-fixture.mjs"
|
|
1088
1088
|
},
|
|
1089
1089
|
"sourceHashes": {
|
|
1090
|
-
"build/checks/agent-action-pattern.mjs": "
|
|
1090
|
+
"build/checks/agent-action-pattern.mjs": "3a28b6ae2e8e7cfa4c6c81653ab968f1f36db483d9c05fb966b93540a0fb66c3",
|
|
1091
1091
|
"build/checks/agent-setup.mjs": "173dac8125bf1201db023d42a862d3c6f226ee3886efe40079fbd87e4fc53e8b",
|
|
1092
|
-
"build/checks/assistant-conversation-pattern.mjs": "
|
|
1092
|
+
"build/checks/assistant-conversation-pattern.mjs": "14777b35732ac0b07401f46f844091b8d343a7f51a266e496169cb62daffed18",
|
|
1093
1093
|
"build/checks/audit-log-pattern.mjs": "af7770e7bf08caa9e1875161e4fc39509e4f0a84e612cdf79cb547cb6046af74",
|
|
1094
1094
|
"build/checks/auth-pattern.mjs": "7406cfa7c29c3bb3ac9075c8af079c6f7fd0bc296e81fef1c62667ec245c660b",
|
|
1095
1095
|
"build/checks/billing-pattern.mjs": "75e1809769420bc4c714ba0ddb1298489af7152603018d980182e6131182edc2",
|
|
1096
1096
|
"build/checks/developer-settings-pattern.mjs": "946cf163177db4aa4dfa30dac754d0229bc4b703ef1eac17a17dc35d19e2f093",
|
|
1097
1097
|
"build/checks/guidance.mjs": "ccbf3f1138a99106b3811a41304752be012c1a2a16fede1469271f7235b08636",
|
|
1098
1098
|
"build/checks/import-pattern.mjs": "6b98c0533bb0d8584ba0d677e579a0fdfdbdb5bd4663f261ecbdfb39181c45f6",
|
|
1099
|
-
"build/checks/members-pattern.mjs": "
|
|
1099
|
+
"build/checks/members-pattern.mjs": "ab46f394037fb4b21860987a6bca2d01e823496bf40a18f4a21065e955ae573a",
|
|
1100
1100
|
"build/checks/onboarding-pattern.mjs": "721ef5a202365d3597985bff9ade68bf3312c309687e846ce9a1669dcc00cae2",
|
|
1101
1101
|
"build/checks/pattern-types.mjs": "858431d8b622af096b8a41f35df1789343f96aa07433e8a98185b8740a1ded19",
|
|
1102
1102
|
"build/checks/pattern-workflows.mjs": "72e708399c0141c2b62ca94ab96382eb0e000df9d5a54045be814e261d9a9bdc",
|
|
@@ -1104,29 +1104,29 @@
|
|
|
1104
1104
|
"build/checks/render-tells.mjs": "93eae3f005f2a93654e111627a343440a7d87fa4b11c7c9403283b627fc1834c",
|
|
1105
1105
|
"build/checks/screen-layout-pattern.mjs": "c744bb32b29da50e2a1d852c1005b42addc0e1d7a98297e168f8ce7d51e4ad93",
|
|
1106
1106
|
"build/checks/semantics.mjs": "2ee7689b0472dba2e782ff19304e01018ca470b252fe7137e82bb36a3e0042c0",
|
|
1107
|
-
"build/checks/settings-pattern.mjs": "
|
|
1107
|
+
"build/checks/settings-pattern.mjs": "8830130d4e62294bd759b056e96aef264490a94e8c686d5a9bcfe0f1135f8691",
|
|
1108
1108
|
"build/checks/source-check.mjs": "07a22ce606b28e788ff501ff10da06ec66c2f947cf671d0cd57cb71e629007e0",
|
|
1109
1109
|
"build/checks/sync-pattern.mjs": "2cf9f1ac96be6c48948dea0ffab0fda0a909b5ff19e3e3f9835b6d8bcdd7fbef",
|
|
1110
1110
|
"build/checks/tells-lint.mjs": "f254fa9166f65a085d78cecf7ca66145151cd8b7868c732c25c44bbec2c2deac",
|
|
1111
1111
|
"build/fixtures/pattern-workflows.tsx": "6781938d83aa85f48c63fff98f9eb5b45fcb5531b6a49f902ec9d497f6e65265",
|
|
1112
|
-
"build/fixtures/patterns/agent-action.jsx": "
|
|
1112
|
+
"build/fixtures/patterns/agent-action.jsx": "6840e91a8cd6726adda221bb2d1baacbabc0618d56b80b783215606d4782d5d7",
|
|
1113
1113
|
"build/fixtures/patterns/app-skeleton.jsx": "d2d8e7d5373ee4d65c2e0ecc69451f35d9dfd4bed9f04cf66405cbe9c9478825",
|
|
1114
|
-
"build/fixtures/patterns/assistant-conversation.jsx": "
|
|
1114
|
+
"build/fixtures/patterns/assistant-conversation.jsx": "9d6b6232da8fd1097bc7d82ec91e7c081843f990531216962c3e9cb030f714d2",
|
|
1115
1115
|
"build/fixtures/patterns/audit-log.jsx": "ec1183de4c94c0309824b4187c082f7ea76d50a09953224e4164b4fc5fa70780",
|
|
1116
1116
|
"build/fixtures/patterns/auth.jsx": "1b41c43b734deb75acd8bfd34dae445e627381884abd23512e37bfb1d644eabe",
|
|
1117
1117
|
"build/fixtures/patterns/billing.jsx": "8f56ab9e6d09d73f1ae9ad5d690ff20372f9279d23010d6db7ef5e2a79d0100a",
|
|
1118
1118
|
"build/fixtures/patterns/developer-settings.jsx": "7803d792f516b5a1ee823436c505802954865720f7c8dbae0742a1adc0b2d490",
|
|
1119
1119
|
"build/fixtures/patterns/import.jsx": "3b4148a99bf90a477ae01a0905cae75200bc53427ea197cc2bcda0a9c2469ca2",
|
|
1120
|
-
"build/fixtures/patterns/members.jsx": "
|
|
1120
|
+
"build/fixtures/patterns/members.jsx": "df0e6ab0a6030cf09715e1ea78f01a8ca6c61dde10c2679a2c75fe47247dfdba",
|
|
1121
1121
|
"build/fixtures/patterns/onboarding.jsx": "3ae1325880efa862b84b5d9bcc0691bf6029e1f1ac031bb99adb6c0527c498a9",
|
|
1122
1122
|
"build/fixtures/patterns/screen-layout-decision.jsx": "409d5ce48ddef3ca5de3427155e901f06d142938474894e9eabbc167c910c47a",
|
|
1123
1123
|
"build/fixtures/patterns/screen-layout-editor.jsx": "a93c41d7590fd98fae48403c49e4d4e793b4e92e4cf5b8cc66e30ed0aa55ba68",
|
|
1124
1124
|
"build/fixtures/patterns/screen-layout-report.jsx": "5de2691104456175ef51d2e1d11c85b4075341457e8acd3d5495615c2fbeb0a9",
|
|
1125
|
-
"build/fixtures/patterns/settings.jsx": "
|
|
1125
|
+
"build/fixtures/patterns/settings.jsx": "ecf7a60de4ca08e58474c6cc83b9dcb1009d393e11f67d3e9f83b74e5c0837a0",
|
|
1126
1126
|
"build/fixtures/patterns/sync.jsx": "8474f762f7c63c4bd99fd337b080df1a788b4b92b2ced7fac5aaa1379b1a1eaf",
|
|
1127
|
-
"build/previews.txt": "
|
|
1127
|
+
"build/previews.txt": "0f076d2d802daa3a1df52d899903addd5e27ebcd49bb0835be60ed1cee67c6b5",
|
|
1128
1128
|
"docs/framework/AGENT-SETUP.md": "57b4ba98719fce472e08226a5c784ed4b9eb20241904445825cb2287a84a0162",
|
|
1129
|
-
"project/ActionsInPlace.md": "
|
|
1129
|
+
"project/ActionsInPlace.md": "6e92cffea09a960cbd872ae9208053b798939ce3145acc3404dac3b1272b1868",
|
|
1130
1130
|
"project/Charts.md": "9439a024d8123088f90bb49844f922ce50ba4f255d85e7e6324bb55eee07f287",
|
|
1131
1131
|
"project/Distinctiveness.md": "d2933b1d4c53622c31906154beca9edd89d457baa94fb4be3ae0fb8d414e76ce",
|
|
1132
1132
|
"project/Elevation.md": "100532c631803e9a97018b9da5ffff60acf7d80559f9f162ba9e371f5510371f",
|
|
@@ -1166,7 +1166,7 @@
|
|
|
1166
1166
|
"project/components/ColorPicker/README.md": "24a0f90b86d7b246976d8a41dc047c25bb4b6ccb80717f388783723f15497018",
|
|
1167
1167
|
"project/components/Combobox/README.md": "f19169c7453cba104859b28eb54e8ec0224bd6ab9263a28bca8bbb4be0c67151",
|
|
1168
1168
|
"project/components/CommandPalette/README.md": "a6bf308a4d791873cfedeaf190b422cd67ed4e6dbb7273f3b340f93432d7e741",
|
|
1169
|
-
"project/components/CommentThread/README.md": "
|
|
1169
|
+
"project/components/CommentThread/README.md": "a15f6473a03ba3c0fd04b6478349207725d1c73c508e8fdcc06c4d26718ee56a",
|
|
1170
1170
|
"project/components/Confirmation/README.md": "c6ed60c3ae6c563da1a5473546d14986ecfe5ecf691794ee3e6d89e39f4e3ed4",
|
|
1171
1171
|
"project/components/ContextMenu/README.md": "ab86dfa366dd2bacc98e6b01b45cc6e9919301e680a1d19798a0902b1b23475a",
|
|
1172
1172
|
"project/components/Conversation/README.md": "13ad68c8d4c5a5687245d64136f413d3edc62ce06efcaa0a5771004157ec04f0",
|
|
@@ -1215,7 +1215,7 @@
|
|
|
1215
1215
|
"project/components/RelativeTime/README.md": "5b1a7f716825233b457319c2398ba574419a757c2c92c11223dac5d64a9990a2",
|
|
1216
1216
|
"project/components/RemovalReceipt/README.md": "b5a0392079b5f0db25ea12fa1e40fc5a2b7415360e9c35ecf523462fa88adc66",
|
|
1217
1217
|
"project/components/Resizable/README.md": "c166d0af35119ec622919a7c274696deee465beb3b3a999e263d5ea9d248c1f1",
|
|
1218
|
-
"project/components/SaveBar/README.md": "
|
|
1218
|
+
"project/components/SaveBar/README.md": "7c2babe2cc3254122f438b67d0b6568135d235402261d83f7be127e6b8cf0f29",
|
|
1219
1219
|
"project/components/SavedViews/README.md": "1eb6996c7ba7b6fe2f680603f66c4dcb0b2e98b5901dfa1ad405fd967a2e3fab",
|
|
1220
1220
|
"project/components/ScatterChart/README.md": "73f447b83eea8093ffca91b260a71102bd4e5d7953b4028ffd005f29276bd8c6",
|
|
1221
1221
|
"project/components/Schedule/README.md": "cab13327ec2b8ff9c317dc19ac12390705f15f9f9d61b94c3bc52810cb54ce82",
|
package/dist/guidance/llms.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Altitude 0.5.
|
|
1
|
+
# Altitude 0.5.1
|
|
2
2
|
|
|
3
3
|
> Altitude's guidance for this installed version of altitude-design: the design rules, the task patterns and every component's guide. Height is the interface: settled content sits on the ground, anything live rises above it, anything waiting to receive sinks below it.
|
|
4
4
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"files": {
|
|
5
5
|
"agent-setup.md": "57b4ba98719fce472e08226a5c784ed4b9eb20241904445825cb2287a84a0162",
|
|
6
6
|
"app-skeleton.md": "bc70896a86f4c1dbd3467620562eec62ccf99a9356ff72a7eab8621f492554d9",
|
|
7
7
|
"components/Accordion/README.md": "b166e499eb3604ef84a375818db3aec91c5459870b5d6cd3133ecbdf36e145d6",
|
|
8
|
-
"components/AgentFleet/README.md": "
|
|
8
|
+
"components/AgentFleet/README.md": "3758d4181a85a909ddec8f847ee3ec540da408fb80b6c2c3ce4775756d0c8c1f",
|
|
9
9
|
"components/AgentLanes/README.md": "247eb6e0ead0de5f15da920f083dbaa4150673723b081acf70e19026f982cd16",
|
|
10
10
|
"components/AgentRequests/README.md": "e7ac986cef68b09b5a7df7d1c11cf44ef8d417a3d22f9436f7cea1d8b4190c18",
|
|
11
11
|
"components/AILabel/README.md": "0002447d340029fe28652ed26c474c91edf89a0e23be300d24c198afb7086646",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"components/ColorPicker/README.md": "24a0f90b86d7b246976d8a41dc047c25bb4b6ccb80717f388783723f15497018",
|
|
35
35
|
"components/Combobox/README.md": "f19169c7453cba104859b28eb54e8ec0224bd6ab9263a28bca8bbb4be0c67151",
|
|
36
36
|
"components/CommandPalette/README.md": "a6bf308a4d791873cfedeaf190b422cd67ed4e6dbb7273f3b340f93432d7e741",
|
|
37
|
-
"components/CommentThread/README.md": "
|
|
37
|
+
"components/CommentThread/README.md": "a15f6473a03ba3c0fd04b6478349207725d1c73c508e8fdcc06c4d26718ee56a",
|
|
38
38
|
"components/Confirmation/README.md": "c6ed60c3ae6c563da1a5473546d14986ecfe5ecf691794ee3e6d89e39f4e3ed4",
|
|
39
39
|
"components/ContextMenu/README.md": "ab86dfa366dd2bacc98e6b01b45cc6e9919301e680a1d19798a0902b1b23475a",
|
|
40
40
|
"components/Conversation/README.md": "13ad68c8d4c5a5687245d64136f413d3edc62ce06efcaa0a5771004157ec04f0",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"components/HoldButton/README.md": "bb81a002a2d37701a84a04123fbabd8cb820c52befaacaaf881de48d12f733f5",
|
|
58
58
|
"components/HoverCard/README.md": "23e6de1b79fa302b2ce168431fd15339b33132663911521594882f338c1ca366",
|
|
59
59
|
"components/InlineCitation/README.md": "b3f66c18bdf054f818525fbcf5f5db36535d121289f6d0451413ac0803bf8edd",
|
|
60
|
-
"components/InlineEdit/README.md": "
|
|
60
|
+
"components/InlineEdit/README.md": "38d2f3b1b2368c8c690a55e0546db995b65897cd07c4c33d0b200c14e557ca30",
|
|
61
61
|
"components/Input/README.md": "8b7df74399ce471bead1c81967e63ca1bb249aebd827abefd4fbf1a6a2a13e26",
|
|
62
62
|
"components/InputOTP/README.md": "e1a17bca55de012b26f25dca299d7ffe01b21248efde19bea63ebeac4e2625aa",
|
|
63
63
|
"components/ItemGroup/README.md": "87a1e6c3e124aec1012ef71dc69c3e5ab85feeb4735fa0b77db449a22692f6e8",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"components/RelativeTime/README.md": "5b1a7f716825233b457319c2398ba574419a757c2c92c11223dac5d64a9990a2",
|
|
84
84
|
"components/RemovalReceipt/README.md": "30ab65617692614d846298cb103d7737a5ba464610f44cda64bd0d737cefbc88",
|
|
85
85
|
"components/Resizable/README.md": "c166d0af35119ec622919a7c274696deee465beb3b3a999e263d5ea9d248c1f1",
|
|
86
|
-
"components/SaveBar/README.md": "
|
|
86
|
+
"components/SaveBar/README.md": "7c2babe2cc3254122f438b67d0b6568135d235402261d83f7be127e6b8cf0f29",
|
|
87
87
|
"components/SavedViews/README.md": "1eb6996c7ba7b6fe2f680603f66c4dcb0b2e98b5901dfa1ad405fd967a2e3fab",
|
|
88
88
|
"components/ScatterChart/README.md": "ff9a5f079a75dabeb2df15d2c8db7282f280aae159ad618dfbaa5d25c8a77150",
|
|
89
89
|
"components/Schedule/README.md": "cab13327ec2b8ff9c317dc19ac12390705f15f9f9d61b94c3bc52810cb54ce82",
|
|
@@ -118,8 +118,8 @@
|
|
|
118
118
|
"components/Trace/README.md": "62c571b2d96a83e5515988eacecd47de3e2c1a2452476d00645d1a26d3cbae3d",
|
|
119
119
|
"components/Tree/README.md": "9fadf66c7d223653bd299362e997c814f06baf2a9c59f8ebc15ef9a0a24235e4",
|
|
120
120
|
"evidence.json": "71e9602167286fb714419d0e89a80d4765b632c910d51875d1b167fd1ee499d9",
|
|
121
|
-
"index.json": "
|
|
122
|
-
"llms.txt": "
|
|
121
|
+
"index.json": "613707136c882562c94686f3400f31839e6fbd4352272ca5b187a5addef3a497",
|
|
122
|
+
"llms.txt": "705e875de8e0f52824c83a01f180303c20d771fa0f6a67792002c1cdf3a39353",
|
|
123
123
|
"pattern.schema.json": "abcb37bd5de4a74f27ac079e587e5d288b23e491569a73971f1a31131a37d309",
|
|
124
124
|
"patterns/agent-action.json": "532915c25183d1a6093d9e14b929f3e49d29e400b116ef0612d933d70d49b09a",
|
|
125
125
|
"patterns/agent-action.md": "a11e9d98a84d8a0fae755bae3e618e7daa2608f1f853cfe88e2e58ee74cc01e7",
|
|
@@ -155,16 +155,16 @@
|
|
|
155
155
|
"patterns/sync.md": "9b6c6928fe19c6f28b88bd092997c0c0645aedddf02a25327a1c7c60969e3729",
|
|
156
156
|
"principles.md": "1c57c684c4b0029012a79d6a38b26b8821abf75852b14db2b18b7e7f6d364b32",
|
|
157
157
|
"README.md": "bde7983588a9fd0f7bbcc0d282dc110ecb4811cd5753a4ea835399c7ea7ff520",
|
|
158
|
-
"references/build/checks/agent-action-pattern.mjs": "
|
|
158
|
+
"references/build/checks/agent-action-pattern.mjs": "3a28b6ae2e8e7cfa4c6c81653ab968f1f36db483d9c05fb966b93540a0fb66c3",
|
|
159
159
|
"references/build/checks/agent-setup.mjs": "173dac8125bf1201db023d42a862d3c6f226ee3886efe40079fbd87e4fc53e8b",
|
|
160
|
-
"references/build/checks/assistant-conversation-pattern.mjs": "
|
|
160
|
+
"references/build/checks/assistant-conversation-pattern.mjs": "14777b35732ac0b07401f46f844091b8d343a7f51a266e496169cb62daffed18",
|
|
161
161
|
"references/build/checks/audit-log-pattern.mjs": "af7770e7bf08caa9e1875161e4fc39509e4f0a84e612cdf79cb547cb6046af74",
|
|
162
162
|
"references/build/checks/auth-pattern.mjs": "7406cfa7c29c3bb3ac9075c8af079c6f7fd0bc296e81fef1c62667ec245c660b",
|
|
163
163
|
"references/build/checks/billing-pattern.mjs": "75e1809769420bc4c714ba0ddb1298489af7152603018d980182e6131182edc2",
|
|
164
164
|
"references/build/checks/developer-settings-pattern.mjs": "946cf163177db4aa4dfa30dac754d0229bc4b703ef1eac17a17dc35d19e2f093",
|
|
165
165
|
"references/build/checks/guidance.mjs": "ccbf3f1138a99106b3811a41304752be012c1a2a16fede1469271f7235b08636",
|
|
166
166
|
"references/build/checks/import-pattern.mjs": "6b98c0533bb0d8584ba0d677e579a0fdfdbdb5bd4663f261ecbdfb39181c45f6",
|
|
167
|
-
"references/build/checks/members-pattern.mjs": "
|
|
167
|
+
"references/build/checks/members-pattern.mjs": "ab46f394037fb4b21860987a6bca2d01e823496bf40a18f4a21065e955ae573a",
|
|
168
168
|
"references/build/checks/onboarding-pattern.mjs": "721ef5a202365d3597985bff9ade68bf3312c309687e846ce9a1669dcc00cae2",
|
|
169
169
|
"references/build/checks/pattern-types.mjs": "858431d8b622af096b8a41f35df1789343f96aa07433e8a98185b8740a1ded19",
|
|
170
170
|
"references/build/checks/pattern-workflows.mjs": "72e708399c0141c2b62ca94ab96382eb0e000df9d5a54045be814e261d9a9bdc",
|
|
@@ -172,25 +172,25 @@
|
|
|
172
172
|
"references/build/checks/render-tells.mjs": "93eae3f005f2a93654e111627a343440a7d87fa4b11c7c9403283b627fc1834c",
|
|
173
173
|
"references/build/checks/screen-layout-pattern.mjs": "c744bb32b29da50e2a1d852c1005b42addc0e1d7a98297e168f8ce7d51e4ad93",
|
|
174
174
|
"references/build/checks/semantics.mjs": "2ee7689b0472dba2e782ff19304e01018ca470b252fe7137e82bb36a3e0042c0",
|
|
175
|
-
"references/build/checks/settings-pattern.mjs": "
|
|
175
|
+
"references/build/checks/settings-pattern.mjs": "8830130d4e62294bd759b056e96aef264490a94e8c686d5a9bcfe0f1135f8691",
|
|
176
176
|
"references/build/checks/source-check.mjs": "07a22ce606b28e788ff501ff10da06ec66c2f947cf671d0cd57cb71e629007e0",
|
|
177
177
|
"references/build/checks/sync-pattern.mjs": "2cf9f1ac96be6c48948dea0ffab0fda0a909b5ff19e3e3f9835b6d8bcdd7fbef",
|
|
178
178
|
"references/build/checks/tells-lint.mjs": "f254fa9166f65a085d78cecf7ca66145151cd8b7868c732c25c44bbec2c2deac",
|
|
179
179
|
"references/build/fixtures/pattern-workflows.tsx": "6781938d83aa85f48c63fff98f9eb5b45fcb5531b6a49f902ec9d497f6e65265",
|
|
180
|
-
"references/build/fixtures/patterns/agent-action.jsx": "
|
|
180
|
+
"references/build/fixtures/patterns/agent-action.jsx": "6840e91a8cd6726adda221bb2d1baacbabc0618d56b80b783215606d4782d5d7",
|
|
181
181
|
"references/build/fixtures/patterns/app-skeleton.jsx": "d2d8e7d5373ee4d65c2e0ecc69451f35d9dfd4bed9f04cf66405cbe9c9478825",
|
|
182
|
-
"references/build/fixtures/patterns/assistant-conversation.jsx": "
|
|
182
|
+
"references/build/fixtures/patterns/assistant-conversation.jsx": "9d6b6232da8fd1097bc7d82ec91e7c081843f990531216962c3e9cb030f714d2",
|
|
183
183
|
"references/build/fixtures/patterns/audit-log.jsx": "ec1183de4c94c0309824b4187c082f7ea76d50a09953224e4164b4fc5fa70780",
|
|
184
184
|
"references/build/fixtures/patterns/auth.jsx": "1b41c43b734deb75acd8bfd34dae445e627381884abd23512e37bfb1d644eabe",
|
|
185
185
|
"references/build/fixtures/patterns/billing.jsx": "8f56ab9e6d09d73f1ae9ad5d690ff20372f9279d23010d6db7ef5e2a79d0100a",
|
|
186
186
|
"references/build/fixtures/patterns/developer-settings.jsx": "7803d792f516b5a1ee823436c505802954865720f7c8dbae0742a1adc0b2d490",
|
|
187
187
|
"references/build/fixtures/patterns/import.jsx": "3b4148a99bf90a477ae01a0905cae75200bc53427ea197cc2bcda0a9c2469ca2",
|
|
188
|
-
"references/build/fixtures/patterns/members.jsx": "
|
|
188
|
+
"references/build/fixtures/patterns/members.jsx": "df0e6ab0a6030cf09715e1ea78f01a8ca6c61dde10c2679a2c75fe47247dfdba",
|
|
189
189
|
"references/build/fixtures/patterns/onboarding.jsx": "3ae1325880efa862b84b5d9bcc0691bf6029e1f1ac031bb99adb6c0527c498a9",
|
|
190
190
|
"references/build/fixtures/patterns/screen-layout-decision.jsx": "409d5ce48ddef3ca5de3427155e901f06d142938474894e9eabbc167c910c47a",
|
|
191
191
|
"references/build/fixtures/patterns/screen-layout-editor.jsx": "a93c41d7590fd98fae48403c49e4d4e793b4e92e4cf5b8cc66e30ed0aa55ba68",
|
|
192
192
|
"references/build/fixtures/patterns/screen-layout-report.jsx": "5de2691104456175ef51d2e1d11c85b4075341457e8acd3d5495615c2fbeb0a9",
|
|
193
|
-
"references/build/fixtures/patterns/settings.jsx": "
|
|
193
|
+
"references/build/fixtures/patterns/settings.jsx": "ecf7a60de4ca08e58474c6cc83b9dcb1009d393e11f67d3e9f83b74e5c0837a0",
|
|
194
194
|
"references/build/fixtures/patterns/sync.jsx": "8474f762f7c63c4bd99fd337b080df1a788b4b92b2ced7fac5aaa1379b1a1eaf",
|
|
195
195
|
"references/project/components/src/pattern-async-collection.tsx": "9e4df2265d1de6f269278eb4a42d8d63b3ef74a881a455eb17102be477ecbf4d",
|
|
196
196
|
"references/project/components/src/pattern-consequential-action.tsx": "ffe49b7a9fa978e9177c6f3d839d311bdd3da913a6eeedc241800b10fc3287f7",
|
|
@@ -199,15 +199,15 @@
|
|
|
199
199
|
"references/project/components/src/settings.tsx": "957a04e37936746f2b6b4086d8e2f866ce71f7fb9dded8ba81fff56840206e01",
|
|
200
200
|
"references/scripts/build-framework-fixture.mjs": "1b4a2d7ece0459d2c4df2ec067d8d3b9d00110f2af1cef3be6042ab8f9ea90c9",
|
|
201
201
|
"rules.json": "552c8328f60adc9eef4aa9aeed098e3a5c617e993bd300781389da8ad0e402c9",
|
|
202
|
-
"visual/ActionsInPlace.md": "
|
|
202
|
+
"visual/ActionsInPlace.md": "6d6370b2da6b2664096c74edb0404d4c41eff5c836c366cf0b53fc307413853a",
|
|
203
203
|
"visual/Charts.md": "9439a024d8123088f90bb49844f922ce50ba4f255d85e7e6324bb55eee07f287",
|
|
204
|
-
"visual/Distinctiveness.md": "
|
|
204
|
+
"visual/Distinctiveness.md": "c3f9c7884ec2a5880257ad6ee80ba03f2f8c63e9e127b0d9424a978b714716f4",
|
|
205
205
|
"visual/Elevation.md": "50f2aeefd457e1a329cc80578b196c48cbf0c019a5f43d75901d92b4b4632c44",
|
|
206
206
|
"visual/Fundamentals.md": "65120fd170ff8ea9f50b1498bfedc8c45dbe1a616bfccc32664213e5404d3a32",
|
|
207
207
|
"visual/Mobile.md": "511db58119a1653c2c00e2ccb34c6cf943de93f2184dec0faf3228f563e0b1b7",
|
|
208
208
|
"visual/Motion.md": "7fa4e7501b710a5599c7a8c99e531f2b9b1b4dfeba6a6a4d9716685d45f33d31",
|
|
209
209
|
"visual/README.md": "08c3a9ef3ff53a0fb8f9f873240022edefc67739a16d1f50c3a47367f72fc9f9",
|
|
210
|
-
"visual/Research.md": "
|
|
211
|
-
"visual/Theming.md": "
|
|
210
|
+
"visual/Research.md": "fea667b84b3ac4c73b31b7a033c43c6323a5ee38e71ab930d4da1e57048bc096",
|
|
211
|
+
"visual/Theming.md": "3b922953bdb1040cf240aa3d69eef1d502c1f6d6f33a8ea0bcb5d8e608c31b5a"
|
|
212
212
|
}
|
|
213
213
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// failed step says nothing changed and retries; the changed record carries an AI label naming the approver. Run after a
|
|
5
5
|
// render of every preview (it opens test/p-AgentActionPattern-daylight.html); exits non-zero on a failure.
|
|
6
6
|
import { chromium } from 'playwright-core';
|
|
7
|
+
import { openFixtures } from './preview-fixtures.mjs';
|
|
7
8
|
const browser = await chromium.launch(process.env.CHROME ? { executablePath: process.env.CHROME } : {});
|
|
8
9
|
const T = new URL('../test/', import.meta.url).pathname;
|
|
9
10
|
let pass = 0, fail = 0;
|
|
@@ -43,6 +44,7 @@ await page.getByRole('button', { name: 'Undo archive' }).click();
|
|
|
43
44
|
await page.waitForTimeout(200);
|
|
44
45
|
expect(/Archive undone/.test(await page.evaluate(() => document.querySelector('.ag-receipt').textContent)), 'Undo reverses the reversible step');
|
|
45
46
|
|
|
47
|
+
await openFixtures(page);
|
|
46
48
|
await page.getByRole('switch', { name: 'Make the next step fail' }).click();
|
|
47
49
|
await page.getByRole('button', { name: 'Run again' }).click();
|
|
48
50
|
await page.waitForTimeout(1100);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// words. Run after a render of every preview (it opens test/p-AssistantConversationPattern-daylight.html); exits
|
|
6
6
|
// non-zero on a failure.
|
|
7
7
|
import { chromium } from 'playwright-core';
|
|
8
|
+
import { openFixtures } from './preview-fixtures.mjs';
|
|
8
9
|
const browser = await chromium.launch(process.env.CHROME ? { executablePath: process.env.CHROME } : {});
|
|
9
10
|
const T = new URL('../test/', import.meta.url).pathname;
|
|
10
11
|
let pass = 0, fail = 0;
|
|
@@ -26,6 +27,7 @@ await page.click('.alt-msg[data-from="assistant"] button:has-text("Retry")'); aw
|
|
|
26
27
|
a = await answer();
|
|
27
28
|
expect(a.stream === 'complete' && a.text.includes('decision from legal by Friday'), `Retry completes the answer (${a.stream})`);
|
|
28
29
|
// Offline: the message stays in the composer, said in words.
|
|
30
|
+
await openFixtures(page);
|
|
29
31
|
await page.click('[role="radio"]:has-text("Offline"), button:has-text("Offline")'); await page.waitForTimeout(100);
|
|
30
32
|
await box.fill('Summarise it'); await box.press('Enter'); await page.waitForTimeout(700);
|
|
31
33
|
let r = await read();
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// what they lose and is said once done; revoking an invitation is said and focus goes to the heading. Run after a render
|
|
6
6
|
// of every preview (it opens test/p-MembersPattern-daylight.html); exits non-zero on a failure.
|
|
7
7
|
import { chromium } from 'playwright-core';
|
|
8
|
+
import { openFixtures } from './preview-fixtures.mjs';
|
|
8
9
|
const browser = await chromium.launch(process.env.CHROME ? { executablePath: process.env.CHROME } : {});
|
|
9
10
|
const T = new URL('../test/', import.meta.url).pathname;
|
|
10
11
|
let pass = 0, fail = 0;
|
|
@@ -43,6 +44,7 @@ expect(r.status === 'pending' && /Changing role…/.test(r.text), `a role change
|
|
|
43
44
|
await page.waitForTimeout(700);
|
|
44
45
|
r = await row('Theo Marsh');
|
|
45
46
|
expect(r.status === 'committed' && /Role changed/.test(r.text), 'and lands as changed');
|
|
47
|
+
await openFixtures(page);
|
|
46
48
|
await page.getByRole('switch', { name: 'Make the next role change fail' }).click();
|
|
47
49
|
await page.getByRole('button', { name: 'Role for Ines Duarte' }).click();
|
|
48
50
|
await page.getByRole('option', { name: 'Viewer' }).click();
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// needs the workspace's name typed into a stationary dialog. Run after a render of every preview (it opens
|
|
6
6
|
// test/p-SettingsPattern-daylight.html); exits non-zero on a failure.
|
|
7
7
|
import { chromium } from 'playwright-core';
|
|
8
|
+
import { openFixtures } from './preview-fixtures.mjs';
|
|
8
9
|
const browser = await chromium.launch(process.env.CHROME ? { executablePath: process.env.CHROME } : {});
|
|
9
10
|
const T = new URL('../test/', import.meta.url).pathname;
|
|
10
11
|
let pass = 0, fail = 0;
|
|
@@ -29,6 +30,7 @@ expect(await page.evaluate(() => getComputedStyle(document.querySelector('.alt-s
|
|
|
29
30
|
await page.waitForTimeout(800);
|
|
30
31
|
r = await row('Weekly digest');
|
|
31
32
|
expect(r.status === 'committed' && r.words === 'Saved' && r.checked === 'false', `then lands, saved (${JSON.stringify(r)})`);
|
|
33
|
+
await openFixtures(page);
|
|
32
34
|
await page.getByRole('switch', { name: 'Make the next change fail' }).click();
|
|
33
35
|
await page.getByRole('switch', { name: 'Mentions' }).click();
|
|
34
36
|
await page.waitForTimeout(1300);
|
|
@@ -24,36 +24,40 @@ function App() {
|
|
|
24
24
|
const stepFor = (c) => (c === 'requested' ? 'awaiting-approval' : c === 'running' || c === 'approved' ? 'running' : c === 'failed' ? 'failed' : 'done');
|
|
25
25
|
const ready = archive === 'done';
|
|
26
26
|
return (
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
27
|
+
<>
|
|
28
|
+
<main className="ag-page">
|
|
29
|
+
<div className="ag-ask"><span className="ag-who">You asked</span><p>Clean up leads nobody has touched since July, and tell their owners.</p></div>
|
|
30
|
+
<A.Trace aria-label="Assistant run: clean up stale leads">
|
|
31
|
+
<A.TraceStep title="Find leads untouched since July" status={search} duration={search === 'done' ? 900 : undefined}
|
|
32
|
+
error={search === 'failed' ? 'The CRM didn’t answer in time. Nothing was changed.' : undefined} onRetry={search === 'failed' ? runSearch : undefined}>
|
|
33
|
+
<A.TraceToolCall name="search_leads" input={{ untouchedSince: '2026-07-01', limit: 50 }} output={search === 'done' ? { found: 4 } : undefined} />
|
|
34
|
+
</A.TraceStep>
|
|
35
|
+
<A.TraceStep title="Archive 4 stale leads" status={archive}>
|
|
36
|
+
{archive === 'done' && <div className="ag-receipt"><span role="status">{undone ? 'Archive undone. The 4 leads are back.' : '4 leads archived. You can undo this for 30 days.'}</span>
|
|
37
|
+
{!undone && <A.Button size="sm" variant="ghost" onClick={() => setUndone(true)}>Undo archive</A.Button>}</div>}
|
|
38
|
+
</A.TraceStep>
|
|
39
|
+
<A.TraceStep title={email === 'rejected' ? 'Didn’t email the lead owners' : 'Email 3 lead owners'} status={ready ? stepFor(email) : 'planned'}>
|
|
40
|
+
{ready && <A.Confirmation state={email} title="Email 3 lead owners" requestedBy="The assistant" resolvedBy="Maya Chen"
|
|
41
|
+
consequence="Theo Marsh, Ines Duarte and Sam Okafor will get an email listing the leads that were archived."
|
|
42
|
+
approveLabel="Send 3 emails" rejectLabel="Don’t send" runningLabel="Sending…" doneLabel="3 emails sent" failedLabel="The emails weren’t sent."
|
|
43
|
+
onApprove={() => resolve(setEmail, !fail.current)} onReject={() => setEmail('rejected')} onRetry={() => resolve(setEmail, true)} />}
|
|
44
|
+
</A.TraceStep>
|
|
45
|
+
<A.TraceStep title="Delete the “Summer import” list for good" status={ready && email !== 'requested' ? stepFor(purge) : 'planned'}>
|
|
46
|
+
{ready && email !== 'requested' && <A.Confirmation state={purge} escalate="dialog" title="Delete the “Summer import” list" resolvedBy="Maya Chen"
|
|
47
|
+
consequence="The list and its 212 rows are deleted permanently. Leads in it stay; only the list goes."
|
|
48
|
+
approveLabel="Delete list" rejectLabel="Keep the list" runningLabel="Deleting…" doneLabel="List deleted"
|
|
49
|
+
onApprove={() => resolve(setPurge, true)} onReject={() => setPurge('rejected')} />}
|
|
50
|
+
</A.TraceStep>
|
|
51
|
+
</A.Trace>
|
|
52
|
+
{email === 'done' && <section className="ag-record" aria-labelledby="ag-rec-h"><h3 id="ag-rec-h" className="ag-sub">Northwind Traders</h3>
|
|
53
|
+
<p className="ag-line">Status: Archived <A.AILabel subject="Change" model="Opus 5.5" reviewedBy="Maya Chen" generatedAt="2026-10-30T09:00:00Z" /></p>
|
|
54
|
+
<p className="ag-muted">Archived by the assistant, approved by Maya Chen.</p>
|
|
55
|
+
</section>}
|
|
56
|
+
</main>
|
|
57
|
+
<details className="preview-fixtures"><summary>Example fixtures</summary>
|
|
58
|
+
<div className="ag-demo"><A.Switch label="Make the next step fail" checked={failNext} onCheckedChange={setFailNext} /><A.Button size="sm" onClick={restart}>Run again</A.Button></div>
|
|
59
|
+
</details>
|
|
60
|
+
</>
|
|
57
61
|
);
|
|
58
62
|
}
|
|
59
63
|
// preview:end
|
|
@@ -32,12 +32,6 @@ function Thread({ restored }) {
|
|
|
32
32
|
React.useEffect(() => { if (turn.state === 'complete') setUsed((u) => Math.min(99, u + 9)); }, [turn.state]);
|
|
33
33
|
return (
|
|
34
34
|
<div className="col ac">
|
|
35
|
-
<A.ToggleGroup type="single" size="sm" aria-label="Make the next send fail" value={failure} onValueChange={(v) => setFailure(/** @type {any} */ (v) || 'none')}>
|
|
36
|
-
<A.ToggleGroupItem value="none">Works</A.ToggleGroupItem>
|
|
37
|
-
<A.ToggleGroupItem value="offline">Offline</A.ToggleGroupItem>
|
|
38
|
-
<A.ToggleGroupItem value="rate-limited">Rate limited</A.ToggleGroupItem>
|
|
39
|
-
<A.ToggleGroupItem value="context-full">Context full</A.ToggleGroupItem>
|
|
40
|
-
</A.ToggleGroup>
|
|
41
35
|
<A.Conversation aria-label="Assistant">
|
|
42
36
|
<A.ConversationContent>
|
|
43
37
|
{turn.input !== undefined && <A.Message from="user"><A.MessageContent>{turn.input}</A.MessageContent></A.Message>}
|
|
@@ -61,6 +55,14 @@ function Thread({ restored }) {
|
|
|
61
55
|
<A.PromptInputSubmit />
|
|
62
56
|
</A.PromptInputToolbar>
|
|
63
57
|
</A.PromptInput>
|
|
58
|
+
<details className="preview-fixtures"><summary>Example fixtures</summary>
|
|
59
|
+
<A.ToggleGroup type="single" size="sm" aria-label="Make the next send fail" value={failure} onValueChange={(v) => setFailure(/** @type {any} */ (v) || 'none')}>
|
|
60
|
+
<A.ToggleGroupItem value="none">Works</A.ToggleGroupItem>
|
|
61
|
+
<A.ToggleGroupItem value="offline">Offline</A.ToggleGroupItem>
|
|
62
|
+
<A.ToggleGroupItem value="rate-limited">Rate limited</A.ToggleGroupItem>
|
|
63
|
+
<A.ToggleGroupItem value="context-full">Context full</A.ToggleGroupItem>
|
|
64
|
+
</A.ToggleGroup>
|
|
65
|
+
</details>
|
|
64
66
|
</div>
|
|
65
67
|
);
|
|
66
68
|
}
|
|
@@ -76,30 +76,34 @@ function App() {
|
|
|
76
76
|
setStatus([fresh.length && `${fresh.length} ${fresh.length === 1 ? 'invite' : 'invites'} sent`, already && `${already} ${already === 1 ? 'address is' : 'addresses are'} already in the workspace`].filter(Boolean).join(', ') + '.');
|
|
77
77
|
};
|
|
78
78
|
return (
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
<A.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
79
|
+
<>
|
|
80
|
+
<main className="mb-page">
|
|
81
|
+
<h2 id="mb-heading" tabIndex={-1} className="mb-h">Members</h2>
|
|
82
|
+
<A.Card className="mb-invite" aria-labelledby="mb-invite-h">
|
|
83
|
+
<h3 id="mb-invite-h" className="mb-sub">Invite people</h3>
|
|
84
|
+
<A.Field label="Email addresses" hint="Separate addresses with commas, or paste a list.">
|
|
85
|
+
<A.TagInput value={emails} onValueChange={setEmails} noun={['address', 'addresses']} placeholder="name@acme.dev" disabled={sending}
|
|
86
|
+
normalize={(t) => t.trim().toLowerCase()} validate={(t) => (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t) ? undefined : `${t} isn’t an email address.`)} />
|
|
87
|
+
</A.Field>
|
|
88
|
+
<div className="mb-roles"><span id="mb-role-label" className="mb-legend">Role</span>
|
|
89
|
+
<A.RadioGroup value={role} onValueChange={setRole} aria-labelledby="mb-role-label">{ROLES.map((r) => <A.Radio key={r.value} value={r.value} label={r.label} description={r.description} />)}</A.RadioGroup>
|
|
90
|
+
</div>
|
|
91
|
+
<div><A.Button variant="primary" loading={sending} disabled={!emails.length} onClick={send}>{sending ? 'Sending invites' : emails.length > 1 ? `Send ${emails.length} invites` : 'Send invite'}</A.Button></div>
|
|
92
|
+
</A.Card>
|
|
93
|
+
<A.Table aria-label="Members and invitations">
|
|
94
|
+
<A.TableHeader><A.TableRow><A.TableHead>Person</A.TableHead><A.TableHead>Role</A.TableHead><A.TableHead align="end"><span className="mb-vh">Actions</span></A.TableHead></A.TableRow></A.TableHeader>
|
|
95
|
+
<A.TableBody>{people.map((p) => <MemberRow key={p.id} person={p} me={me} owners={owners} fail={fail}
|
|
96
|
+
onRole={(id, r) => setPeople((l) => l.map((x) => (x.id === id ? { ...x, role: r } : x)))}
|
|
97
|
+
onRemove={(x) => { setPeople((l) => l.filter((y) => y.id !== x.id)); setStatus(`${x.name} was removed.`); }}
|
|
98
|
+
onResend={(x) => setStatus(`Invite resent to ${x.name}.`)}
|
|
99
|
+
onRevoke={(x) => { setPeople((l) => l.filter((y) => y.id !== x.id)); setStatus(`Invitation to ${x.name} revoked.`); document.getElementById('mb-heading')?.focus(); }} />)}</A.TableBody>
|
|
100
|
+
</A.Table>
|
|
101
|
+
<A.WorkflowStatus>{status}</A.WorkflowStatus>
|
|
102
|
+
</main>
|
|
103
|
+
<details className="preview-fixtures"><summary>Example fixtures</summary>
|
|
104
|
+
<A.Switch label="Make the next role change fail" checked={failNext} onCheckedChange={setFailNext} />
|
|
105
|
+
</details>
|
|
106
|
+
</>
|
|
103
107
|
);
|
|
104
108
|
}
|
|
105
109
|
// preview:end
|
|
@@ -37,36 +37,40 @@ function App() {
|
|
|
37
37
|
const field = (key, label, hint) => <A.Field label={label} hint={hint} error={general.errors[key]}><A.Input id={'ws-' + key} value={general.draft[key]} onChange={(e) => general.setField(key, e.target.value)} /></A.Field>;
|
|
38
38
|
if (deleted) return <main className="st-page"><h2 ref={heading} tabIndex={-1} className="st-h">Workspace deleted</h2><p>Acme and everything in it were deleted.</p><A.WorkflowStatus>{remove.status}</A.WorkflowStatus></main>;
|
|
39
39
|
return (
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
<>
|
|
41
|
+
<main className="st-page">
|
|
42
|
+
<h2 ref={heading} tabIndex={-1} className="st-h">Workspace settings</h2>
|
|
43
|
+
<nav aria-label="Settings sections" className="st-nav"><a href="#st-general">General</a><a href="#st-notify">Notifications</a><a href="#st-billing">Billing</a><a href="#st-danger">Danger zone</a></nav>
|
|
44
|
+
<A.SettingsSection id="st-general" title="General" description="Saved together: change what you need, then save once.">
|
|
45
|
+
<form className="st-form" noValidate onSubmit={(e) => { e.preventDefault(); void general.submit(); }}>
|
|
46
|
+
<A.ErrorSummary errors={Object.entries(general.errors).map(([k, message]) => ({ id: 'ws-' + k, label: k === 'name' ? 'Workspace name' : 'Workspace URL', message }))} focusKey={general.submitCount} />
|
|
47
|
+
{field('name', 'Workspace name', 'Shown to everyone in the workspace.')}
|
|
48
|
+
{field('url', 'Workspace URL', 'altitude.app/' + general.draft.url)}
|
|
49
|
+
</form>
|
|
50
|
+
</A.SettingsSection>
|
|
51
|
+
<A.SettingsSection id="st-notify" title="Notifications" description="Each change applies as soon as you make it.">
|
|
52
|
+
<A.SettingsRow label="Weekly digest" description="A summary of activity every Monday." status={writes.digest}><A.Switch checked={prefs.digest} onCheckedChange={(v) => apply('digest', v)} /></A.SettingsRow>
|
|
53
|
+
<A.SettingsRow label="Mentions" description="Email me when someone mentions me." status={writes.mentions}><A.Switch checked={prefs.mentions} onCheckedChange={(v) => apply('mentions', v)} /></A.SettingsRow>
|
|
54
|
+
</A.SettingsSection>
|
|
55
|
+
<A.SettingsSection id="st-billing" title="Billing" readOnlyReason="Only workspace owners can change billing details. Ask Maya Chen.">
|
|
56
|
+
<A.SettingsRow label="Billing email" description="Invoices and receipts go here."><A.Input defaultValue="finance@acme.dev" /></A.SettingsRow>
|
|
57
|
+
</A.SettingsSection>
|
|
58
|
+
<A.SettingsSection id="st-danger" title="Danger zone" tone="critical">
|
|
59
|
+
<A.SettingsRow label="Delete workspace" description={remove.consequence}><A.Button variant="danger" onClick={remove.request}>Delete workspace</A.Button></A.SettingsRow>
|
|
60
|
+
</A.SettingsSection>
|
|
61
|
+
<A.WorkflowStatus>{general.status || remove.status}</A.WorkflowStatus>
|
|
62
|
+
<A.SaveBar record={general} />
|
|
63
|
+
<A.Dialog open={confirming} background="stationary" dismissible={remove.phase !== 'pending'} onOpenChange={(o) => { if (!o) { remove.cancel(); setTyped(''); } }} returnFocus={() => heading.current}
|
|
64
|
+
title="Delete Acme workspace?" description={remove.consequence}
|
|
65
|
+
footer={<><A.Button disabled={remove.phase === 'pending'} onClick={() => { remove.cancel(); setTyped(''); }}>Keep workspace</A.Button><A.Button variant="danger" disabled={typed !== 'Acme' || remove.phase === 'pending'} onClick={remove.phase === 'failed' ? remove.retry : remove.confirm}>{remove.phase === 'pending' ? 'Deleting workspace' : remove.phase === 'failed' ? 'Try deleting again' : 'Delete workspace'}</A.Button></>}>
|
|
66
|
+
<A.Field label="Type Acme to confirm"><A.Input value={typed} onChange={(e) => setTyped(e.target.value)} autoComplete="off" /></A.Field>
|
|
67
|
+
{remove.error && <p role="alert">{remove.error}</p>}
|
|
68
|
+
</A.Dialog>
|
|
69
|
+
</main>
|
|
70
|
+
<details className="preview-fixtures"><summary>Example fixtures</summary>
|
|
71
|
+
<A.Switch label="Make the next change fail" checked={failNext} onCheckedChange={setFailNext} />
|
|
72
|
+
</details>
|
|
73
|
+
</>
|
|
70
74
|
);
|
|
71
75
|
}
|
|
72
76
|
// preview:end
|
|
@@ -6,12 +6,12 @@ The application chooses that policy from its domain. A danger button does not im
|
|
|
6
6
|
|
|
7
7
|
## Try the same example in two views
|
|
8
8
|
|
|
9
|
-
- [Focused recovery preview](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
10
|
-
- [Complete Files example](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
11
|
-
- [InlineEdit comparison](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
9
|
+
- [Focused recovery preview](https://github.com/richlaconte/altitude/blob/v0.5.1/project/components/ActionsInPlace/preview.html) — archive, Undo, and restore later from Archived.
|
|
10
|
+
- [Complete Files example](https://github.com/richlaconte/altitude/blob/v0.5.1/project/components/ActionsInPlace/preview.html#files) — rename with the exported InlineEdit, archive, recover, and permanently delete from Archived.
|
|
11
|
+
- [InlineEdit comparison](https://github.com/richlaconte/altitude/blob/v0.5.1/project/components/InlineEdit/preview.html) and [Dialog presentation comparison](https://github.com/richlaconte/altitude/blob/v0.5.1/project/components/Dialog/preview.html).
|
|
12
12
|
- Generated Storybook stories: `Patterns/ActionsInPlace`, `Inputs/InlineEdit`, and `Overlays/Dialog`.
|
|
13
13
|
|
|
14
|
-
Both Files views use the same source and service in [`build/previews.txt`](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
14
|
+
Both Files views use the same source and service in [`build/previews.txt`](https://github.com/richlaconte/altitude/blob/v0.5.1/build/previews.txt). The default has no fixture toolbar in the product. Expand “Example fixtures and source” below the scene to select the deterministic service behavior, reset records/counters, simulate an external change, or inspect accepted requests. “Connection interrupted after save” commits at 100 ms and loses its response at 1,200 ms; the UI must reconcile that result before offering recovery or retry.
|
|
15
15
|
|
|
16
16
|
## Act and recover
|
|
17
17
|
|
|
@@ -438,12 +438,9 @@ export default function FilesApp() {
|
|
|
438
438
|
.aip-target span { color: var(--ink-muted); font: 400 12.5px/17px var(--font-sans); }
|
|
439
439
|
.aip-documentation { margin-top: var(--space-6); border-top: 1px solid var(--line); padding-top: var(--space-4); font: 400 12.5px/17px var(--font-sans); }
|
|
440
440
|
.aip a { color: var(--accent-ink); }
|
|
441
|
-
.
|
|
442
|
-
.
|
|
443
|
-
.
|
|
444
|
-
.aip-harness select { max-width: 100%; font: inherit; padding: var(--space-2); background: var(--surface-well); color: var(--ink); border: 1px solid var(--line-control); border-radius: var(--radius-sm); }
|
|
445
|
-
.aip-harness-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
|
|
446
|
-
.aip-harness pre { overflow: auto; max-height: 220px; font: 12px/1.5 var(--font-mono); }
|
|
441
|
+
.preview-fixtures label { display: grid; gap: var(--space-2); }
|
|
442
|
+
.preview-fixtures select { max-width: 100%; font: inherit; padding: var(--space-2); background: var(--surface-well); color: var(--ink); border: 1px solid var(--line-control); border-radius: var(--radius-sm); }
|
|
443
|
+
.preview-fixtures pre { overflow: auto; max-height: 220px; font: 12px/1.5 var(--font-mono); }
|
|
447
444
|
@media (max-width: 600px) { #root { padding: 16px; } .aip-list > li { align-items: stretch; flex-direction: column; gap: var(--space-2); } .aip-row-actions { align-self: flex-start; } .aip-toolbar > .alt-input { max-width: none; } .aip-header > .aip-meta { display: none; } .aip-recovery .alt-alert-inner, .aip-file .alt-alert-inner { flex-wrap: wrap; } .aip-recovery .alt-alert-body, .aip-file .alt-alert-body { flex-basis: calc(100% - 60px); } .aip-recovery .alt-alert-action, .aip-file .alt-alert-action { width: 100%; } }
|
|
448
445
|
```
|
|
449
446
|
<!-- recipe-css:end -->
|
|
@@ -458,6 +455,6 @@ Every state has text or an ARIA equivalent when motion and shadows are absent. N
|
|
|
458
455
|
|
|
459
456
|
## Verification and scope
|
|
460
457
|
|
|
461
|
-
[`build/checks/actions-in-place.mjs`](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
458
|
+
[`build/checks/actions-in-place.mjs`](https://github.com/richlaconte/altitude/blob/v0.5.1/build/checks/actions-in-place.mjs) exercises the canonical fixture model and browser interactions under React 18 and 19: duplicate requests, revision conflicts, uncertain outcomes, ordered feedback, dismissed/replaced recovery, targeted deletion, pending Close, old/new dialog sessions, focus recovery, reduced motion, increased contrast, forced colors, and narrow layouts. [The validation record](https://github.com/richlaconte/altitude/blob/v0.5.1/project/ActionsInPlaceValidation.md) distinguishes engineering evidence from remaining assistive-technology and participant gates.
|
|
462
459
|
|
|
463
460
|
[EditRegion](../components/EditRegion/README.md) now edits several fields of one record in place with this guide's session rules (issue #12 proposed ItemGroup, PropertyList, DataTable row expansion and Board card editing as its multi-field consumers). ConfirmAction and a shared action hook remain deferred. These demos do not establish two independent real application needs for those abstractions, and they do not establish a measured usability benefit. Structural activation counts and proposed design intent are not participant results.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Interfaces built by agents now have a look people recognise and distrust: purple gradients, Inter, a centred hero, three icon cards, a sidebar and a grid of equal cards on every screen. Altitude is made for apps that agents write, so it can fall into that look twice: through its own defaults, and through what agents compose from them. This chapter says how it stays out, and how we keep checking, because the look keeps moving.
|
|
4
4
|
|
|
5
|
-
The evidence is in **Research** ("Generated interfaces converge"). Every tell, with its sources and where Altitude stands, is in [`tells.json`](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
5
|
+
The evidence is in **Research** ("Generated interfaces converge"). Every tell, with its sources and where Altitude stands, is in [`tells.json`](https://github.com/richlaconte/altitude/blob/v0.5.1/project/tells.json). Looking generated is half the problem; the other half is breaking established rules (hierarchy, labelling, recovery, honesty), which [Fundamentals](Fundamentals.md) covers.
|
|
6
6
|
|
|
7
7
|
## Why it happens
|
|
8
8
|
|
|
@@ -622,7 +622,7 @@ A measurement, then a design review ([#97](https://github.com/richlaconte/altitu
|
|
|
622
622
|
- **A pointer over the list holds the close.** A delayed close could move the next row under a pointer reaching for it. The close waits while a mouse is over the list, capped at `dur-settle`; touch has no hover, so it doesn't wait.
|
|
623
623
|
- **`dur-linger` is 2000ms by judgement.** About four words read in roughly a second (Nielsen's 1s flow limit) plus a second to act; the top of the "second or two" asked for.
|
|
624
624
|
|
|
625
|
-
Not yet tested with people: whether the close is noticeable enough at `dur-travel-3`, and whether waiting for the pointer to leave the list reads as lag. Both are open in [the validation record](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
625
|
+
Not yet tested with people: whether the close is noticeable enough at `dur-travel-3`, and whether waiting for the pointer to leave the list reads as lag. Both are open in [the validation record](https://github.com/richlaconte/altitude/blob/v0.5.1/project/ActionsInPlaceValidation.md).
|
|
626
626
|
|
|
627
627
|
### E47 · Can a chart Altitude doesn't draw keep its rules?
|
|
628
628
|
|
|
@@ -165,7 +165,7 @@ That gets shadcn's components onto Altitude's colors and shadows. The elevation
|
|
|
165
165
|
|
|
166
166
|
### Charts
|
|
167
167
|
|
|
168
|
-
shadcn/ui's `Chart` is Recharts underneath (Tremor wraps Recharts too), so charts already built with it can take Altitude's colours and most of its chart rules without being rewritten. What they can't take is listed at the end. [`examples/shadcn-chart`](https://github.com/richlaconte/altitude/blob/v0.5.
|
|
168
|
+
shadcn/ui's `Chart` is Recharts underneath (Tremor wraps Recharts too), so charts already built with it can take Altitude's colours and most of its chart rules without being rewritten. What they can't take is listed at the end. [`examples/shadcn-chart`](https://github.com/richlaconte/altitude/blob/v0.5.1/examples/shadcn-chart) is this setup, checked in both schemes by `build/checks/shadcn-chart.mjs`.
|
|
169
169
|
|
|
170
170
|
**Map the palette.** Add the chart lines to the `@theme inline` block above, so Tailwind's `fill-chart-1` and the like are Altitude's slots:
|
|
171
171
|
|