@ryuxdsgn/design-intelligence 2.18.0 → 2.19.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/cli/index.js
CHANGED
|
@@ -463,6 +463,21 @@ const CONTEXT_FIELDS = [
|
|
|
463
463
|
{ value: "Premium", label: "Premium" },
|
|
464
464
|
] },
|
|
465
465
|
},
|
|
466
|
+
{
|
|
467
|
+
label: "Voice and tone", hint: "(voice words, how it addresses people, what it must never sound like; tone shifts by moment)",
|
|
468
|
+
ask: { flag: "voice", group: "Design", question: "How should it talk?", example: 'Hangat, lugas, pakai "kamu"', options: [
|
|
469
|
+
{ value: "Warm and casual", label: "Warm and casual" },
|
|
470
|
+
{ value: "Calm and professional", label: "Calm and professional" },
|
|
471
|
+
{ value: "Direct and brief", label: "Direct and brief" },
|
|
472
|
+
{ value: "Playful", label: "Playful", hint: "only where it costs no clarity" },
|
|
473
|
+
{ value: "Reassuring", label: "Reassuring", hint: "for money, health, or waiting" },
|
|
474
|
+
], then: { question: "What must it never sound like? Pick any.", example: "not preachy", multi: true, options: [
|
|
475
|
+
{ value: "not stiff or overly formal", label: "Stiff or overly formal" },
|
|
476
|
+
{ value: "not salesy or hyped", label: "Salesy or hyped" },
|
|
477
|
+
{ value: "not too familiar", label: "Too familiar" },
|
|
478
|
+
{ value: "no jokes when things go wrong", label: "Jokey when things go wrong" },
|
|
479
|
+
] } },
|
|
480
|
+
},
|
|
466
481
|
{
|
|
467
482
|
label: "Motion direction", hint: "(feel, what motion communicates, what to avoid)",
|
|
468
483
|
ask: { flag: "motion", group: "Design", question: "How much motion?", example: "Only to confirm a payment went through", options: [
|
|
@@ -768,7 +783,7 @@ Options:
|
|
|
768
783
|
--list-rules scan: list what each check looks for
|
|
769
784
|
--ignore <ids> scan: skip rules, e.g. RX-DS-03 (or a ryux-ignore RX-.. comment in the file)
|
|
770
785
|
--widths <list> scan <url>: viewport widths in CSS px (default 320,390,1280)
|
|
771
|
-
--product, --work, --audience, --market, --constraints, --intent, --ux, --ui, --motion <text>
|
|
786
|
+
--product, --work, --audience, --market, --constraints, --intent, --ux, --ui, --voice, --motion <text>
|
|
772
787
|
set project context fields without questions (setup)
|
|
773
788
|
|
|
774
789
|
Examples:
|
|
@@ -55,8 +55,10 @@ Cover what the captures show; skip what they do not, and say it was not visible.
|
|
|
55
55
|
| **Imagery and motion** | art direction (product UI, photography, illustration, 3D) and its style; each visual's job; composition (where the focal point sits, the space kept for copy); motion character and level (L1 to L5) when motion was captured |
|
|
56
56
|
| **Design language** | the visual language in 3 to 5 traits, each tied to evidence; component patterns; the spacing and typography systems; interaction patterns |
|
|
57
57
|
|
|
58
|
-
Also note content and tone (natural Indonesian or translated, how money and dates are written
|
|
59
|
-
local patterns (QRIS, virtual accounts, OTP, addresses, paylater, e-KYC).
|
|
58
|
+
Also note content and tone (natural Indonesian or translated, how money and dates are written,
|
|
59
|
+
"kamu" or "Anda") and local patterns (QRIS, virtual accounts, OTP, addresses, paylater, e-KYC). When
|
|
60
|
+
there is enough copy, place the voice on the four RX-CD-11 scales with the screens it comes from;
|
|
61
|
+
it is observed, not the brand's rule until the user confirms it.
|
|
60
62
|
|
|
61
63
|
### 4. Patterns and evidence
|
|
62
64
|
|
|
@@ -661,13 +661,13 @@ export const RULES = [
|
|
|
661
661
|
num: 11,
|
|
662
662
|
title: "Tone fits the moment, voice stays",
|
|
663
663
|
level: "preferred",
|
|
664
|
-
do: "Set a tone profile once, from the brand and the users, on four scales: formal to casual, serious to funny, respectful to irreverent, matter-of-fact to enthusiastic; add a few tone words and the anti-tone words to avoid (\"hangat, tidak sok akrab\").\n - Keep the voice the same everywhere and shift the tone with the user's state: matter-of-fact and serious for errors, money, and waiting; brief for success, where a check mark already says it worked (\"Alamat disimpan\", without \"berhasil\" unless the voice wants the warmth); warmer only in onboarding and empty moments.\n - Add personality only where it costs no clarity or length: clarity first, concision second, character third.",
|
|
664
|
+
do: "Set a tone profile once, from the brand and the users, on four scales: formal to casual, serious to funny, respectful to irreverent, matter-of-fact to enthusiastic; add a few tone words and the anti-tone words to avoid (\"hangat, tidak sok akrab\").\n - Take it from the Voice and tone field in DESIGN.md when it is set. When it is blank, infer it from the product's existing copy or brand docs, label it inferred in Assumptions, and keep it out of DESIGN.md until the user confirms it: copy that is live is observed, not a brand rule.\n - Keep the voice the same everywhere and shift the tone with the user's state: matter-of-fact and serious for errors, money, and waiting; brief for success, where a check mark already says it worked (\"Alamat disimpan\", without \"berhasil\" unless the voice wants the warmth); warmer only in onboarding and empty moments.\n - Add personality only where it costs no clarity or length: clarity first, concision second, character third.",
|
|
665
665
|
dont: "Joke in an error or a payment failure, cheer on a routine save, or switch between \"kamu\" and \"Anda\" across screens.",
|
|
666
666
|
why: "The same words feel caring in one moment and careless in another; tone measurably changes how users judge a product.",
|
|
667
667
|
basis: "NNGroup tone-of-voice dimensions (four dimensions; tested tone profiles); NNGroup 3 C's of informational microcopy",
|
|
668
668
|
notWhen: "the brand guide already defines the tone; follow it",
|
|
669
669
|
tradeoff: "a sober tone in serious moments gives up some brand flavour",
|
|
670
|
-
check: "review",
|
|
670
|
+
check: "review against the Voice and tone field in DESIGN.md; a profile taken from existing copy is labeled inferred",
|
|
671
671
|
},
|
|
672
672
|
{
|
|
673
673
|
num: 12,
|
|
@@ -73,17 +73,22 @@ The six stages of the core workflow (SKILL.md), as Design runs them.
|
|
|
73
73
|
counts toward the three) instead of choosing it yourself. **No DESIGN.md and no product docs is the
|
|
74
74
|
case where these questions matter most, never a reason to skip them:** ask, then wait for the
|
|
75
75
|
answer before designing. Complete context means no questions.
|
|
76
|
+
**Voice and tone** is not asked by default: when the field is blank, infer it from the product's
|
|
77
|
+
existing copy or brand docs, label it inferred, and continue (RX-CD-11). Ask only when there is
|
|
78
|
+
no source at all and the work is mostly copy (onboarding, marketing, error and success messages);
|
|
79
|
+
it counts toward the three.
|
|
76
80
|
**Ask as choices.** When you ask, or the user picks (stage 4, Reconsider), use the agent's
|
|
77
81
|
question or choice tool if it has one: two to four options per question, the recommended one
|
|
78
82
|
first and labeled, and room for the user's own answer. Without such a tool, write numbered
|
|
79
83
|
options with the recommendation first, so the user can answer with a number. Never ask what the prompt, DESIGN.md, or the
|
|
80
84
|
product docs already answer. For the rest, make the smallest reasonable assumption, write it
|
|
81
85
|
down, and continue (RX-PR-01, RX-PR-02).
|
|
82
|
-
**Record direction answers.** When the user answers a UI
|
|
83
|
-
|
|
86
|
+
**Record direction answers.** When the user answers a UI direction, motion direction, or voice
|
|
87
|
+
question, or confirms an inferred voice, write the answer into the UI direction, Motion direction,
|
|
88
|
+
or Voice and tone field of the RYUX project context in DESIGN.md:
|
|
84
89
|
between \`<!-- ryux-context:start -->\` and \`<!-- ryux-context:end -->\`, one line per field
|
|
85
90
|
(\`- **UI direction**: Calm, trustworthy\`). If DESIGN.md or the block does not exist, create it
|
|
86
|
-
with
|
|
91
|
+
with the fields answered. Change only those field lines; leave every other line as it is. Your own
|
|
87
92
|
assumptions do not go into DESIGN.md.
|
|
88
93
|
**What exists.** When there is a screen, product, or design system already, read its
|
|
89
94
|
analysis or run Analyze first (capabilities/analyze.md). Existing screens, components, and any
|
package/dist/scan.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// contents, returns findings, no LLM and no network. Each detector names the RX rule it checks; the
|
|
3
3
|
// rule text stays in intelligence/content.ts. "fail" is for a pattern that is wrong wherever it
|
|
4
4
|
// appears; "warn" is for a signal a person or agent should look at.
|
|
5
|
+
const INDONESIAN = /\blang=["']id\b|\bid-ID\b|\blocale\s*[:=]\s*["'`]id\b|\bRp\.?\s?\d|\b(?:yang|untuk|tidak|silakan|pesanan|belum)\b/;
|
|
6
|
+
const TEST_FILE = /(?:^|\/)(?:tests?|__tests__)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/;
|
|
5
7
|
/** What `ryux scan <url>` measures on the rendered page (cli/page-probe.ts), for --list-rules and the
|
|
6
8
|
* rule text. */
|
|
7
9
|
export const RENDER_CHECKS = [
|
|
@@ -92,9 +94,9 @@ export const DETECTORS = [
|
|
|
92
94
|
{
|
|
93
95
|
rule: "RX-CD-09",
|
|
94
96
|
level: "warn",
|
|
95
|
-
looksFor: "dates as 10/02/2026 and times as 2:30 PM in copy",
|
|
97
|
+
looksFor: "dates as 10/02/2026 and times as 2:30 PM in Indonesian copy (lang id, id-ID, Rupiah, or Indonesian words in the folder); test files are skipped",
|
|
96
98
|
exts: CODE,
|
|
97
|
-
find: ({ text }) => matches(text, [
|
|
99
|
+
find: ({ path, text }, ctx) => TEST_FILE.test(path) || !(ctx.indonesian ?? INDONESIAN.test(text)) ? [] : matches(text, [
|
|
98
100
|
[/(?<![\d/])\d{1,2}\/\d{1,2}\/\d{4}(?![\d/])/, (m) => `"${m[0]}": in Indonesian copy write 2 Okt 2026 (other markets follow their locale)`],
|
|
99
101
|
[/\b\d{1,2}[:.]\d{2}\s?(?:AM|PM|am|pm)\b/, (m) => `"${m[0]}": in Indonesian copy write 14.30 in 24-hour form (other markets follow their locale)`],
|
|
100
102
|
]),
|
|
@@ -318,7 +320,10 @@ function lineCol(raw, index) {
|
|
|
318
320
|
/** Run every detector over the sources. Findings are ordered by file, then line. */
|
|
319
321
|
export function scanSources(sources, opts) {
|
|
320
322
|
const ctx = opts.folder
|
|
321
|
-
? {
|
|
323
|
+
? {
|
|
324
|
+
reducedMotion: sources.some((s) => /prefers-reduced-motion|motion-(?:reduce|safe):|useReducedMotion|reducedMotion/.test(s.text)),
|
|
325
|
+
indonesian: sources.some((s) => !TEST_FILE.test(s.path) && INDONESIAN.test(s.text)),
|
|
326
|
+
}
|
|
322
327
|
: {};
|
|
323
328
|
const findings = [];
|
|
324
329
|
for (const src of sources) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryuxdsgn/design-intelligence",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.1",
|
|
4
4
|
"description": "RYUX: design intelligence for AI agents and designers. One skill, five entry points: Analyze, Design, Build, Critique, and QA, for Claude Code, Codex, Cursor, Gemini CLI, OpenCode, Cline, Copilot, and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|