synthesisui 0.16.42 → 0.16.44
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/commands/import.js +68 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/commands/import.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { join, relative } from "node:path";
|
|
2
|
+
import { basename, join, relative } from "node:path";
|
|
3
3
|
import { readToken, resolveRegistry } from "../config.js";
|
|
4
4
|
import { isNearDuplicate } from "../doctor/color-distance.js";
|
|
5
5
|
import { diagnose, scanSource } from "../doctor/scan.js";
|
|
@@ -396,6 +396,70 @@ async function sayIfWorkspace(root) {
|
|
|
396
396
|
console.log("");
|
|
397
397
|
console.log(body(paint.dim("One system, many consumers - each app gets its own number against the same contract.")));
|
|
398
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* A name derived from the package, and honest about when it is a guess.
|
|
401
|
+
*
|
|
402
|
+
* `@frontend-hub/ui` stripped to "ui" (dono, 30/07), which names nothing: half
|
|
403
|
+
* the workspaces on earth have a package called ui, app or core. When the last
|
|
404
|
+
* segment is one of those generic words the scope carries the meaning, so it
|
|
405
|
+
* comes along - `frontend-hub-ui` - and failing that the folder the project
|
|
406
|
+
* lives in does.
|
|
407
|
+
*/
|
|
408
|
+
const GENERIC = new Set([
|
|
409
|
+
"ui",
|
|
410
|
+
"app",
|
|
411
|
+
"web",
|
|
412
|
+
"core",
|
|
413
|
+
"lib",
|
|
414
|
+
"libs",
|
|
415
|
+
"src",
|
|
416
|
+
"client",
|
|
417
|
+
"frontend",
|
|
418
|
+
"design",
|
|
419
|
+
"design-system",
|
|
420
|
+
"components",
|
|
421
|
+
"shared",
|
|
422
|
+
"common",
|
|
423
|
+
]);
|
|
424
|
+
export function deriveName(pkgName, dirName) {
|
|
425
|
+
const raw = (pkgName ?? "").trim();
|
|
426
|
+
const scoped = /^@([^/]+)\/(.+)$/.exec(raw);
|
|
427
|
+
const tail = (scoped ? scoped[2] : raw).toLowerCase();
|
|
428
|
+
if (tail && !GENERIC.has(tail))
|
|
429
|
+
return scoped ? scoped[2] : raw;
|
|
430
|
+
const owner = scoped ? scoped[1] : dirName;
|
|
431
|
+
if (owner && tail)
|
|
432
|
+
return `${owner}-${tail}`;
|
|
433
|
+
return tail || owner || "";
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Ask for the name, once, with the derived one ready to accept.
|
|
437
|
+
*
|
|
438
|
+
* Only on a real run and only at a terminal: a piped or scripted invocation
|
|
439
|
+
* must never block waiting for a person who is not there. `--name` skips it
|
|
440
|
+
* entirely, which is what CI should pass.
|
|
441
|
+
*/
|
|
442
|
+
async function askName(suggested) {
|
|
443
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
444
|
+
return suggested;
|
|
445
|
+
const { createInterface } = await import("node:readline/promises");
|
|
446
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
447
|
+
try {
|
|
448
|
+
console.log("");
|
|
449
|
+
console.log(section("What should this system be called"));
|
|
450
|
+
console.log(body(paint.faint("Answering creates it on your account. You can rename it later; the install slug never changes.")));
|
|
451
|
+
const answer = await rl.question(` name [${suggested}]: `);
|
|
452
|
+
const clean = answer.trim().slice(0, 60);
|
|
453
|
+
return clean || suggested;
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
// A closed stdin is not a failure worth stopping an import over.
|
|
457
|
+
return suggested;
|
|
458
|
+
}
|
|
459
|
+
finally {
|
|
460
|
+
rl.close();
|
|
461
|
+
}
|
|
462
|
+
}
|
|
399
463
|
export async function runImport(opts) {
|
|
400
464
|
const root = opts.root ?? process.cwd();
|
|
401
465
|
// A census handed to us (an agent annotated it) is sent as-is; the numbers
|
|
@@ -440,6 +504,8 @@ export async function runImport(opts) {
|
|
|
440
504
|
console.log("");
|
|
441
505
|
return;
|
|
442
506
|
}
|
|
507
|
+
const suggested = deriveName(census.project.name, basename(root) || "system");
|
|
508
|
+
const chosen = opts.name?.trim() || (await askName(suggested));
|
|
443
509
|
const token = await readToken();
|
|
444
510
|
if (!token) {
|
|
445
511
|
console.log("");
|
|
@@ -456,7 +522,7 @@ export async function runImport(opts) {
|
|
|
456
522
|
"content-type": "application/json",
|
|
457
523
|
Authorization: `Bearer ${token}`,
|
|
458
524
|
},
|
|
459
|
-
body: JSON.stringify({ census, name:
|
|
525
|
+
body: JSON.stringify({ census, name: chosen }),
|
|
460
526
|
}).catch(() => null);
|
|
461
527
|
if (!res || !res.ok) {
|
|
462
528
|
const detail = res
|
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ Usage - deterministic, FREE:
|
|
|
41
41
|
|
|
42
42
|
Usage - governance (deterministic, FREE):
|
|
43
43
|
synthesisui adopt [--write] turn the design system you ALREADY have into a contract
|
|
44
|
-
synthesisui import [--dry]
|
|
44
|
+
synthesisui import [--dry] [--name <n>] read the app you already have and make it a system
|
|
45
45
|
your agent follows - without touching your CSS
|
|
46
46
|
synthesisui connect wire your agent: the check as an editor hook, the system
|
|
47
47
|
as MCP tools, and a contract that stops repeating itself
|
package/package.json
CHANGED