youiyoux 0.1.0 → 0.1.3
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 +24 -14
- package/dist/chunks/{chunk-FUB7B3VK.js → chunk-74KBRI2H.js} +1 -1
- package/dist/chunks/{chunk-ZLRFD5JI.js → chunk-C3TSTYP7.js} +68 -7
- package/dist/chunks/{chunk-3ZHGONNA.js → chunk-L5BV4PI7.js} +399 -37
- package/dist/chunks/{src-7ENJHYG4.js → chunk-OIHNEGWH.js} +278 -78
- package/dist/chunks/{chunk-UXLATKEQ.js → chunk-RTOTNSOV.js} +484 -141
- package/dist/chunks/{chunk-UHPK62Q5.js → chunk-UEB6MJDX.js} +75 -10
- package/dist/chunks/{src-VEHGMKYV.js → src-DS43LCRA.js} +2 -2
- package/dist/chunks/src-U5NTDPUX.js +148 -0
- package/dist/chunks/{src-WQWYJ6IQ.js → src-YGEZCUAO.js} +48 -6
- package/dist/chunks/{src-4KFNL3MY.js → src-YUC5PIDK.js} +6 -2
- package/dist/chunks/{src-B742AYFC.js → src-ZS76UD7E.js} +30 -2
- package/dist/schema/youi.request.schema.json +229 -0
- package/dist/youi.js +5 -5
- package/dist/youiyoux.js +5 -5
- package/package.json +10 -12
package/README.md
CHANGED
|
@@ -1,26 +1,36 @@
|
|
|
1
1
|
# youiyoux
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Your agent rebuilds components you already have. youiyoux catches it.**
|
|
4
|
+
|
|
5
|
+
UI context and verification for coding agents: it tells the agent what your repo already has before
|
|
6
|
+
it writes UI, then checks what it wrote.
|
|
4
7
|
|
|
5
8
|
```sh
|
|
6
|
-
npx youiyoux
|
|
7
|
-
npx youiyoux path/to/repo
|
|
9
|
+
npx youiyoux # scan this repo
|
|
10
|
+
npx youiyoux path/to/repo # or another one; --out <dir> writes elsewhere
|
|
8
11
|
```
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
No config, no account. You get:
|
|
14
|
+
|
|
15
|
+
- `youiyoux-report.html`: near-duplicate components and which to keep, hardcoded values your theme already has, off-library imports, and the top fixes with their next steps. One offline page.
|
|
16
|
+
- `youiyoux-card.png`: a 1200×630 card with the headline numbers.
|
|
17
|
+
- `youiyoux-summary.md`: paste it into a PR or issue.
|
|
18
|
+
|
|
19
|
+
## For your agent
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| `youiyoux-summary.md` | A short summary for a README or pull request |
|
|
21
|
+
```sh
|
|
22
|
+
npx youiyoux agents install # rule in AGENTS.md + CLAUDE.md, MCP server for Claude Code + Codex
|
|
23
|
+
npx youiyoux hooks install # check after each Claude Code edit, and at git commit
|
|
24
|
+
```
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
- `ui_find_component` (MCP): before writing a component, the existing one with its import, props and a real usage.
|
|
27
|
+
- `npx youiyoux check --diff`: after UI edits, what the change adds, each with its fix.
|
|
28
|
+
- `ui_render` (MCP) or `npx youiyoux render <file>`: screenshots light and dark, accessibility issues, a diff against base.
|
|
19
29
|
|
|
20
|
-
|
|
30
|
+
## Privacy
|
|
21
31
|
|
|
22
|
-
|
|
32
|
+
Runs locally; nothing is uploaded, no telemetry. The report includes relative paths, component names, class lists, counts and rendered images when available. No source lines unless `--include-code`; home paths, usernames, env values and credentials are stripped. Rendered looks need a headless Chromium (`--render` offers to download it, ~100 MB, once); specimen images are cached in `~/.cache/youiyoux/specimens`.
|
|
23
33
|
|
|
24
|
-
Node 20 or later.
|
|
34
|
+
Node 20 or later. The `youi` bin is a silent alias.
|
|
25
35
|
|
|
26
|
-
|
|
36
|
+
Docs, agent reference and source: [github.com/ap9000/youiyoux](https://github.com/ap9000/youiyoux)
|
|
@@ -27331,7 +27331,7 @@ var STAGE_MOVES = [
|
|
|
27331
27331
|
function canMove(from, to, actor) {
|
|
27332
27332
|
return STAGE_MOVES.some((move) => move.from === from && move.to === to && move.by.includes(actor));
|
|
27333
27333
|
}
|
|
27334
|
-
var MCP_TOOLS = ["system_search", "system_get_component", "system_get_tokens", "system_get_rules", "system_where_used", "system_screen_bom", "system_check", "system_plan", "library_search", "library_request", "discover_search", "discover_show", "index_where_used", "index_swap_impact", "index_rule_covers", "ui_find_component", "ui_render"];
|
|
27334
|
+
var MCP_TOOLS = ["system_search", "system_get_component", "system_get_tokens", "system_get_rules", "system_where_used", "system_screen_bom", "system_check", "system_plan", "library_search", "library_request", "discover_search", "discover_show", "index_where_used", "index_swap_impact", "index_rule_covers", "ui_find_component", "ui_render", "requests_list", "request_reply", "request_addressed"];
|
|
27335
27335
|
var LIBRARY_KINDS = ["component", "token", "pattern"];
|
|
27336
27336
|
var LIBRARY_ID_PATTERN = /^lib:([a-z][a-z0-9-]*)\/(component|token|pattern)\/([a-z0-9][a-z0-9.\-]*)$/;
|
|
27337
27337
|
var LibraryId = external_exports.string().regex(LIBRARY_ID_PATTERN, "expected lib:<source>/<kind>/<name>");
|
|
@@ -27406,6 +27406,55 @@ async function loadLibrary(root) {
|
|
|
27406
27406
|
return { entries };
|
|
27407
27407
|
}
|
|
27408
27408
|
|
|
27409
|
+
// ../core/src/requests.ts
|
|
27410
|
+
var IsoTime2 = external_exports.string().datetime({ offset: true });
|
|
27411
|
+
var REQUEST_ID = /^r-[0-9a-f]{10}$/;
|
|
27412
|
+
var REQUEST_STATUSES = ["open", "addressed", "closed"];
|
|
27413
|
+
var RequestAuthor = external_exports.object({ kind: external_exports.enum(["person", "agent"]), name: external_exports.string().min(1).max(100) });
|
|
27414
|
+
var Box = external_exports.object({ x: external_exports.number(), y: external_exports.number(), width: external_exports.number().nonnegative(), height: external_exports.number().nonnegative() });
|
|
27415
|
+
var Size = external_exports.object({ width: external_exports.number().positive(), height: external_exports.number().positive() });
|
|
27416
|
+
var RequestTarget = external_exports.object({
|
|
27417
|
+
/** The route as the usage map names it (`/settings`, `*` for the app shell). */
|
|
27418
|
+
route: external_exports.string().min(1).max(300),
|
|
27419
|
+
/** here: this one, on this screen; element: every place the element is used. */
|
|
27420
|
+
scope: external_exports.enum(["here", "element"]),
|
|
27421
|
+
/** The component's name as it rendered (`Button`). */
|
|
27422
|
+
name: external_exports.string().min(1).max(200),
|
|
27423
|
+
/** The System element it is, or the one a lookalike stands in for. */
|
|
27424
|
+
element: ElementId.optional(),
|
|
27425
|
+
lookalike: external_exports.boolean().optional(),
|
|
27426
|
+
/** Project-relative, and the line that rendered it, when the capture found them. */
|
|
27427
|
+
file: external_exports.string().min(1).max(500).optional(),
|
|
27428
|
+
line: external_exports.number().int().positive().optional(),
|
|
27429
|
+
box: Box.optional(),
|
|
27430
|
+
page: Size.optional()
|
|
27431
|
+
});
|
|
27432
|
+
var RequestEntry = external_exports.object({
|
|
27433
|
+
author: RequestAuthor,
|
|
27434
|
+
at: IsoTime2,
|
|
27435
|
+
body: external_exports.string().max(4e3),
|
|
27436
|
+
/** A status change this entry made, if any. */
|
|
27437
|
+
status: external_exports.enum(REQUEST_STATUSES).optional()
|
|
27438
|
+
});
|
|
27439
|
+
var RequestDoc = external_exports.object({
|
|
27440
|
+
$schema: external_exports.string().optional(),
|
|
27441
|
+
schema: external_exports.literal("youi.request/v1"),
|
|
27442
|
+
id: external_exports.string().regex(REQUEST_ID, "expected r-<10 hex>"),
|
|
27443
|
+
/** The project id from youi.project.json. */
|
|
27444
|
+
project: external_exports.string().min(1).max(200),
|
|
27445
|
+
/** comment: a note; change: something to do. */
|
|
27446
|
+
kind: external_exports.enum(["comment", "change"]),
|
|
27447
|
+
status: external_exports.enum(REQUEST_STATUSES),
|
|
27448
|
+
body: external_exports.string().min(1).max(4e3),
|
|
27449
|
+
author: RequestAuthor,
|
|
27450
|
+
createdAt: IsoTime2,
|
|
27451
|
+
updatedAt: IsoTime2,
|
|
27452
|
+
target: RequestTarget,
|
|
27453
|
+
/** The screen as it was when this was filed (`<id>.before.webp` beside it), to compare with after a change. */
|
|
27454
|
+
before: external_exports.string().regex(/^r-[0-9a-f]{10}\.before\.webp$/).optional(),
|
|
27455
|
+
thread: external_exports.array(RequestEntry).max(500)
|
|
27456
|
+
});
|
|
27457
|
+
|
|
27409
27458
|
// ../core/src/tokens.ts
|
|
27410
27459
|
var TOKEN_ALIAS = /^\{([^{}]+)\}$/;
|
|
27411
27460
|
var ALIAS_MESSAGE = "expected an alias like {color.brand}";
|
|
@@ -27617,7 +27666,7 @@ function normalizeRelPath(path) {
|
|
|
27617
27666
|
return posix2.normalize(path.replace(/\\/g, "/")).replace(/^\.\//, "").replace(/\/+$/, "") || ".";
|
|
27618
27667
|
}
|
|
27619
27668
|
var RelPath = external_exports.string().min(1).refine((p) => !p.startsWith("/") && !normalizeRelPath(p).split("/").includes(".."), "expected a path relative to its root, without ..");
|
|
27620
|
-
var
|
|
27669
|
+
var IsoTime3 = external_exports.string().datetime({ offset: true });
|
|
27621
27670
|
var SystemConfig = external_exports.object({
|
|
27622
27671
|
id: external_exports.string().regex(/^[a-z][a-z0-9-]*$/, { error: ({ input: input2 }) => safeId(input2) === null ? `Invalid system id ${JSON.stringify(input2)}: use a plain name without ".." or path separators` : `Invalid system id ${JSON.stringify(input2)}: use lowercase letters, digits and hyphens, starting with a letter` }),
|
|
27623
27672
|
name: external_exports.string().min(1),
|
|
@@ -27875,7 +27924,7 @@ var ScanReport = external_exports.object({
|
|
|
27875
27924
|
/** Files checked from supplied text (unsaved edits, candidate code) rather than disk. */
|
|
27876
27925
|
overrides: external_exports.array(external_exports.string())
|
|
27877
27926
|
}).optional(),
|
|
27878
|
-
generatedAt:
|
|
27927
|
+
generatedAt: IsoTime3,
|
|
27879
27928
|
durationMs: external_exports.number(),
|
|
27880
27929
|
status: external_exports.enum(["complete", "partial"]),
|
|
27881
27930
|
coverage: external_exports.object({
|
|
@@ -27918,7 +27967,7 @@ var Baseline = external_exports.object({
|
|
|
27918
27967
|
$schema: external_exports.string().optional(),
|
|
27919
27968
|
schema: external_exports.literal("youi.baseline/v1"),
|
|
27920
27969
|
project: external_exports.string(),
|
|
27921
|
-
recordedAt:
|
|
27970
|
+
recordedAt: IsoTime3,
|
|
27922
27971
|
identity: CheckIdentity,
|
|
27923
27972
|
totals: external_exports.object({ errors: external_exports.number().int(), warnings: external_exports.number().int() }),
|
|
27924
27973
|
entries: external_exports.array(BaselineEntry)
|
|
@@ -27940,7 +27989,7 @@ var LockFile = external_exports.object({
|
|
|
27940
27989
|
system: external_exports.string(),
|
|
27941
27990
|
systemVersion: SemVer,
|
|
27942
27991
|
sourceCommit: external_exports.string().nullable(),
|
|
27943
|
-
syncedAt:
|
|
27992
|
+
syncedAt: IsoTime3,
|
|
27944
27993
|
files: external_exports.record(external_exports.string(), LockEntry)
|
|
27945
27994
|
});
|
|
27946
27995
|
var INVENTORY_ROLES = ["button", "link-as-button", "input", "card", "badge", "dialog", "tabs"];
|
|
@@ -28092,7 +28141,7 @@ var InventoryReport = external_exports.object({
|
|
|
28092
28141
|
$schema: external_exports.string().optional(),
|
|
28093
28142
|
schema: external_exports.literal("youi.inventory/v1"),
|
|
28094
28143
|
scanner: external_exports.string(),
|
|
28095
|
-
generatedAt:
|
|
28144
|
+
generatedAt: IsoTime3,
|
|
28096
28145
|
durationMs: external_exports.number(),
|
|
28097
28146
|
/** Two looks share a family only when every dimension is within these (px; weight in units) of every other look's. */
|
|
28098
28147
|
tolerance: external_exports.object({ height: external_exports.number(), padding: external_exports.number(), radius: external_exports.number(), fontSize: external_exports.number(), fontWeight: external_exports.number() }),
|
|
@@ -28126,7 +28175,8 @@ var PUBLISHED_SCHEMAS = {
|
|
|
28126
28175
|
"youi.baseline.schema.json": Baseline,
|
|
28127
28176
|
"youi.inventory.schema.json": InventoryReport,
|
|
28128
28177
|
"youi.detect.schema.json": DetectReport,
|
|
28129
|
-
"youi.tokens.schema.json": TokenDocument
|
|
28178
|
+
"youi.tokens.schema.json": TokenDocument,
|
|
28179
|
+
"youi.request.schema.json": RequestDoc
|
|
28130
28180
|
};
|
|
28131
28181
|
function normalizeProjectConfig(config2) {
|
|
28132
28182
|
const n = normalizeRelPath;
|
|
@@ -28263,6 +28313,12 @@ function executionLabel(execution) {
|
|
|
28263
28313
|
}
|
|
28264
28314
|
}
|
|
28265
28315
|
|
|
28316
|
+
// ../core/src/licence.ts
|
|
28317
|
+
function copyleft(spdx) {
|
|
28318
|
+
const strong = (part) => part.split(/\s+(?:AND|WITH)\s+/).some((id) => /^A?GPL-/.test(id.replace(/[()]/g, "").trim()));
|
|
28319
|
+
return spdx.split(/\s+OR\s+/).every(strong);
|
|
28320
|
+
}
|
|
28321
|
+
|
|
28266
28322
|
export {
|
|
28267
28323
|
require_dist,
|
|
28268
28324
|
clone,
|
|
@@ -28323,6 +28379,11 @@ export {
|
|
|
28323
28379
|
LibraryEntry,
|
|
28324
28380
|
LIBRARY_DIR,
|
|
28325
28381
|
loadLibrary,
|
|
28382
|
+
copyleft,
|
|
28383
|
+
REQUEST_ID,
|
|
28384
|
+
REQUEST_STATUSES,
|
|
28385
|
+
RequestTarget,
|
|
28386
|
+
RequestDoc,
|
|
28326
28387
|
TOKEN_ALIAS,
|
|
28327
28388
|
CSS_SAFE_NAME,
|
|
28328
28389
|
aliasesIn,
|