@svadmin/create 0.14.1 → 0.16.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/README.md +11 -0
- package/dist/index.js +124 -74
- package/guidance/AGENTS.md +40 -0
- package/guidance/DESIGN.md +268 -0
- package/package.json +2 -1
- package/scaffold-manifest.json +2 -2
package/README.md
CHANGED
|
@@ -97,3 +97,14 @@ bun src/sync-template.ts
|
|
|
97
97
|
# Build CLI (for npm publishing)
|
|
98
98
|
bun run build
|
|
99
99
|
```
|
|
100
|
+
Generated projects include root-level `DESIGN.md` and `AGENTS.md` files. They
|
|
101
|
+
define the Stripe-first visual language, page information budget, feedback
|
|
102
|
+
ownership, and AI generation acceptance rules.
|
|
103
|
+
|
|
104
|
+
Existing projects can preview and install any missing guidance files without
|
|
105
|
+
overwriting local standards:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
bunx @svadmin/create guidance .
|
|
109
|
+
bunx @svadmin/create guidance . --write
|
|
110
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -20,12 +20,14 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
20
20
|
}
|
|
21
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
if (mod && typeof mod === "object" || typeof mod === "function") {
|
|
24
|
+
for (let key of __getOwnPropNames(mod))
|
|
25
|
+
if (!__hasOwnProp.call(to, key))
|
|
26
|
+
__defProp(to, key, {
|
|
27
|
+
get: __accessProp.bind(mod, key),
|
|
28
|
+
enumerable: true
|
|
29
|
+
});
|
|
30
|
+
}
|
|
29
31
|
if (canCache)
|
|
30
32
|
cache.set(mod, to);
|
|
31
33
|
return to;
|
|
@@ -34,7 +36,7 @@ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports,
|
|
|
34
36
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
35
37
|
|
|
36
38
|
// ../../node_modules/prompts/node_modules/kleur/index.js
|
|
37
|
-
var require_kleur = __commonJS((exports, module)
|
|
39
|
+
var require_kleur = __commonJS(function(exports, module) {
|
|
38
40
|
var { FORCE_COLOR, NODE_DISABLE_COLORS, TERM } = process.env;
|
|
39
41
|
var $ = {
|
|
40
42
|
enabled: !NODE_DISABLE_COLORS && TERM !== "dumb" && FORCE_COLOR !== "0",
|
|
@@ -125,7 +127,7 @@ var require_kleur = __commonJS((exports, module) => {
|
|
|
125
127
|
});
|
|
126
128
|
|
|
127
129
|
// ../../node_modules/prompts/dist/util/action.js
|
|
128
|
-
var require_action = __commonJS((exports, module)
|
|
130
|
+
var require_action = __commonJS(function(exports, module) {
|
|
129
131
|
module.exports = (key, isSelect) => {
|
|
130
132
|
if (key.meta && key.name !== "escape")
|
|
131
133
|
return;
|
|
@@ -182,7 +184,7 @@ var require_action = __commonJS((exports, module) => {
|
|
|
182
184
|
});
|
|
183
185
|
|
|
184
186
|
// ../../node_modules/prompts/dist/util/strip.js
|
|
185
|
-
var require_strip = __commonJS((exports, module)
|
|
187
|
+
var require_strip = __commonJS(function(exports, module) {
|
|
186
188
|
module.exports = (str) => {
|
|
187
189
|
const pattern = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"].join("|");
|
|
188
190
|
const RGX = new RegExp(pattern, "g");
|
|
@@ -191,7 +193,7 @@ var require_strip = __commonJS((exports, module) => {
|
|
|
191
193
|
});
|
|
192
194
|
|
|
193
195
|
// ../../node_modules/sisteransi/src/index.js
|
|
194
|
-
var require_src = __commonJS((exports, module)
|
|
196
|
+
var require_src = __commonJS(function(exports, module) {
|
|
195
197
|
var ESC = "\x1B";
|
|
196
198
|
var CSI = `${ESC}[`;
|
|
197
199
|
var beep = "\x07";
|
|
@@ -249,7 +251,7 @@ var require_src = __commonJS((exports, module) => {
|
|
|
249
251
|
});
|
|
250
252
|
|
|
251
253
|
// ../../node_modules/prompts/dist/util/clear.js
|
|
252
|
-
var require_clear = __commonJS((exports, module)
|
|
254
|
+
var require_clear = __commonJS(function(exports, module) {
|
|
253
255
|
function _createForOfIteratorHelper(o, allowArrayLike) {
|
|
254
256
|
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
255
257
|
if (!it) {
|
|
@@ -335,7 +337,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
335
337
|
});
|
|
336
338
|
|
|
337
339
|
// ../../node_modules/prompts/dist/util/figures.js
|
|
338
|
-
var require_figures = __commonJS((exports, module)
|
|
340
|
+
var require_figures = __commonJS(function(exports, module) {
|
|
339
341
|
var main = {
|
|
340
342
|
arrowUp: "↑",
|
|
341
343
|
arrowDown: "↓",
|
|
@@ -369,7 +371,7 @@ var require_figures = __commonJS((exports, module) => {
|
|
|
369
371
|
});
|
|
370
372
|
|
|
371
373
|
// ../../node_modules/prompts/dist/util/style.js
|
|
372
|
-
var require_style = __commonJS((exports, module)
|
|
374
|
+
var require_style = __commonJS(function(exports, module) {
|
|
373
375
|
var c = require_kleur();
|
|
374
376
|
var figures = require_figures();
|
|
375
377
|
var styles = Object.freeze({
|
|
@@ -411,7 +413,7 @@ var require_style = __commonJS((exports, module) => {
|
|
|
411
413
|
});
|
|
412
414
|
|
|
413
415
|
// ../../node_modules/prompts/dist/util/lines.js
|
|
414
|
-
var require_lines = __commonJS((exports, module)
|
|
416
|
+
var require_lines = __commonJS(function(exports, module) {
|
|
415
417
|
var strip = require_strip();
|
|
416
418
|
module.exports = function(msg, perLine) {
|
|
417
419
|
let lines = String(strip(msg) || "").split(/\r?\n/);
|
|
@@ -422,7 +424,7 @@ var require_lines = __commonJS((exports, module) => {
|
|
|
422
424
|
});
|
|
423
425
|
|
|
424
426
|
// ../../node_modules/prompts/dist/util/wrap.js
|
|
425
|
-
var require_wrap = __commonJS((exports, module)
|
|
427
|
+
var require_wrap = __commonJS(function(exports, module) {
|
|
426
428
|
module.exports = (msg, opts = {}) => {
|
|
427
429
|
const tab = Number.isSafeInteger(parseInt(opts.margin)) ? new Array(parseInt(opts.margin)).fill(" ").join("") : opts.margin || "";
|
|
428
430
|
const width = opts.width;
|
|
@@ -439,7 +441,7 @@ var require_wrap = __commonJS((exports, module) => {
|
|
|
439
441
|
});
|
|
440
442
|
|
|
441
443
|
// ../../node_modules/prompts/dist/util/entriesToDisplay.js
|
|
442
|
-
var require_entriesToDisplay = __commonJS((exports, module)
|
|
444
|
+
var require_entriesToDisplay = __commonJS(function(exports, module) {
|
|
443
445
|
module.exports = (cursor, total, maxVisible) => {
|
|
444
446
|
maxVisible = maxVisible || total;
|
|
445
447
|
let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));
|
|
@@ -454,7 +456,7 @@ var require_entriesToDisplay = __commonJS((exports, module) => {
|
|
|
454
456
|
});
|
|
455
457
|
|
|
456
458
|
// ../../node_modules/prompts/dist/util/index.js
|
|
457
|
-
var require_util = __commonJS((exports, module)
|
|
459
|
+
var require_util = __commonJS(function(exports, module) {
|
|
458
460
|
module.exports = {
|
|
459
461
|
action: require_action(),
|
|
460
462
|
clear: require_clear(),
|
|
@@ -468,7 +470,7 @@ var require_util = __commonJS((exports, module) => {
|
|
|
468
470
|
});
|
|
469
471
|
|
|
470
472
|
// ../../node_modules/prompts/dist/elements/prompt.js
|
|
471
|
-
var require_prompt = __commonJS((exports, module)
|
|
473
|
+
var require_prompt = __commonJS(function(exports, module) {
|
|
472
474
|
var readline = __require("readline");
|
|
473
475
|
var _require = require_util();
|
|
474
476
|
var action = _require.action;
|
|
@@ -536,7 +538,7 @@ var require_prompt = __commonJS((exports, module) => {
|
|
|
536
538
|
});
|
|
537
539
|
|
|
538
540
|
// ../../node_modules/prompts/dist/elements/text.js
|
|
539
|
-
var require_text = __commonJS((exports, module)
|
|
541
|
+
var require_text = __commonJS(function(exports, module) {
|
|
540
542
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
541
543
|
try {
|
|
542
544
|
var info = gen[key](arg);
|
|
@@ -760,7 +762,7 @@ ${i ? " " : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|
|
760
762
|
});
|
|
761
763
|
|
|
762
764
|
// ../../node_modules/prompts/dist/elements/select.js
|
|
763
|
-
var require_select = __commonJS((exports, module)
|
|
765
|
+
var require_select = __commonJS(function(exports, module) {
|
|
764
766
|
var color = require_kleur();
|
|
765
767
|
var Prompt = require_prompt();
|
|
766
768
|
var _require = require_util();
|
|
@@ -916,7 +918,7 @@ var require_select = __commonJS((exports, module) => {
|
|
|
916
918
|
});
|
|
917
919
|
|
|
918
920
|
// ../../node_modules/prompts/dist/elements/toggle.js
|
|
919
|
-
var require_toggle = __commonJS((exports, module)
|
|
921
|
+
var require_toggle = __commonJS(function(exports, module) {
|
|
920
922
|
var color = require_kleur();
|
|
921
923
|
var Prompt = require_prompt();
|
|
922
924
|
var _require = require_util();
|
|
@@ -1020,7 +1022,7 @@ var require_toggle = __commonJS((exports, module) => {
|
|
|
1020
1022
|
});
|
|
1021
1023
|
|
|
1022
1024
|
// ../../node_modules/prompts/dist/dateparts/datepart.js
|
|
1023
|
-
var require_datepart = __commonJS((exports, module)
|
|
1025
|
+
var require_datepart = __commonJS(function(exports, module) {
|
|
1024
1026
|
class DatePart {
|
|
1025
1027
|
constructor({
|
|
1026
1028
|
token,
|
|
@@ -1053,7 +1055,7 @@ var require_datepart = __commonJS((exports, module) => {
|
|
|
1053
1055
|
});
|
|
1054
1056
|
|
|
1055
1057
|
// ../../node_modules/prompts/dist/dateparts/meridiem.js
|
|
1056
|
-
var require_meridiem = __commonJS((exports, module)
|
|
1058
|
+
var require_meridiem = __commonJS(function(exports, module) {
|
|
1057
1059
|
var DatePart = require_datepart();
|
|
1058
1060
|
|
|
1059
1061
|
class Meridiem extends DatePart {
|
|
@@ -1075,7 +1077,7 @@ var require_meridiem = __commonJS((exports, module) => {
|
|
|
1075
1077
|
});
|
|
1076
1078
|
|
|
1077
1079
|
// ../../node_modules/prompts/dist/dateparts/day.js
|
|
1078
|
-
var require_day = __commonJS((exports, module)
|
|
1080
|
+
var require_day = __commonJS(function(exports, module) {
|
|
1079
1081
|
var DatePart = require_datepart();
|
|
1080
1082
|
var pos = (n) => {
|
|
1081
1083
|
n = n % 10;
|
|
@@ -1105,7 +1107,7 @@ var require_day = __commonJS((exports, module) => {
|
|
|
1105
1107
|
});
|
|
1106
1108
|
|
|
1107
1109
|
// ../../node_modules/prompts/dist/dateparts/hours.js
|
|
1108
|
-
var require_hours = __commonJS((exports, module)
|
|
1110
|
+
var require_hours = __commonJS(function(exports, module) {
|
|
1109
1111
|
var DatePart = require_datepart();
|
|
1110
1112
|
|
|
1111
1113
|
class Hours extends DatePart {
|
|
@@ -1132,7 +1134,7 @@ var require_hours = __commonJS((exports, module) => {
|
|
|
1132
1134
|
});
|
|
1133
1135
|
|
|
1134
1136
|
// ../../node_modules/prompts/dist/dateparts/milliseconds.js
|
|
1135
|
-
var require_milliseconds = __commonJS((exports, module)
|
|
1137
|
+
var require_milliseconds = __commonJS(function(exports, module) {
|
|
1136
1138
|
var DatePart = require_datepart();
|
|
1137
1139
|
|
|
1138
1140
|
class Milliseconds extends DatePart {
|
|
@@ -1156,7 +1158,7 @@ var require_milliseconds = __commonJS((exports, module) => {
|
|
|
1156
1158
|
});
|
|
1157
1159
|
|
|
1158
1160
|
// ../../node_modules/prompts/dist/dateparts/minutes.js
|
|
1159
|
-
var require_minutes = __commonJS((exports, module)
|
|
1161
|
+
var require_minutes = __commonJS(function(exports, module) {
|
|
1160
1162
|
var DatePart = require_datepart();
|
|
1161
1163
|
|
|
1162
1164
|
class Minutes extends DatePart {
|
|
@@ -1181,7 +1183,7 @@ var require_minutes = __commonJS((exports, module) => {
|
|
|
1181
1183
|
});
|
|
1182
1184
|
|
|
1183
1185
|
// ../../node_modules/prompts/dist/dateparts/month.js
|
|
1184
|
-
var require_month = __commonJS((exports, module)
|
|
1186
|
+
var require_month = __commonJS(function(exports, module) {
|
|
1185
1187
|
var DatePart = require_datepart();
|
|
1186
1188
|
|
|
1187
1189
|
class Month extends DatePart {
|
|
@@ -1208,7 +1210,7 @@ var require_month = __commonJS((exports, module) => {
|
|
|
1208
1210
|
});
|
|
1209
1211
|
|
|
1210
1212
|
// ../../node_modules/prompts/dist/dateparts/seconds.js
|
|
1211
|
-
var require_seconds = __commonJS((exports, module)
|
|
1213
|
+
var require_seconds = __commonJS(function(exports, module) {
|
|
1212
1214
|
var DatePart = require_datepart();
|
|
1213
1215
|
|
|
1214
1216
|
class Seconds extends DatePart {
|
|
@@ -1233,7 +1235,7 @@ var require_seconds = __commonJS((exports, module) => {
|
|
|
1233
1235
|
});
|
|
1234
1236
|
|
|
1235
1237
|
// ../../node_modules/prompts/dist/dateparts/year.js
|
|
1236
|
-
var require_year = __commonJS((exports, module)
|
|
1238
|
+
var require_year = __commonJS(function(exports, module) {
|
|
1237
1239
|
var DatePart = require_datepart();
|
|
1238
1240
|
|
|
1239
1241
|
class Year extends DatePart {
|
|
@@ -1258,7 +1260,7 @@ var require_year = __commonJS((exports, module) => {
|
|
|
1258
1260
|
});
|
|
1259
1261
|
|
|
1260
1262
|
// ../../node_modules/prompts/dist/dateparts/index.js
|
|
1261
|
-
var require_dateparts = __commonJS((exports, module)
|
|
1263
|
+
var require_dateparts = __commonJS(function(exports, module) {
|
|
1262
1264
|
module.exports = {
|
|
1263
1265
|
DatePart: require_datepart(),
|
|
1264
1266
|
Meridiem: require_meridiem(),
|
|
@@ -1273,7 +1275,7 @@ var require_dateparts = __commonJS((exports, module) => {
|
|
|
1273
1275
|
});
|
|
1274
1276
|
|
|
1275
1277
|
// ../../node_modules/prompts/dist/elements/date.js
|
|
1276
|
-
var require_date = __commonJS((exports, module)
|
|
1278
|
+
var require_date = __commonJS(function(exports, module) {
|
|
1277
1279
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
1278
1280
|
try {
|
|
1279
1281
|
var info = gen[key](arg);
|
|
@@ -1500,7 +1502,7 @@ ${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|
|
1500
1502
|
});
|
|
1501
1503
|
|
|
1502
1504
|
// ../../node_modules/prompts/dist/elements/number.js
|
|
1503
|
-
var require_number = __commonJS((exports, module)
|
|
1505
|
+
var require_number = __commonJS(function(exports, module) {
|
|
1504
1506
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
1505
1507
|
try {
|
|
1506
1508
|
var info = gen[key](arg);
|
|
@@ -1723,7 +1725,7 @@ ${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|
|
1723
1725
|
});
|
|
1724
1726
|
|
|
1725
1727
|
// ../../node_modules/prompts/dist/elements/multiselect.js
|
|
1726
|
-
var require_multiselect = __commonJS((exports, module)
|
|
1728
|
+
var require_multiselect = __commonJS(function(exports, module) {
|
|
1727
1729
|
var color = require_kleur();
|
|
1728
1730
|
var _require = require_src();
|
|
1729
1731
|
var cursor = _require.cursor;
|
|
@@ -1959,7 +1961,7 @@ Instructions:
|
|
|
1959
1961
|
});
|
|
1960
1962
|
|
|
1961
1963
|
// ../../node_modules/prompts/dist/elements/autocomplete.js
|
|
1962
|
-
var require_autocomplete = __commonJS((exports, module)
|
|
1964
|
+
var require_autocomplete = __commonJS(function(exports, module) {
|
|
1963
1965
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
1964
1966
|
try {
|
|
1965
1967
|
var info = gen[key](arg);
|
|
@@ -2230,7 +2232,7 @@ var require_autocomplete = __commonJS((exports, module) => {
|
|
|
2230
2232
|
});
|
|
2231
2233
|
|
|
2232
2234
|
// ../../node_modules/prompts/dist/elements/autocompleteMultiselect.js
|
|
2233
|
-
var require_autocompleteMultiselect = __commonJS((exports, module)
|
|
2235
|
+
var require_autocompleteMultiselect = __commonJS(function(exports, module) {
|
|
2234
2236
|
var color = require_kleur();
|
|
2235
2237
|
var _require = require_src();
|
|
2236
2238
|
var cursor = _require.cursor;
|
|
@@ -2392,7 +2394,7 @@ Filtered results for: ${this.inputValue ? this.inputValue : color.gray("Enter so
|
|
|
2392
2394
|
});
|
|
2393
2395
|
|
|
2394
2396
|
// ../../node_modules/prompts/dist/elements/confirm.js
|
|
2395
|
-
var require_confirm = __commonJS((exports, module)
|
|
2397
|
+
var require_confirm = __commonJS(function(exports, module) {
|
|
2396
2398
|
var color = require_kleur();
|
|
2397
2399
|
var Prompt = require_prompt();
|
|
2398
2400
|
var _require = require_util();
|
|
@@ -2467,7 +2469,7 @@ var require_confirm = __commonJS((exports, module) => {
|
|
|
2467
2469
|
});
|
|
2468
2470
|
|
|
2469
2471
|
// ../../node_modules/prompts/dist/elements/index.js
|
|
2470
|
-
var require_elements = __commonJS((exports, module)
|
|
2472
|
+
var require_elements = __commonJS(function(exports, module) {
|
|
2471
2473
|
module.exports = {
|
|
2472
2474
|
TextPrompt: require_text(),
|
|
2473
2475
|
SelectPrompt: require_select(),
|
|
@@ -2482,7 +2484,7 @@ var require_elements = __commonJS((exports, module) => {
|
|
|
2482
2484
|
});
|
|
2483
2485
|
|
|
2484
2486
|
// ../../node_modules/prompts/dist/prompts.js
|
|
2485
|
-
var require_prompts = __commonJS((exports)
|
|
2487
|
+
var require_prompts = __commonJS(function(exports) {
|
|
2486
2488
|
var $ = exports;
|
|
2487
2489
|
var el = require_elements();
|
|
2488
2490
|
var noop = (v) => v;
|
|
@@ -2543,7 +2545,7 @@ var require_prompts = __commonJS((exports) => {
|
|
|
2543
2545
|
});
|
|
2544
2546
|
|
|
2545
2547
|
// ../../node_modules/prompts/dist/index.js
|
|
2546
|
-
var require_dist = __commonJS((exports, module)
|
|
2548
|
+
var require_dist = __commonJS(function(exports, module) {
|
|
2547
2549
|
function ownKeys(object, enumerableOnly) {
|
|
2548
2550
|
var keys = Object.keys(object);
|
|
2549
2551
|
if (Object.getOwnPropertySymbols) {
|
|
@@ -2773,7 +2775,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
2773
2775
|
});
|
|
2774
2776
|
|
|
2775
2777
|
// ../../node_modules/prompts/lib/util/action.js
|
|
2776
|
-
var require_action2 = __commonJS((exports, module)
|
|
2778
|
+
var require_action2 = __commonJS(function(exports, module) {
|
|
2777
2779
|
module.exports = (key, isSelect) => {
|
|
2778
2780
|
if (key.meta && key.name !== "escape")
|
|
2779
2781
|
return;
|
|
@@ -2830,7 +2832,7 @@ var require_action2 = __commonJS((exports, module) => {
|
|
|
2830
2832
|
});
|
|
2831
2833
|
|
|
2832
2834
|
// ../../node_modules/prompts/lib/util/strip.js
|
|
2833
|
-
var require_strip2 = __commonJS((exports, module)
|
|
2835
|
+
var require_strip2 = __commonJS(function(exports, module) {
|
|
2834
2836
|
module.exports = (str) => {
|
|
2835
2837
|
const pattern = [
|
|
2836
2838
|
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
|
@@ -2842,7 +2844,7 @@ var require_strip2 = __commonJS((exports, module) => {
|
|
|
2842
2844
|
});
|
|
2843
2845
|
|
|
2844
2846
|
// ../../node_modules/prompts/lib/util/clear.js
|
|
2845
|
-
var require_clear2 = __commonJS((exports, module)
|
|
2847
|
+
var require_clear2 = __commonJS(function(exports, module) {
|
|
2846
2848
|
var strip = require_strip2();
|
|
2847
2849
|
var { erase, cursor } = require_src();
|
|
2848
2850
|
var width = (str) => [...strip(str)].length;
|
|
@@ -2859,7 +2861,7 @@ var require_clear2 = __commonJS((exports, module) => {
|
|
|
2859
2861
|
});
|
|
2860
2862
|
|
|
2861
2863
|
// ../../node_modules/prompts/lib/util/figures.js
|
|
2862
|
-
var require_figures2 = __commonJS((exports, module)
|
|
2864
|
+
var require_figures2 = __commonJS(function(exports, module) {
|
|
2863
2865
|
var main = {
|
|
2864
2866
|
arrowUp: "↑",
|
|
2865
2867
|
arrowDown: "↓",
|
|
@@ -2893,7 +2895,7 @@ var require_figures2 = __commonJS((exports, module) => {
|
|
|
2893
2895
|
});
|
|
2894
2896
|
|
|
2895
2897
|
// ../../node_modules/prompts/lib/util/style.js
|
|
2896
|
-
var require_style2 = __commonJS((exports, module)
|
|
2898
|
+
var require_style2 = __commonJS(function(exports, module) {
|
|
2897
2899
|
var c = require_kleur();
|
|
2898
2900
|
var figures = require_figures2();
|
|
2899
2901
|
var styles = Object.freeze({
|
|
@@ -2923,7 +2925,7 @@ var require_style2 = __commonJS((exports, module) => {
|
|
|
2923
2925
|
});
|
|
2924
2926
|
|
|
2925
2927
|
// ../../node_modules/prompts/lib/util/lines.js
|
|
2926
|
-
var require_lines2 = __commonJS((exports, module)
|
|
2928
|
+
var require_lines2 = __commonJS(function(exports, module) {
|
|
2927
2929
|
var strip = require_strip2();
|
|
2928
2930
|
module.exports = function(msg, perLine) {
|
|
2929
2931
|
let lines = String(strip(msg) || "").split(/\r?\n/);
|
|
@@ -2934,7 +2936,7 @@ var require_lines2 = __commonJS((exports, module) => {
|
|
|
2934
2936
|
});
|
|
2935
2937
|
|
|
2936
2938
|
// ../../node_modules/prompts/lib/util/wrap.js
|
|
2937
|
-
var require_wrap2 = __commonJS((exports, module)
|
|
2939
|
+
var require_wrap2 = __commonJS(function(exports, module) {
|
|
2938
2940
|
module.exports = (msg, opts = {}) => {
|
|
2939
2941
|
const tab = Number.isSafeInteger(parseInt(opts.margin)) ? new Array(parseInt(opts.margin)).fill(" ").join("") : opts.margin || "";
|
|
2940
2942
|
const width = opts.width;
|
|
@@ -2951,7 +2953,7 @@ var require_wrap2 = __commonJS((exports, module) => {
|
|
|
2951
2953
|
});
|
|
2952
2954
|
|
|
2953
2955
|
// ../../node_modules/prompts/lib/util/entriesToDisplay.js
|
|
2954
|
-
var require_entriesToDisplay2 = __commonJS((exports, module)
|
|
2956
|
+
var require_entriesToDisplay2 = __commonJS(function(exports, module) {
|
|
2955
2957
|
module.exports = (cursor, total, maxVisible) => {
|
|
2956
2958
|
maxVisible = maxVisible || total;
|
|
2957
2959
|
let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));
|
|
@@ -2963,7 +2965,7 @@ var require_entriesToDisplay2 = __commonJS((exports, module) => {
|
|
|
2963
2965
|
});
|
|
2964
2966
|
|
|
2965
2967
|
// ../../node_modules/prompts/lib/util/index.js
|
|
2966
|
-
var require_util2 = __commonJS((exports, module)
|
|
2968
|
+
var require_util2 = __commonJS(function(exports, module) {
|
|
2967
2969
|
module.exports = {
|
|
2968
2970
|
action: require_action2(),
|
|
2969
2971
|
clear: require_clear2(),
|
|
@@ -2977,7 +2979,7 @@ var require_util2 = __commonJS((exports, module) => {
|
|
|
2977
2979
|
});
|
|
2978
2980
|
|
|
2979
2981
|
// ../../node_modules/prompts/lib/elements/prompt.js
|
|
2980
|
-
var require_prompt2 = __commonJS((exports, module)
|
|
2982
|
+
var require_prompt2 = __commonJS(function(exports, module) {
|
|
2981
2983
|
var readline = __require("readline");
|
|
2982
2984
|
var { action } = require_util2();
|
|
2983
2985
|
var EventEmitter = __require("events");
|
|
@@ -3039,7 +3041,7 @@ var require_prompt2 = __commonJS((exports, module) => {
|
|
|
3039
3041
|
});
|
|
3040
3042
|
|
|
3041
3043
|
// ../../node_modules/prompts/lib/elements/text.js
|
|
3042
|
-
var require_text2 = __commonJS((exports, module)
|
|
3044
|
+
var require_text2 = __commonJS(function(exports, module) {
|
|
3043
3045
|
var color = require_kleur();
|
|
3044
3046
|
var Prompt = require_prompt2();
|
|
3045
3047
|
var { erase, cursor } = require_src();
|
|
@@ -3227,7 +3229,7 @@ ${i ? " " : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|
|
3227
3229
|
});
|
|
3228
3230
|
|
|
3229
3231
|
// ../../node_modules/prompts/lib/elements/select.js
|
|
3230
|
-
var require_select2 = __commonJS((exports, module)
|
|
3232
|
+
var require_select2 = __commonJS(function(exports, module) {
|
|
3231
3233
|
var color = require_kleur();
|
|
3232
3234
|
var Prompt = require_prompt2();
|
|
3233
3235
|
var { style, clear, figures, wrap, entriesToDisplay } = require_util2();
|
|
@@ -3376,7 +3378,7 @@ var require_select2 = __commonJS((exports, module) => {
|
|
|
3376
3378
|
});
|
|
3377
3379
|
|
|
3378
3380
|
// ../../node_modules/prompts/lib/elements/toggle.js
|
|
3379
|
-
var require_toggle2 = __commonJS((exports, module)
|
|
3381
|
+
var require_toggle2 = __commonJS(function(exports, module) {
|
|
3380
3382
|
var color = require_kleur();
|
|
3381
3383
|
var Prompt = require_prompt2();
|
|
3382
3384
|
var { style, clear } = require_util2();
|
|
@@ -3483,7 +3485,7 @@ var require_toggle2 = __commonJS((exports, module) => {
|
|
|
3483
3485
|
});
|
|
3484
3486
|
|
|
3485
3487
|
// ../../node_modules/prompts/lib/dateparts/datepart.js
|
|
3486
|
-
var require_datepart2 = __commonJS((exports, module)
|
|
3488
|
+
var require_datepart2 = __commonJS(function(exports, module) {
|
|
3487
3489
|
class DatePart {
|
|
3488
3490
|
constructor({ token, date, parts, locales }) {
|
|
3489
3491
|
this.token = token;
|
|
@@ -3511,7 +3513,7 @@ var require_datepart2 = __commonJS((exports, module) => {
|
|
|
3511
3513
|
});
|
|
3512
3514
|
|
|
3513
3515
|
// ../../node_modules/prompts/lib/dateparts/meridiem.js
|
|
3514
|
-
var require_meridiem2 = __commonJS((exports, module)
|
|
3516
|
+
var require_meridiem2 = __commonJS(function(exports, module) {
|
|
3515
3517
|
var DatePart = require_datepart2();
|
|
3516
3518
|
|
|
3517
3519
|
class Meridiem extends DatePart {
|
|
@@ -3533,7 +3535,7 @@ var require_meridiem2 = __commonJS((exports, module) => {
|
|
|
3533
3535
|
});
|
|
3534
3536
|
|
|
3535
3537
|
// ../../node_modules/prompts/lib/dateparts/day.js
|
|
3536
|
-
var require_day2 = __commonJS((exports, module)
|
|
3538
|
+
var require_day2 = __commonJS(function(exports, module) {
|
|
3537
3539
|
var DatePart = require_datepart2();
|
|
3538
3540
|
var pos = (n) => {
|
|
3539
3541
|
n = n % 10;
|
|
@@ -3563,7 +3565,7 @@ var require_day2 = __commonJS((exports, module) => {
|
|
|
3563
3565
|
});
|
|
3564
3566
|
|
|
3565
3567
|
// ../../node_modules/prompts/lib/dateparts/hours.js
|
|
3566
|
-
var require_hours2 = __commonJS((exports, module)
|
|
3568
|
+
var require_hours2 = __commonJS(function(exports, module) {
|
|
3567
3569
|
var DatePart = require_datepart2();
|
|
3568
3570
|
|
|
3569
3571
|
class Hours extends DatePart {
|
|
@@ -3590,7 +3592,7 @@ var require_hours2 = __commonJS((exports, module) => {
|
|
|
3590
3592
|
});
|
|
3591
3593
|
|
|
3592
3594
|
// ../../node_modules/prompts/lib/dateparts/milliseconds.js
|
|
3593
|
-
var require_milliseconds2 = __commonJS((exports, module)
|
|
3595
|
+
var require_milliseconds2 = __commonJS(function(exports, module) {
|
|
3594
3596
|
var DatePart = require_datepart2();
|
|
3595
3597
|
|
|
3596
3598
|
class Milliseconds extends DatePart {
|
|
@@ -3614,7 +3616,7 @@ var require_milliseconds2 = __commonJS((exports, module) => {
|
|
|
3614
3616
|
});
|
|
3615
3617
|
|
|
3616
3618
|
// ../../node_modules/prompts/lib/dateparts/minutes.js
|
|
3617
|
-
var require_minutes2 = __commonJS((exports, module)
|
|
3619
|
+
var require_minutes2 = __commonJS(function(exports, module) {
|
|
3618
3620
|
var DatePart = require_datepart2();
|
|
3619
3621
|
|
|
3620
3622
|
class Minutes extends DatePart {
|
|
@@ -3639,7 +3641,7 @@ var require_minutes2 = __commonJS((exports, module) => {
|
|
|
3639
3641
|
});
|
|
3640
3642
|
|
|
3641
3643
|
// ../../node_modules/prompts/lib/dateparts/month.js
|
|
3642
|
-
var require_month2 = __commonJS((exports, module)
|
|
3644
|
+
var require_month2 = __commonJS(function(exports, module) {
|
|
3643
3645
|
var DatePart = require_datepart2();
|
|
3644
3646
|
|
|
3645
3647
|
class Month extends DatePart {
|
|
@@ -3666,7 +3668,7 @@ var require_month2 = __commonJS((exports, module) => {
|
|
|
3666
3668
|
});
|
|
3667
3669
|
|
|
3668
3670
|
// ../../node_modules/prompts/lib/dateparts/seconds.js
|
|
3669
|
-
var require_seconds2 = __commonJS((exports, module)
|
|
3671
|
+
var require_seconds2 = __commonJS(function(exports, module) {
|
|
3670
3672
|
var DatePart = require_datepart2();
|
|
3671
3673
|
|
|
3672
3674
|
class Seconds extends DatePart {
|
|
@@ -3691,7 +3693,7 @@ var require_seconds2 = __commonJS((exports, module) => {
|
|
|
3691
3693
|
});
|
|
3692
3694
|
|
|
3693
3695
|
// ../../node_modules/prompts/lib/dateparts/year.js
|
|
3694
|
-
var require_year2 = __commonJS((exports, module)
|
|
3696
|
+
var require_year2 = __commonJS(function(exports, module) {
|
|
3695
3697
|
var DatePart = require_datepart2();
|
|
3696
3698
|
|
|
3697
3699
|
class Year extends DatePart {
|
|
@@ -3716,7 +3718,7 @@ var require_year2 = __commonJS((exports, module) => {
|
|
|
3716
3718
|
});
|
|
3717
3719
|
|
|
3718
3720
|
// ../../node_modules/prompts/lib/dateparts/index.js
|
|
3719
|
-
var require_dateparts2 = __commonJS((exports, module)
|
|
3721
|
+
var require_dateparts2 = __commonJS(function(exports, module) {
|
|
3720
3722
|
module.exports = {
|
|
3721
3723
|
DatePart: require_datepart2(),
|
|
3722
3724
|
Meridiem: require_meridiem2(),
|
|
@@ -3731,7 +3733,7 @@ var require_dateparts2 = __commonJS((exports, module) => {
|
|
|
3731
3733
|
});
|
|
3732
3734
|
|
|
3733
3735
|
// ../../node_modules/prompts/lib/elements/date.js
|
|
3734
|
-
var require_date2 = __commonJS((exports, module)
|
|
3736
|
+
var require_date2 = __commonJS(function(exports, module) {
|
|
3735
3737
|
var color = require_kleur();
|
|
3736
3738
|
var Prompt = require_prompt2();
|
|
3737
3739
|
var { style, clear, figures } = require_util2();
|
|
@@ -3907,7 +3909,7 @@ ${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|
|
3907
3909
|
});
|
|
3908
3910
|
|
|
3909
3911
|
// ../../node_modules/prompts/lib/elements/number.js
|
|
3910
|
-
var require_number2 = __commonJS((exports, module)
|
|
3912
|
+
var require_number2 = __commonJS(function(exports, module) {
|
|
3911
3913
|
var color = require_kleur();
|
|
3912
3914
|
var Prompt = require_prompt2();
|
|
3913
3915
|
var { cursor, erase } = require_src();
|
|
@@ -4094,7 +4096,7 @@ ${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|
|
4094
4096
|
});
|
|
4095
4097
|
|
|
4096
4098
|
// ../../node_modules/prompts/lib/elements/multiselect.js
|
|
4097
|
-
var require_multiselect2 = __commonJS((exports, module)
|
|
4099
|
+
var require_multiselect2 = __commonJS(function(exports, module) {
|
|
4098
4100
|
var color = require_kleur();
|
|
4099
4101
|
var { cursor } = require_src();
|
|
4100
4102
|
var Prompt = require_prompt2();
|
|
@@ -4323,7 +4325,7 @@ Instructions:
|
|
|
4323
4325
|
});
|
|
4324
4326
|
|
|
4325
4327
|
// ../../node_modules/prompts/lib/elements/autocomplete.js
|
|
4326
|
-
var require_autocomplete2 = __commonJS((exports, module)
|
|
4328
|
+
var require_autocomplete2 = __commonJS(function(exports, module) {
|
|
4327
4329
|
var color = require_kleur();
|
|
4328
4330
|
var Prompt = require_prompt2();
|
|
4329
4331
|
var { erase, cursor } = require_src();
|
|
@@ -4547,7 +4549,7 @@ var require_autocomplete2 = __commonJS((exports, module) => {
|
|
|
4547
4549
|
});
|
|
4548
4550
|
|
|
4549
4551
|
// ../../node_modules/prompts/lib/elements/autocompleteMultiselect.js
|
|
4550
|
-
var require_autocompleteMultiselect2 = __commonJS((exports, module)
|
|
4552
|
+
var require_autocompleteMultiselect2 = __commonJS(function(exports, module) {
|
|
4551
4553
|
var color = require_kleur();
|
|
4552
4554
|
var { cursor } = require_src();
|
|
4553
4555
|
var MultiselectPrompt = require_multiselect2();
|
|
@@ -4710,7 +4712,7 @@ Filtered results for: ${this.inputValue ? this.inputValue : color.gray("Enter so
|
|
|
4710
4712
|
});
|
|
4711
4713
|
|
|
4712
4714
|
// ../../node_modules/prompts/lib/elements/confirm.js
|
|
4713
|
-
var require_confirm2 = __commonJS((exports, module)
|
|
4715
|
+
var require_confirm2 = __commonJS(function(exports, module) {
|
|
4714
4716
|
var color = require_kleur();
|
|
4715
4717
|
var Prompt = require_prompt2();
|
|
4716
4718
|
var { style, clear } = require_util2();
|
|
@@ -4786,7 +4788,7 @@ var require_confirm2 = __commonJS((exports, module) => {
|
|
|
4786
4788
|
});
|
|
4787
4789
|
|
|
4788
4790
|
// ../../node_modules/prompts/lib/elements/index.js
|
|
4789
|
-
var require_elements2 = __commonJS((exports, module)
|
|
4791
|
+
var require_elements2 = __commonJS(function(exports, module) {
|
|
4790
4792
|
module.exports = {
|
|
4791
4793
|
TextPrompt: require_text2(),
|
|
4792
4794
|
SelectPrompt: require_select2(),
|
|
@@ -4801,7 +4803,7 @@ var require_elements2 = __commonJS((exports, module) => {
|
|
|
4801
4803
|
});
|
|
4802
4804
|
|
|
4803
4805
|
// ../../node_modules/prompts/lib/prompts.js
|
|
4804
|
-
var require_prompts2 = __commonJS((exports)
|
|
4806
|
+
var require_prompts2 = __commonJS(function(exports) {
|
|
4805
4807
|
var $ = exports;
|
|
4806
4808
|
var el = require_elements2();
|
|
4807
4809
|
var noop = (v) => v;
|
|
@@ -4862,7 +4864,7 @@ var require_prompts2 = __commonJS((exports) => {
|
|
|
4862
4864
|
});
|
|
4863
4865
|
|
|
4864
4866
|
// ../../node_modules/prompts/lib/index.js
|
|
4865
|
-
var require_lib = __commonJS((exports, module)
|
|
4867
|
+
var require_lib = __commonJS(function(exports, module) {
|
|
4866
4868
|
var prompts = require_prompts2();
|
|
4867
4869
|
var passOn = ["suggest", "format", "onState", "validate", "onRender", "type"];
|
|
4868
4870
|
var noop = () => {};
|
|
@@ -4935,7 +4937,7 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
4935
4937
|
});
|
|
4936
4938
|
|
|
4937
4939
|
// ../../node_modules/prompts/index.js
|
|
4938
|
-
var require_prompts3 = __commonJS((exports, module)
|
|
4940
|
+
var require_prompts3 = __commonJS(function(exports, module) {
|
|
4939
4941
|
function isNodeLT(tar) {
|
|
4940
4942
|
tar = (Array.isArray(tar) ? tar : tar.split(".")).map(Number);
|
|
4941
4943
|
let i = 0, src = process.versions.node.split(".").map(Number);
|
|
@@ -4951,7 +4953,7 @@ var require_prompts3 = __commonJS((exports, module) => {
|
|
|
4951
4953
|
});
|
|
4952
4954
|
|
|
4953
4955
|
// ../../node_modules/picocolors/picocolors.js
|
|
4954
|
-
var require_picocolors = __commonJS((exports, module)
|
|
4956
|
+
var require_picocolors = __commonJS(function(exports, module) {
|
|
4955
4957
|
var p = process || {};
|
|
4956
4958
|
var argv = p.argv || [];
|
|
4957
4959
|
var env = p.env || {};
|
|
@@ -5516,6 +5518,47 @@ function upgrade(args) {
|
|
|
5516
5518
|
const upgradeExecution = commandArguments.write ? writeProjectPackageJsonUpgrade(packagePath, scaffoldManifest, new Date) : planProjectPackageFileUpgrade(packagePath, scaffoldManifest);
|
|
5517
5519
|
printUpgradeExecution(upgradeExecution, commandArguments.projectDirectory, packagePath);
|
|
5518
5520
|
}
|
|
5521
|
+
var GUIDANCE_FILES = ["DESIGN.md", "AGENTS.md"];
|
|
5522
|
+
function missingGuidanceFiles(projectDirectory) {
|
|
5523
|
+
return GUIDANCE_FILES.filter((fileName) => !fs.existsSync(path.join(projectDirectory, fileName)));
|
|
5524
|
+
}
|
|
5525
|
+
function printGuidancePlan(projectDirectory, missingFiles) {
|
|
5526
|
+
console.log();
|
|
5527
|
+
console.log(import_picocolors.default.bold(`svadmin guidance — ${projectDirectory}`));
|
|
5528
|
+
for (const fileName of missingFiles) {
|
|
5529
|
+
console.log(` ${import_picocolors.default.cyan("•")} add ${fileName}`);
|
|
5530
|
+
}
|
|
5531
|
+
console.log();
|
|
5532
|
+
}
|
|
5533
|
+
function installMissingGuidanceFiles(guidanceDirectory, projectDirectory, missingFiles) {
|
|
5534
|
+
for (const fileName of missingFiles) {
|
|
5535
|
+
fs.copyFileSync(path.join(guidanceDirectory, fileName), path.join(projectDirectory, fileName));
|
|
5536
|
+
}
|
|
5537
|
+
}
|
|
5538
|
+
function guidance(args) {
|
|
5539
|
+
const { projectDirectory, write } = parseUpgradeArguments(args);
|
|
5540
|
+
const guidanceDirectory = path.join(__dirname2, "..", "guidance");
|
|
5541
|
+
if (!fs.existsSync(projectDirectory))
|
|
5542
|
+
throw new Error(`Project directory does not exist: ${projectDirectory}`);
|
|
5543
|
+
if (!fs.existsSync(guidanceDirectory))
|
|
5544
|
+
throw new Error("Shipped svadmin guidance files are missing");
|
|
5545
|
+
const missingFiles = missingGuidanceFiles(projectDirectory);
|
|
5546
|
+
if (missingFiles.length === 0) {
|
|
5547
|
+
console.log(import_picocolors.default.green(`
|
|
5548
|
+
✔ DESIGN.md and AGENTS.md already exist; nothing was changed.
|
|
5549
|
+
`));
|
|
5550
|
+
return;
|
|
5551
|
+
}
|
|
5552
|
+
printGuidancePlan(projectDirectory, missingFiles);
|
|
5553
|
+
if (!write) {
|
|
5554
|
+
console.log(import_picocolors.default.yellow(` Dry run only; re-run with --write to add missing guidance files.
|
|
5555
|
+
`));
|
|
5556
|
+
return;
|
|
5557
|
+
}
|
|
5558
|
+
installMissingGuidanceFiles(guidanceDirectory, projectDirectory, missingFiles);
|
|
5559
|
+
console.log(import_picocolors.default.green(` ✔ Added ${missingFiles.length} guidance file(s); existing files were preserved.`));
|
|
5560
|
+
console.log();
|
|
5561
|
+
}
|
|
5519
5562
|
async function init() {
|
|
5520
5563
|
console.log();
|
|
5521
5564
|
console.log(import_picocolors.default.cyan(" ╔═══════════════════════════════════╗"));
|
|
@@ -5583,6 +5626,7 @@ Operation cancelled.
|
|
|
5583
5626
|
${import_picocolors.default.bold("Scaffolding")} project in ${import_picocolors.default.green(projectDir)}...
|
|
5584
5627
|
`);
|
|
5585
5628
|
const templateDir = path.join(__dirname2, "..", "template");
|
|
5629
|
+
const guidanceDir = path.join(__dirname2, "..", "guidance");
|
|
5586
5630
|
const scaffoldManifest = loadShippedScaffoldManifest();
|
|
5587
5631
|
function copyDir(src, dest) {
|
|
5588
5632
|
fs.mkdirSync(dest, { recursive: true });
|
|
@@ -5601,6 +5645,10 @@ ${import_picocolors.default.bold("Scaffolding")} project in ${import_picocolors.
|
|
|
5601
5645
|
copyDir(templateDir, projectDir);
|
|
5602
5646
|
console.log(import_picocolors.default.green(" ✔") + " Template files copied");
|
|
5603
5647
|
}
|
|
5648
|
+
if (fs.existsSync(guidanceDir)) {
|
|
5649
|
+
copyDir(guidanceDir, projectDir);
|
|
5650
|
+
console.log(import_picocolors.default.green(" ✔") + " AI and design guidance copied");
|
|
5651
|
+
}
|
|
5604
5652
|
const packageJson = createProjectPackageJson(scaffoldManifest, {
|
|
5605
5653
|
projectName: response.projectName,
|
|
5606
5654
|
dataProvider: response.dataProvider,
|
|
@@ -5769,6 +5817,8 @@ if (subcommand === "eject") {
|
|
|
5769
5817
|
runCommand(() => doctor(rest));
|
|
5770
5818
|
} else if (subcommand === "upgrade") {
|
|
5771
5819
|
runCommand(() => upgrade(rest));
|
|
5820
|
+
} else if (subcommand === "guidance") {
|
|
5821
|
+
runCommand(() => guidance(rest));
|
|
5772
5822
|
} else {
|
|
5773
5823
|
runCommand(init);
|
|
5774
5824
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# svadmin UI Generation Rules
|
|
2
|
+
|
|
3
|
+
Read `DESIGN.md` before creating, revising, or reviewing any UI. It is the
|
|
4
|
+
authority for visual language, page hierarchy, feedback ownership, and
|
|
5
|
+
acceptance checks in this project.
|
|
6
|
+
|
|
7
|
+
## Required workflow
|
|
8
|
+
|
|
9
|
+
1. Name the page's single primary workflow and dominant next action.
|
|
10
|
+
2. Inventory every heading, description, notice, metric, badge, and data view.
|
|
11
|
+
3. Assign each fact and event to one primary UI surface.
|
|
12
|
+
4. Reuse `@svadmin/ui` components and semantic Tailwind tokens before writing
|
|
13
|
+
custom markup or raw colors.
|
|
14
|
+
5. Verify loading, empty, partial, error, permission, success, and mobile states.
|
|
15
|
+
|
|
16
|
+
## Feedback invariant
|
|
17
|
+
|
|
18
|
+
`one event -> one primary feedback surface`
|
|
19
|
+
|
|
20
|
+
- Field errors are inline.
|
|
21
|
+
- Routine success is a 3-second Toast.
|
|
22
|
+
- If success changes the page into a completed state, render that state and set
|
|
23
|
+
`successNotification: false` on the hook or form.
|
|
24
|
+
- Persistent notices are only for unresolved context, required action, blocking
|
|
25
|
+
failures, or risk. Use `FeedbackNotice`; it has no success variant.
|
|
26
|
+
- The first viewport may contain at most one full-width high-emphasis notice.
|
|
27
|
+
- A count or status already shown in a badge, table, progress state, or filename
|
|
28
|
+
must not be repeated in a banner or explanatory paragraph.
|
|
29
|
+
- Toasts are keyed by event identity when duplicate delivery is possible. Do not
|
|
30
|
+
deduplicate globally by message text.
|
|
31
|
+
|
|
32
|
+
## Reject generated UI when
|
|
33
|
+
|
|
34
|
+
- success appears simultaneously in a Toast, heading, description, Alert, badge,
|
|
35
|
+
or result summary;
|
|
36
|
+
- the page contains decorative explanation panels or nested cards;
|
|
37
|
+
- copy only describes the controls or data immediately below it;
|
|
38
|
+
- a resolved success banner remains in the normal reading flow;
|
|
39
|
+
- desktop or mobile output overlaps, clips, scrolls horizontally, or pushes the
|
|
40
|
+
primary action out of view.
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: "alpha"
|
|
3
|
+
name: "svadmin Stripe-first"
|
|
4
|
+
description: "A restrained, precise product interface for repeated administrative work."
|
|
5
|
+
colors:
|
|
6
|
+
background: "oklch(0.982 0.003 264)"
|
|
7
|
+
foreground: "oklch(0.205 0.012 264)"
|
|
8
|
+
surface: "oklch(1 0 0)"
|
|
9
|
+
surface-subtle: "oklch(0.968 0.004 264)"
|
|
10
|
+
muted-foreground: "oklch(0.493 0.018 264)"
|
|
11
|
+
border: "oklch(0.914 0.006 264)"
|
|
12
|
+
primary: "oklch(0.558 0.22 278)"
|
|
13
|
+
on-primary: "oklch(0.99 0 0)"
|
|
14
|
+
success: "oklch(0.51 0.16 151)"
|
|
15
|
+
warning: "oklch(0.7 0.15 75)"
|
|
16
|
+
danger: "oklch(0.58 0.22 27)"
|
|
17
|
+
typography:
|
|
18
|
+
body:
|
|
19
|
+
fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
|
|
20
|
+
fontSize: "0.875rem"
|
|
21
|
+
fontWeight: 400
|
|
22
|
+
lineHeight: 1.5
|
|
23
|
+
letterSpacing: "0px"
|
|
24
|
+
label:
|
|
25
|
+
fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
|
|
26
|
+
fontSize: "0.8125rem"
|
|
27
|
+
fontWeight: 500
|
|
28
|
+
lineHeight: 1.35
|
|
29
|
+
letterSpacing: "0px"
|
|
30
|
+
heading:
|
|
31
|
+
fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
|
|
32
|
+
fontSize: "1.25rem"
|
|
33
|
+
fontWeight: 600
|
|
34
|
+
lineHeight: 1.3
|
|
35
|
+
letterSpacing: "0px"
|
|
36
|
+
rounded:
|
|
37
|
+
sm: "4px"
|
|
38
|
+
md: "6px"
|
|
39
|
+
lg: "8px"
|
|
40
|
+
spacing:
|
|
41
|
+
xs: "4px"
|
|
42
|
+
sm: "8px"
|
|
43
|
+
md: "16px"
|
|
44
|
+
lg: "24px"
|
|
45
|
+
xl: "32px"
|
|
46
|
+
components:
|
|
47
|
+
page:
|
|
48
|
+
backgroundColor: "{colors.background}"
|
|
49
|
+
textColor: "{colors.foreground}"
|
|
50
|
+
typography: "{typography.body}"
|
|
51
|
+
surface:
|
|
52
|
+
backgroundColor: "{colors.surface}"
|
|
53
|
+
textColor: "{colors.foreground}"
|
|
54
|
+
rounded: "{rounded.lg}"
|
|
55
|
+
surface-subtle:
|
|
56
|
+
backgroundColor: "{colors.surface-subtle}"
|
|
57
|
+
textColor: "{colors.muted-foreground}"
|
|
58
|
+
rounded: "{rounded.md}"
|
|
59
|
+
button-primary:
|
|
60
|
+
backgroundColor: "{colors.primary}"
|
|
61
|
+
textColor: "{colors.on-primary}"
|
|
62
|
+
rounded: "{rounded.md}"
|
|
63
|
+
typography: "{typography.label}"
|
|
64
|
+
input:
|
|
65
|
+
backgroundColor: "{colors.surface}"
|
|
66
|
+
textColor: "{colors.foreground}"
|
|
67
|
+
rounded: "{rounded.md}"
|
|
68
|
+
typography: "{typography.body}"
|
|
69
|
+
divider:
|
|
70
|
+
backgroundColor: "{colors.border}"
|
|
71
|
+
height: "1px"
|
|
72
|
+
status-success:
|
|
73
|
+
backgroundColor: "{colors.success}"
|
|
74
|
+
textColor: "{colors.on-primary}"
|
|
75
|
+
rounded: "{rounded.sm}"
|
|
76
|
+
typography: "{typography.label}"
|
|
77
|
+
status-warning:
|
|
78
|
+
backgroundColor: "{colors.warning}"
|
|
79
|
+
textColor: "{colors.foreground}"
|
|
80
|
+
rounded: "{rounded.sm}"
|
|
81
|
+
typography: "{typography.label}"
|
|
82
|
+
status-danger:
|
|
83
|
+
backgroundColor: "{colors.danger}"
|
|
84
|
+
textColor: "{colors.on-primary}"
|
|
85
|
+
rounded: "{rounded.sm}"
|
|
86
|
+
typography: "{typography.label}"
|
|
87
|
+
page-heading:
|
|
88
|
+
textColor: "{colors.foreground}"
|
|
89
|
+
typography: "{typography.heading}"
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Overview
|
|
93
|
+
|
|
94
|
+
svadmin uses a Stripe-first product language: quiet neutral canvases, precise
|
|
95
|
+
type, hairline borders, restrained elevation, compact controls, and clear
|
|
96
|
+
feedback for repeated operational work. The interface should feel like a real
|
|
97
|
+
administrative product with trustworthy states, not a collection of dashboard
|
|
98
|
+
templates.
|
|
99
|
+
|
|
100
|
+
Metronic is a capability reference only. Its page families, information
|
|
101
|
+
architecture, and scenario coverage may expose missing components or examples,
|
|
102
|
+
but its palette, decoration, card treatment, typography, and branding are not
|
|
103
|
+
visual authority.
|
|
104
|
+
|
|
105
|
+
### Design principles
|
|
106
|
+
|
|
107
|
+
Seven principles turn the Stripe-first direction into reviewable product
|
|
108
|
+
decisions. They apply to built-in components, examples, generated applications,
|
|
109
|
+
and documentation:
|
|
110
|
+
|
|
111
|
+
1. **Clear by default:** every page has one primary job, one dominant next
|
|
112
|
+
action, and one owner for every visible fact. Supporting copy adds a
|
|
113
|
+
constraint, consequence, scope, or recovery path instead of repeating UI.
|
|
114
|
+
2. **Efficient in the loop:** preserve filters, selection, navigation context,
|
|
115
|
+
and keyboard reachability across repeated work. Loading and feedback must not
|
|
116
|
+
move the primary action or force an unnecessary page transition.
|
|
117
|
+
3. **Consistent by contract:** semantic tokens, component variants, state names,
|
|
118
|
+
page skeletons, and feedback lifecycles remain stable across products. Layout
|
|
119
|
+
presets may change density and composition, not interaction meaning.
|
|
120
|
+
4. **Trustworthy in every state:** loading, empty, partial, error, forbidden,
|
|
121
|
+
destructive, reversible, and completed states expose their scope and next
|
|
122
|
+
step. Data freshness, permission boundaries, and action consequences must be
|
|
123
|
+
visible when they affect a decision.
|
|
124
|
+
5. **Restrained like Stripe:** neutral surfaces and precise hierarchy carry the
|
|
125
|
+
interface. Accent, elevation, radius, animation, and decoration are used only
|
|
126
|
+
when they clarify priority or interaction.
|
|
127
|
+
6. **Accessible by construction:** keyboard access, visible focus, semantic
|
|
128
|
+
structure, non-color status cues, readable contrast, stable targets, and
|
|
129
|
+
responsive behavior are component defaults rather than page-level repairs.
|
|
130
|
+
7. **AI-ready and auditable:** generated UI declares its primary workflow,
|
|
131
|
+
information owners, state owners, and feedback removal conditions; it uses
|
|
132
|
+
the trusted component catalog and passes deterministic and visual gates.
|
|
133
|
+
|
|
134
|
+
Use these principles as an ordered review: first verify the task and state are
|
|
135
|
+
clear, then efficiency and consistency, then trust, restraint, accessibility,
|
|
136
|
+
and generation evidence. A visually polished page still fails when its state or
|
|
137
|
+
action ownership is ambiguous.
|
|
138
|
+
|
|
139
|
+
## Colors
|
|
140
|
+
|
|
141
|
+
Neutrals carry the interface. Primary is a single controlled interaction accent,
|
|
142
|
+
not a page background. Success, warning, and danger are reserved for semantic
|
|
143
|
+
status and feedback. Consumer themes may replace the primary hue while keeping
|
|
144
|
+
the neutral hierarchy and contrast relationships intact.
|
|
145
|
+
|
|
146
|
+
## Typography
|
|
147
|
+
|
|
148
|
+
Use Inter or the consumer's compatible system sans. Product pages use compact
|
|
149
|
+
headings and normal letter spacing. Uppercase table labels, negative tracking,
|
|
150
|
+
and oversized dashboard numerals are not defaults.
|
|
151
|
+
|
|
152
|
+
## Layout
|
|
153
|
+
|
|
154
|
+
Use an 8px spacing rhythm with 4px for tight internal alignment. Pages are
|
|
155
|
+
unframed layouts with a stable content width. Cards represent individual
|
|
156
|
+
objects or bounded tools; page sections are not decorative floating cards and
|
|
157
|
+
cards are not nested for visual effect.
|
|
158
|
+
|
|
159
|
+
## Elevation & Depth
|
|
160
|
+
|
|
161
|
+
Surfaces use a one-pixel border plus a subtle two-layer shadow. Hover elevation
|
|
162
|
+
may increase slightly for genuinely clickable items, without translation or
|
|
163
|
+
glow. Dialogs and menus receive stronger depth because they are floating
|
|
164
|
+
layers. Dark mode keeps the same hierarchy with low-chroma surfaces.
|
|
165
|
+
|
|
166
|
+
## Shapes
|
|
167
|
+
|
|
168
|
+
Controls use 6px radii and bounded surfaces use 8px radii. Pills are limited to
|
|
169
|
+
status badges, avatar groups, and controls whose geometry carries meaning.
|
|
170
|
+
|
|
171
|
+
## Components
|
|
172
|
+
|
|
173
|
+
Buttons, fields, tabs, tables, badges, empty states, skeletons, alerts, and
|
|
174
|
+
feedback use shared components and semantic tokens. Layout presets may adjust
|
|
175
|
+
density and composition, but they must not replace component color, typography,
|
|
176
|
+
focus, or elevation with hard-coded values.
|
|
177
|
+
|
|
178
|
+
### Reference responsibilities
|
|
179
|
+
|
|
180
|
+
The reference stack is layered. It is not a visual mixture:
|
|
181
|
+
|
|
182
|
+
- **Stripe is the visual authority:** hierarchy, restraint, neutral surfaces,
|
|
183
|
+
typography, density, and interaction tone.
|
|
184
|
+
- **Refine is an application-model reference:** resource routing, CRUD flows,
|
|
185
|
+
provider state, access control, and mutation ownership.
|
|
186
|
+
- **Ant Design is a behavior reference:** field validation, alerts, messages,
|
|
187
|
+
notifications, results, empty states, loading, and high-density data tasks.
|
|
188
|
+
- **shadcn/ui is a composition reference:** accessible primitives, source-owned
|
|
189
|
+
components, semantic tokens, variants, and AI-readable assembly patterns.
|
|
190
|
+
- **Carbon and PatternFly are enterprise-pattern references:** notification
|
|
191
|
+
lifecycle, inline versus global feedback, empty/error states, and operational
|
|
192
|
+
page composition.
|
|
193
|
+
- **Metronic is a coverage reference:** page families and missing scenarios only.
|
|
194
|
+
|
|
195
|
+
Never copy a reference library's palette, radius, elevation, marketing layout,
|
|
196
|
+
or component chrome without an explicit svadmin design decision.
|
|
197
|
+
|
|
198
|
+
### Page hierarchy and information budget
|
|
199
|
+
|
|
200
|
+
Every page must have one primary job and one dominant next action. Before adding
|
|
201
|
+
content, identify the page's primary workflow, current unresolved state, data
|
|
202
|
+
state, and action owner.
|
|
203
|
+
|
|
204
|
+
- From the page header through the primary work area, allow at most one
|
|
205
|
+
full-width, high-emphasis persistent feedback surface.
|
|
206
|
+
- Explanatory copy must add a constraint, consequence, scope, or recovery path.
|
|
207
|
+
It must not paraphrase the heading, field label, button, badge, or data below.
|
|
208
|
+
- A fact or count already visible in a filename, badge, table, progress state,
|
|
209
|
+
or summary has one owner and is not repeated in another banner or paragraph.
|
|
210
|
+
- Use a page section only when it groups a real task or bounded data set. Do not
|
|
211
|
+
create an informational section solely to describe the surrounding UI.
|
|
212
|
+
- A feedback surface has at most one primary action. Additional recovery paths
|
|
213
|
+
belong in the destination workflow, menu, or supporting text.
|
|
214
|
+
|
|
215
|
+
### Feedback hierarchy
|
|
216
|
+
|
|
217
|
+
The invariant is: **one event -> one primary feedback surface**.
|
|
218
|
+
|
|
219
|
+
| Event | Primary surface | Lifecycle |
|
|
220
|
+
| --- | --- | --- |
|
|
221
|
+
| Invalid field or field-specific server error | Inline field message | Until corrected |
|
|
222
|
+
| Successful mutation with no next action | Toast | 3 seconds |
|
|
223
|
+
| Success that changes the page into a completed state | New page/local state; disable the automatic Toast | Until navigation or a new task |
|
|
224
|
+
| Unresolved partial result or required user action | `FeedbackNotice` warning | Until resolved |
|
|
225
|
+
| Blocking failure, permission boundary, or unavailable workflow | `FeedbackNotice` danger or error state | Until resolved or dismissed |
|
|
226
|
+
| Non-blocking policy or scope context | `FeedbackNotice` info | While context remains relevant |
|
|
227
|
+
| Reversible mutation | Undoable Toast | Exactly the undo window |
|
|
228
|
+
|
|
229
|
+
Success is never a persistent page-level banner. `FeedbackNotice` intentionally
|
|
230
|
+
has no success tone. A successful event must not simultaneously occupy a Toast,
|
|
231
|
+
heading, description, Alert, status badge, and data summary. When a page owns a
|
|
232
|
+
completed state, disable hook-level success notification with
|
|
233
|
+
`successNotification: false` on the owning hook or form.
|
|
234
|
+
|
|
235
|
+
Toasts are collapsed by default, limited to three visible items, and keyed by
|
|
236
|
+
event identity when duplicate delivery is possible. A key represents one event,
|
|
237
|
+
not a message string. Errors may remain longer than success, but persistent
|
|
238
|
+
errors must expose a recovery path or a dismiss action.
|
|
239
|
+
|
|
240
|
+
### AI generation contract
|
|
241
|
+
|
|
242
|
+
Before accepting an AI-generated application page, verify all of the following:
|
|
243
|
+
|
|
244
|
+
1. The page has one explicit primary workflow and the main action is visible.
|
|
245
|
+
2. Every heading, description, notice, metric, badge, and table has unique
|
|
246
|
+
information ownership.
|
|
247
|
+
3. Loading, empty, partial, error, permission, and success states use the
|
|
248
|
+
feedback hierarchy above.
|
|
249
|
+
4. Ordinary success uses a Toast; state-transition success uses the new state;
|
|
250
|
+
the two are never emitted for the same event.
|
|
251
|
+
5. The first viewport contains no nested cards, decorative explanation panels,
|
|
252
|
+
or more than one persistent high-emphasis notice.
|
|
253
|
+
6. Desktop and mobile screenshots show no overlap, clipping, horizontal scroll,
|
|
254
|
+
or action displacement caused by feedback content.
|
|
255
|
+
|
|
256
|
+
## Do's and Don'ts
|
|
257
|
+
|
|
258
|
+
- Do keep hierarchy quiet, dense, aligned, and easy to scan repeatedly.
|
|
259
|
+
- Do show loading, empty, error, permission, progress, and mutation feedback.
|
|
260
|
+
- Do preserve visible keyboard focus and at least 44px coarse-pointer targets.
|
|
261
|
+
- Do remove, downgrade, or relocate feedback as soon as its state is resolved.
|
|
262
|
+
- Don't copy Metronic colors, decorative treatment, or template branding.
|
|
263
|
+
- Don't repeat a success fact across Toast, title, description, banner, badge,
|
|
264
|
+
and table data.
|
|
265
|
+
- Don't use persistent success banners for routine mutations.
|
|
266
|
+
- Don't use gradients, glow, glassmorphism, negative letter spacing, or blanket
|
|
267
|
+
`!important` overrides as the default product language.
|
|
268
|
+
- Don't use cards inside cards or make every section a floating card.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svadmin/create",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Scaffolding tool for svadmin projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
11
|
"template",
|
|
12
|
+
"guidance",
|
|
12
13
|
"scaffold-manifest.json"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
package/scaffold-manifest.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"check": "svelte-check --tsconfig ./tsconfig.json"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@svadmin/core": "^0.
|
|
14
|
-
"@svadmin/ui": "^0.
|
|
13
|
+
"@svadmin/core": "^0.38.0",
|
|
14
|
+
"@svadmin/ui": "^0.46.0",
|
|
15
15
|
"@tanstack/svelte-query": "^6.1.38",
|
|
16
16
|
"highlight.js": "^11.11.1",
|
|
17
17
|
"@lucide/svelte": "^1.31.0"
|