@reqvire-org/ads 0.3.11 → 0.3.12
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/mcp/catalog.mjs +3 -3
- package/dist/mcp/mutations.mjs +1 -1
- package/dist/mcp/server.mjs +2 -2
- package/dist/project-documents.mjs +29 -6
- package/dist/skills/ads-break-ui/SKILL.md +6 -4
- package/dist/skills/ads-break-ui/references/guarded-editing.md +10 -0
- package/dist/skills/ads-break-ui/references/scenarios.md +17 -0
- package/dist/skills/ads-designer/SKILL.md +6 -4
- package/dist/skills/ads-designer/references/guarded-editing.md +10 -0
- package/dist/skills/ads-designer/references/scenarios.md +17 -0
- package/dist/skills/ads-import/SKILL.md +6 -4
- package/dist/skills/ads-import/references/guarded-editing.md +10 -0
- package/dist/skills/ads-import/references/implementation.md +3 -1
- package/dist/skills/ads-import/references/scenarios.md +17 -0
- package/dist/skills/ads-migrate/SKILL.md +6 -4
- package/dist/skills/ads-migrate/references/guarded-editing.md +10 -0
- package/dist/skills/ads-migrate/references/scenarios.md +17 -0
- package/dist/skills/ads-migrate/references/testing.md +5 -0
- package/dist/skills/ads-motion/SKILL.md +6 -4
- package/dist/skills/ads-motion/references/guarded-editing.md +10 -0
- package/dist/skills/ads-motion/references/scenarios.md +17 -0
- package/dist/units.mjs +7 -6
- package/docs/ADS.md +4 -0
- package/docs/ARCHITECTURE.md +5 -1
- package/docs/CHANGELOG.md +11 -0
- package/docs/MCP.md +14 -1
- package/package.json +1 -1
package/dist/mcp/catalog.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import ts from "typescript";
|
|
|
4
4
|
import { isInside, sourceFiles } from "../config.mjs";
|
|
5
5
|
import { projectCompilerOptions } from "../boundaries.mjs";
|
|
6
6
|
import { publicApi } from "../public-api.mjs";
|
|
7
|
-
import {
|
|
7
|
+
import { projectDocumentFiles } from "../project-documents.mjs";
|
|
8
8
|
|
|
9
9
|
export const PROJECT_URI = "ads://project";
|
|
10
10
|
export const sourceUri = (file) => `${PROJECT_URI}/files/${file.split("/").map(encodeURIComponent).join("/")}`;
|
|
@@ -21,10 +21,10 @@ export function projectDocuments(options) {
|
|
|
21
21
|
}
|
|
22
22
|
for (const directory of new Set(files.map((file) => path.dirname(file)))) docs(directory);
|
|
23
23
|
docs(dsRoot);
|
|
24
|
-
for (const
|
|
24
|
+
for (const directory of new Set([root,dsRoot])) for (const name of projectDocumentFiles(directory)) files.push(path.join(directory, name));
|
|
25
25
|
return [...new Set(files)].filter((file) => isInside(root, realpathSync(file))).sort().map((file) => {
|
|
26
26
|
const relative = path.relative(root, file).replaceAll("\\", "/");
|
|
27
|
-
return { uri: sourceUri(relative), name: relative, mimeType:
|
|
27
|
+
return { uri: sourceUri(relative), name: relative, mimeType: /\.md$/i.test(file) ? "text/markdown" : file.endsWith(".json") ? "application/json" : "text/plain", file };
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
|
package/dist/mcp/mutations.mjs
CHANGED
|
@@ -65,7 +65,7 @@ function validateContent(change, unit) {
|
|
|
65
65
|
if (change.content === null) return;
|
|
66
66
|
const bytes = Buffer.from(change.content);
|
|
67
67
|
if (bytes.length > mutationLimits.fileBytes) throw fail("mutation-content", "The patched file exceeds 16 MiB.", change.path);
|
|
68
|
-
if (textFile(change.path) && (bytes.includes(0) || !Buffer.from(bytes.toString("utf8")).equals(bytes))) throw fail("mutation-content", "Text source must contain valid UTF-8 without NUL bytes.", change.path);
|
|
68
|
+
if ((unit === "documentation" || textFile(change.path)) && (bytes.includes(0) || !Buffer.from(bytes.toString("utf8")).equals(bytes))) throw fail("mutation-content", "Text source and documentation must contain valid UTF-8 without NUL bytes.", change.path);
|
|
69
69
|
if (/\.jsonc?$/.test(change.path)) {
|
|
70
70
|
const content=bytes.toString("utf8");
|
|
71
71
|
if (unit === "configuration" && !["package.json","ds.config.json"].includes(path.basename(change.path))) {
|
package/dist/mcp/server.mjs
CHANGED
|
@@ -260,9 +260,9 @@ export function createAdsMcp(directory, { era = "legacy", skillDirectory, pollIn
|
|
|
260
260
|
await refresh();
|
|
261
261
|
return { ...json(result), ...(!result.ok ? { isError: true } : {}) };
|
|
262
262
|
} },
|
|
263
|
-
{ name: "ads_units", description: "Discover editable ADS units and their files: components/patterns with colocated previews; shared controllers; composition; tokens; foundation shared files; documentation; assets/brand, assets/fonts and asset groups; configuration with ds.config.json, package/build/lint configuration and registered project guard/compiler sources. List summaries with query, or pass an exact unit ID for its manifest. Manifests include companionFiles with permitted shared-entry or owner-only style-boundary bookkeeping; preserve peer permissions and unrelated configuration. Imported peers stay separate. New owners follow the existing colocation convention.", schema: query.extend({ unit: z.string().min(1).max(256).optional() }), call: ({ unit, query: search = "", limit }) => {
|
|
263
|
+
{ name: "ads_units", description: "Discover editable ADS units and their files: components/patterns with colocated previews; shared controllers; composition; tokens; foundation shared files; documentation including shared credits/license notices; assets/brand, assets/fonts and asset groups; configuration with ds.config.json, package/build/lint configuration and registered project guard/compiler sources. List summaries with query, or pass an exact unit ID for its manifest. Manifests include filePolicy for supported new documentation paths and companionFiles with permitted shared-entry or owner-only style-boundary bookkeeping; preserve peer permissions and unrelated configuration. Imported peers stay separate. New owners follow the existing colocation convention.", schema: query.extend({ unit: z.string().min(1).max(256).optional() }), call: ({ unit, query: search = "", limit }) => {
|
|
264
264
|
const matches = edits.units().filter(item => unit ? item.id === unit : item.id.toLowerCase().includes(search.toLowerCase()));
|
|
265
|
-
return json({ total: matches.length, units: matches.slice(0, limit).map(item => ({ id: item.id, kind: item.kind, fileCount: item.files.length, ...(unit ? { files: item.files.slice(0, 200), filesTruncated: item.files.length > 200, ...(item.companionFiles ? { companionFiles: item.companionFiles } : {}) } : {}) })) });
|
|
265
|
+
return json({ total: matches.length, units: matches.slice(0, limit).map(item => ({ id: item.id, kind: item.kind, fileCount: item.files.length, ...(unit ? { files: item.files.slice(0, 200), filesTruncated: item.files.length > 200, ...(item.companionFiles ? { companionFiles: item.companionFiles } : {}), ...(item.filePolicy ? { filePolicy: item.filePolicy } : {}) } : {}) })) });
|
|
266
266
|
} },
|
|
267
267
|
{ name: "ads_read_file", description: "Read a bounded range of ADS or registered configuration/extension source. Returns unit, full-file digest, startLine and nextOffset; default/max is 12000 UTF-16 characters. Binary assets return byte count/digest and no encoded content. Paths come from ads_units or discovery. Missing new paths return digest null. Read only relevant context before preparing a Git patch.", schema: z.object({ path: z.string().min(1).max(500), offset: z.number().int().min(0).default(0), limit: z.number().int().min(1).max(mutationLimits.readChars).default(mutationLimits.readChars) }).strict(), call: ({ path: file, ...range }) => json(edits.read(file, range)) },
|
|
268
268
|
...(mutations ? [{ name: "ads_prepare_patch", description: "Prepare a Git patch without a separate project mirror. Create copies only one owner plus its declared companions into a local draft; edit that directory with local file tools. Diff checks baseline/source freshness and owner paths, then writes a patchFile under .ds/patches. Discard removes the draft. Live source is never changed; ads_apply_patch still validates all gates. Remote clients can continue sending inline Git diffs instead.", schema:z.object({unit:z.string().min(1).max(256),action:z.enum(["create","diff","discard"]).default("create"),draft:z.string().max(100).optional()}).strict(), call:args=>json(prepareUnitPatch(options,args)) },
|
|
@@ -2,15 +2,31 @@ import { existsSync, lstatSync, readdirSync } from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
const rootNames = ["README.md", "ADS.md", "DS.md", "ARCHITECTURE.md", "Architecture.md", "GUIDE.md", "MCP.md", "CHANGELOG.md"];
|
|
5
|
+
const noticeStem = /^(?:CREDITS|LICEN[CS]ES?|NOTICES?|COPYING|COPYRIGHT)(?:[-_][A-Za-z0-9][A-Za-z0-9._-]*)?$/i;
|
|
6
|
+
const textExtension = /\.(?:md|txt)$/i;
|
|
7
|
+
|
|
8
|
+
export const documentationFilePolicy = "Project guides; root CREDITS, LICENSE/LICENCE, NOTICE, COPYING and COPYRIGHT notices (optional -/_ qualifiers); licenses/ collections, also under docs/ or doc/. Notices use .md, .txt, or conventional extensionless names and valid UTF-8. The same document paths may live at the ADS root. Component-local notices remain with their owner; code, configuration, hidden and generated paths are excluded.";
|
|
9
|
+
|
|
10
|
+
function noticeName(name) {
|
|
11
|
+
const extension = path.posix.extname(name);
|
|
12
|
+
return (!extension || textExtension.test(name)) && noticeStem.test(extension ? name.slice(0,-extension.length) : name);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isProjectNotice(file) {
|
|
16
|
+
if (!file.includes("/")) return noticeName(file);
|
|
17
|
+
return /^(?:(?:docs|doc)\/)?licenses\/.+$/i.test(file) && (textExtension.test(file) || noticeName(path.posix.basename(file)));
|
|
18
|
+
}
|
|
5
19
|
|
|
6
20
|
/** Recognize documentation ownership even before a new guide exists. */
|
|
7
21
|
export function isProjectDocument(file) {
|
|
8
|
-
|
|
22
|
+
if (file.includes("\\") || file.includes("\0") || file.split("/").some(part => !part || part.startsWith("."))) return false;
|
|
23
|
+
return rootNames.includes(file) || isProjectNotice(file) || /^(?:docs|doc)\/.+\.md$/i.test(file);
|
|
9
24
|
}
|
|
10
25
|
|
|
11
|
-
/** Shared
|
|
12
|
-
export function
|
|
13
|
-
|
|
26
|
+
/** Shared document discovery for MCP resources and editable units. */
|
|
27
|
+
export function projectDocumentFiles(root) {
|
|
28
|
+
if (!existsSync(root) || !lstatSync(root).isDirectory()) return [];
|
|
29
|
+
const files = [];
|
|
14
30
|
function walk(relative) {
|
|
15
31
|
const directory = path.join(root, relative);
|
|
16
32
|
if (!existsSync(directory) || !lstatSync(directory).isDirectory()) return;
|
|
@@ -21,7 +37,14 @@ export function projectGuideFiles(root) {
|
|
|
21
37
|
else if (entry.isFile() && isProjectDocument(file)) files.push(file);
|
|
22
38
|
}
|
|
23
39
|
}
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
for (const entry of readdirSync(root,{withFileTypes:true})) {
|
|
41
|
+
if (entry.isFile() && isProjectDocument(entry.name)) files.push(entry.name);
|
|
42
|
+
else if (entry.isDirectory() && /^(?:docs|doc|licenses)$/i.test(entry.name)) walk(entry.name);
|
|
43
|
+
}
|
|
26
44
|
return files.sort();
|
|
27
45
|
}
|
|
46
|
+
|
|
47
|
+
/** Provenance stays discoverable without loading notice inventories as workflow guides. */
|
|
48
|
+
export function projectGuideFiles(root) {
|
|
49
|
+
return projectDocumentFiles(root).filter(file => !isProjectNotice(file));
|
|
50
|
+
}
|
|
@@ -49,10 +49,12 @@ For owner drafts, token-sample reconciliation, coupled transactions and local
|
|
|
49
49
|
constant namespaces, read [guarded-editing.md](references/guarded-editing.md).
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
For parent/child `covers`,
|
|
53
|
-
`scenario-render` / `showcase-class`
|
|
54
|
-
[scenario contracts](references/scenarios.md).
|
|
55
|
-
|
|
52
|
+
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
53
|
+
public style-helper use in scenarios, or `scenario-render` / `showcase-class`
|
|
54
|
+
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
55
|
+
examples explain API visibility, reference baselines and state-transition checks.
|
|
56
|
+
Traced parents can cover declared public children; verified public Linaria
|
|
57
|
+
helpers do not grant custom scenario CSS.
|
|
56
58
|
|
|
57
59
|
For atomic base/variant styling, helper/wrapper class composition, extracted
|
|
58
60
|
custom-property arithmetic, or an
|
|
@@ -6,6 +6,16 @@ tools, request `action:"diff"`, then apply the returned patchFile. Discard the
|
|
|
6
6
|
draft afterward. Remote clients can keep sending inline Git diffs. Neither draft
|
|
7
7
|
preparation nor diff generation validates or changes live source.
|
|
8
8
|
|
|
9
|
+
Shared provenance uses the existing `documentation` unit. Read its `filePolicy`
|
|
10
|
+
from `ads_units`: one patch can create `CREDITS.md`, shared `licenses/*.txt` and
|
|
11
|
+
README links together. Conventional root credits/license/notice names support
|
|
12
|
+
UTF-8 `.md`/`.txt` or extensionless notices; `licenses/` may also sit under
|
|
13
|
+
`docs/`, `doc/` or the ADS root. Preserve upstream notice text exactly. Keep
|
|
14
|
+
component/asset-local notices with their owner; reference shared notices instead
|
|
15
|
+
of duplicating them across units. Do not create an asset group or bypass a guard
|
|
16
|
+
to add these documents. Code/configuration and hidden/generated paths remain
|
|
17
|
+
outside documentation ownership.
|
|
18
|
+
|
|
9
19
|
For genuinely coupled changes, `ads_apply_transaction` accepts 2–8 distinct owner
|
|
10
20
|
patches (32 distinct files and 16 MiB combined). Each patch keeps its ownership and
|
|
11
21
|
companion restrictions. Patches apply in order; later shared-entry hunks match the
|
|
@@ -68,6 +68,23 @@ just to satisfy a guard. Static evidence does not establish successful mounting,
|
|
|
68
68
|
visibility, interaction, every state or visual parity. Verify those in the built
|
|
69
69
|
App and registered browser checks.
|
|
70
70
|
|
|
71
|
+
## Verification pitfalls
|
|
72
|
+
|
|
73
|
+
Preserve the intended API and the reference baseline when resolving a diagnostic.
|
|
74
|
+
These examples describe verification mistakes, not component-specific rules:
|
|
75
|
+
|
|
76
|
+
| Situation | Do not | Do instead |
|
|
77
|
+
|-----------|--------|------------|
|
|
78
|
+
| A reference example sets `width: 15rem`, while the native popup uses its default width. | Remove the reference width and claim the original example now matches. | Keep the baseline intact. Reproduce demo sizing through the project's public review/layout pattern or supported style helper. If a different native size is intentional, document it. Label any additional normalized comparison separately. |
|
|
79
|
+
| Static tracing cannot prove that a public clear control renders when a value is selected. | Remove its export, drop its required coverage, or change runtime behavior merely to pass the gate. | Preserve the intended public API. Try a meaningful selected-state fixture or another real scenario. If valid rendering remains untraceable, report the tooling limitation with a small reproduction. |
|
|
80
|
+
| A screenshot shows the clear control in a selected state. | Treat its presence as evidence that clearing works. | Add a browser check: start selected, activate Clear, assert the value and selection are empty, verify the control's resulting visibility and documented focus behavior, then select again. |
|
|
81
|
+
|
|
82
|
+
A private helper exposed through its parent's public prop can legitimately stay
|
|
83
|
+
private when that is the intended API. Verify the behavior through the parent;
|
|
84
|
+
do not export the helper solely for a test. Public/private ownership is a product
|
|
85
|
+
decision, not a coverage workaround. Browser checks verify transitions but do not
|
|
86
|
+
replace the current static `covers` requirement; `exercises` does not waive it.
|
|
87
|
+
|
|
71
88
|
## Scenarios may consume verified public style helpers
|
|
72
89
|
|
|
73
90
|
A deliberately public helper can expose its owner's Linaria treatment:
|
|
@@ -80,10 +80,12 @@ use the client's normal source-editing tools.
|
|
|
80
80
|
For owner drafts, token-sample reconciliation, coupled transactions and local
|
|
81
81
|
constant namespaces, read [guarded-editing.md](references/guarded-editing.md).
|
|
82
82
|
|
|
83
|
-
For parent/child `covers`,
|
|
84
|
-
`scenario-render` / `showcase-class`
|
|
85
|
-
[scenario contracts](references/scenarios.md).
|
|
86
|
-
|
|
83
|
+
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
84
|
+
public style-helper use in scenarios, or `scenario-render` / `showcase-class`
|
|
85
|
+
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
86
|
+
examples explain API visibility, reference baselines and state-transition checks.
|
|
87
|
+
Traced parents can cover declared public children; verified public Linaria
|
|
88
|
+
helpers do not grant custom scenario CSS.
|
|
87
89
|
|
|
88
90
|
For atomic base/variant styling, helper/wrapper class composition, extracted
|
|
89
91
|
custom-property arithmetic, or an
|
|
@@ -6,6 +6,16 @@ tools, request `action:"diff"`, then apply the returned patchFile. Discard the
|
|
|
6
6
|
draft afterward. Remote clients can keep sending inline Git diffs. Neither draft
|
|
7
7
|
preparation nor diff generation validates or changes live source.
|
|
8
8
|
|
|
9
|
+
Shared provenance uses the existing `documentation` unit. Read its `filePolicy`
|
|
10
|
+
from `ads_units`: one patch can create `CREDITS.md`, shared `licenses/*.txt` and
|
|
11
|
+
README links together. Conventional root credits/license/notice names support
|
|
12
|
+
UTF-8 `.md`/`.txt` or extensionless notices; `licenses/` may also sit under
|
|
13
|
+
`docs/`, `doc/` or the ADS root. Preserve upstream notice text exactly. Keep
|
|
14
|
+
component/asset-local notices with their owner; reference shared notices instead
|
|
15
|
+
of duplicating them across units. Do not create an asset group or bypass a guard
|
|
16
|
+
to add these documents. Code/configuration and hidden/generated paths remain
|
|
17
|
+
outside documentation ownership.
|
|
18
|
+
|
|
9
19
|
For genuinely coupled changes, `ads_apply_transaction` accepts 2–8 distinct owner
|
|
10
20
|
patches (32 distinct files and 16 MiB combined). Each patch keeps its ownership and
|
|
11
21
|
companion restrictions. Patches apply in order; later shared-entry hunks match the
|
|
@@ -68,6 +68,23 @@ just to satisfy a guard. Static evidence does not establish successful mounting,
|
|
|
68
68
|
visibility, interaction, every state or visual parity. Verify those in the built
|
|
69
69
|
App and registered browser checks.
|
|
70
70
|
|
|
71
|
+
## Verification pitfalls
|
|
72
|
+
|
|
73
|
+
Preserve the intended API and the reference baseline when resolving a diagnostic.
|
|
74
|
+
These examples describe verification mistakes, not component-specific rules:
|
|
75
|
+
|
|
76
|
+
| Situation | Do not | Do instead |
|
|
77
|
+
|-----------|--------|------------|
|
|
78
|
+
| A reference example sets `width: 15rem`, while the native popup uses its default width. | Remove the reference width and claim the original example now matches. | Keep the baseline intact. Reproduce demo sizing through the project's public review/layout pattern or supported style helper. If a different native size is intentional, document it. Label any additional normalized comparison separately. |
|
|
79
|
+
| Static tracing cannot prove that a public clear control renders when a value is selected. | Remove its export, drop its required coverage, or change runtime behavior merely to pass the gate. | Preserve the intended public API. Try a meaningful selected-state fixture or another real scenario. If valid rendering remains untraceable, report the tooling limitation with a small reproduction. |
|
|
80
|
+
| A screenshot shows the clear control in a selected state. | Treat its presence as evidence that clearing works. | Add a browser check: start selected, activate Clear, assert the value and selection are empty, verify the control's resulting visibility and documented focus behavior, then select again. |
|
|
81
|
+
|
|
82
|
+
A private helper exposed through its parent's public prop can legitimately stay
|
|
83
|
+
private when that is the intended API. Verify the behavior through the parent;
|
|
84
|
+
do not export the helper solely for a test. Public/private ownership is a product
|
|
85
|
+
decision, not a coverage workaround. Browser checks verify transitions but do not
|
|
86
|
+
replace the current static `covers` requirement; `exercises` does not waive it.
|
|
87
|
+
|
|
71
88
|
## Scenarios may consume verified public style helpers
|
|
72
89
|
|
|
73
90
|
A deliberately public helper can expose its owner's Linaria treatment:
|
|
@@ -44,10 +44,12 @@ use the client's normal source-editing tools.
|
|
|
44
44
|
For owner drafts, token-sample reconciliation, coupled transactions and local
|
|
45
45
|
constant namespaces, read [guarded-editing.md](references/guarded-editing.md).
|
|
46
46
|
|
|
47
|
-
For parent/child `covers`,
|
|
48
|
-
`scenario-render` / `showcase-class`
|
|
49
|
-
[scenario contracts](references/scenarios.md).
|
|
50
|
-
|
|
47
|
+
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
48
|
+
public style-helper use in scenarios, or `scenario-render` / `showcase-class`
|
|
49
|
+
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
50
|
+
examples explain API visibility, reference baselines and state-transition checks.
|
|
51
|
+
Traced parents can cover declared public children; verified public Linaria
|
|
52
|
+
helpers do not grant custom scenario CSS.
|
|
51
53
|
|
|
52
54
|
For atomic base/variant styling, helper/wrapper class composition, extracted
|
|
53
55
|
custom-property arithmetic, or an
|
|
@@ -6,6 +6,16 @@ tools, request `action:"diff"`, then apply the returned patchFile. Discard the
|
|
|
6
6
|
draft afterward. Remote clients can keep sending inline Git diffs. Neither draft
|
|
7
7
|
preparation nor diff generation validates or changes live source.
|
|
8
8
|
|
|
9
|
+
Shared provenance uses the existing `documentation` unit. Read its `filePolicy`
|
|
10
|
+
from `ads_units`: one patch can create `CREDITS.md`, shared `licenses/*.txt` and
|
|
11
|
+
README links together. Conventional root credits/license/notice names support
|
|
12
|
+
UTF-8 `.md`/`.txt` or extensionless notices; `licenses/` may also sit under
|
|
13
|
+
`docs/`, `doc/` or the ADS root. Preserve upstream notice text exactly. Keep
|
|
14
|
+
component/asset-local notices with their owner; reference shared notices instead
|
|
15
|
+
of duplicating them across units. Do not create an asset group or bypass a guard
|
|
16
|
+
to add these documents. Code/configuration and hidden/generated paths remain
|
|
17
|
+
outside documentation ownership.
|
|
18
|
+
|
|
9
19
|
For genuinely coupled changes, `ads_apply_transaction` accepts 2–8 distinct owner
|
|
10
20
|
patches (32 distinct files and 16 MiB combined). Each patch keeps its ownership and
|
|
11
21
|
companion restrictions. Patches apply in order; later shared-entry hunks match the
|
|
@@ -92,7 +92,9 @@ imports, setup/providers, and scope/mounting across routes where relevant.
|
|
|
92
92
|
|
|
93
93
|
Compare the imported component or pattern with the actual source implementation
|
|
94
94
|
at the recorded revision. Align content, configuration, themes, viewport, and
|
|
95
|
-
input modality.
|
|
95
|
+
input modality. Preserve the original comparison baseline; see the
|
|
96
|
+
[verification pitfalls](scenarios.md#verification-pitfalls) before changing
|
|
97
|
+
reference sizing or API visibility to make checks pass. For implementation comparisons, use matching token values when
|
|
96
98
|
possible; also verify the item under its actual destination theme. For
|
|
97
99
|
stateful/motion-heavy items, check lifecycle, focus, keyboard,
|
|
98
100
|
pointer and touch, natural dimensions, transitions, interruption, reduced motion,
|
|
@@ -68,6 +68,23 @@ just to satisfy a guard. Static evidence does not establish successful mounting,
|
|
|
68
68
|
visibility, interaction, every state or visual parity. Verify those in the built
|
|
69
69
|
App and registered browser checks.
|
|
70
70
|
|
|
71
|
+
## Verification pitfalls
|
|
72
|
+
|
|
73
|
+
Preserve the intended API and the reference baseline when resolving a diagnostic.
|
|
74
|
+
These examples describe verification mistakes, not component-specific rules:
|
|
75
|
+
|
|
76
|
+
| Situation | Do not | Do instead |
|
|
77
|
+
|-----------|--------|------------|
|
|
78
|
+
| A reference example sets `width: 15rem`, while the native popup uses its default width. | Remove the reference width and claim the original example now matches. | Keep the baseline intact. Reproduce demo sizing through the project's public review/layout pattern or supported style helper. If a different native size is intentional, document it. Label any additional normalized comparison separately. |
|
|
79
|
+
| Static tracing cannot prove that a public clear control renders when a value is selected. | Remove its export, drop its required coverage, or change runtime behavior merely to pass the gate. | Preserve the intended public API. Try a meaningful selected-state fixture or another real scenario. If valid rendering remains untraceable, report the tooling limitation with a small reproduction. |
|
|
80
|
+
| A screenshot shows the clear control in a selected state. | Treat its presence as evidence that clearing works. | Add a browser check: start selected, activate Clear, assert the value and selection are empty, verify the control's resulting visibility and documented focus behavior, then select again. |
|
|
81
|
+
|
|
82
|
+
A private helper exposed through its parent's public prop can legitimately stay
|
|
83
|
+
private when that is the intended API. Verify the behavior through the parent;
|
|
84
|
+
do not export the helper solely for a test. Public/private ownership is a product
|
|
85
|
+
decision, not a coverage workaround. Browser checks verify transitions but do not
|
|
86
|
+
replace the current static `covers` requirement; `exercises` does not waive it.
|
|
87
|
+
|
|
71
88
|
## Scenarios may consume verified public style helpers
|
|
72
89
|
|
|
73
90
|
A deliberately public helper can expose its owner's Linaria treatment:
|
|
@@ -46,10 +46,12 @@ For owner drafts, token-sample reconciliation, coupled transactions and local
|
|
|
46
46
|
constant namespaces, read [guarded-editing.md](references/guarded-editing.md).
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
For parent/child `covers`,
|
|
50
|
-
`scenario-render` / `showcase-class`
|
|
51
|
-
[scenario contracts](references/scenarios.md).
|
|
52
|
-
|
|
49
|
+
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
50
|
+
public style-helper use in scenarios, or `scenario-render` / `showcase-class`
|
|
51
|
+
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
52
|
+
examples explain API visibility, reference baselines and state-transition checks.
|
|
53
|
+
Traced parents can cover declared public children; verified public Linaria
|
|
54
|
+
helpers do not grant custom scenario CSS.
|
|
53
55
|
|
|
54
56
|
For atomic base/variant styling, helper/wrapper class composition, extracted
|
|
55
57
|
custom-property arithmetic, or an
|
|
@@ -6,6 +6,16 @@ tools, request `action:"diff"`, then apply the returned patchFile. Discard the
|
|
|
6
6
|
draft afterward. Remote clients can keep sending inline Git diffs. Neither draft
|
|
7
7
|
preparation nor diff generation validates or changes live source.
|
|
8
8
|
|
|
9
|
+
Shared provenance uses the existing `documentation` unit. Read its `filePolicy`
|
|
10
|
+
from `ads_units`: one patch can create `CREDITS.md`, shared `licenses/*.txt` and
|
|
11
|
+
README links together. Conventional root credits/license/notice names support
|
|
12
|
+
UTF-8 `.md`/`.txt` or extensionless notices; `licenses/` may also sit under
|
|
13
|
+
`docs/`, `doc/` or the ADS root. Preserve upstream notice text exactly. Keep
|
|
14
|
+
component/asset-local notices with their owner; reference shared notices instead
|
|
15
|
+
of duplicating them across units. Do not create an asset group or bypass a guard
|
|
16
|
+
to add these documents. Code/configuration and hidden/generated paths remain
|
|
17
|
+
outside documentation ownership.
|
|
18
|
+
|
|
9
19
|
For genuinely coupled changes, `ads_apply_transaction` accepts 2–8 distinct owner
|
|
10
20
|
patches (32 distinct files and 16 MiB combined). Each patch keeps its ownership and
|
|
11
21
|
companion restrictions. Patches apply in order; later shared-entry hunks match the
|
|
@@ -68,6 +68,23 @@ just to satisfy a guard. Static evidence does not establish successful mounting,
|
|
|
68
68
|
visibility, interaction, every state or visual parity. Verify those in the built
|
|
69
69
|
App and registered browser checks.
|
|
70
70
|
|
|
71
|
+
## Verification pitfalls
|
|
72
|
+
|
|
73
|
+
Preserve the intended API and the reference baseline when resolving a diagnostic.
|
|
74
|
+
These examples describe verification mistakes, not component-specific rules:
|
|
75
|
+
|
|
76
|
+
| Situation | Do not | Do instead |
|
|
77
|
+
|-----------|--------|------------|
|
|
78
|
+
| A reference example sets `width: 15rem`, while the native popup uses its default width. | Remove the reference width and claim the original example now matches. | Keep the baseline intact. Reproduce demo sizing through the project's public review/layout pattern or supported style helper. If a different native size is intentional, document it. Label any additional normalized comparison separately. |
|
|
79
|
+
| Static tracing cannot prove that a public clear control renders when a value is selected. | Remove its export, drop its required coverage, or change runtime behavior merely to pass the gate. | Preserve the intended public API. Try a meaningful selected-state fixture or another real scenario. If valid rendering remains untraceable, report the tooling limitation with a small reproduction. |
|
|
80
|
+
| A screenshot shows the clear control in a selected state. | Treat its presence as evidence that clearing works. | Add a browser check: start selected, activate Clear, assert the value and selection are empty, verify the control's resulting visibility and documented focus behavior, then select again. |
|
|
81
|
+
|
|
82
|
+
A private helper exposed through its parent's public prop can legitimately stay
|
|
83
|
+
private when that is the intended API. Verify the behavior through the parent;
|
|
84
|
+
do not export the helper solely for a test. Public/private ownership is a product
|
|
85
|
+
decision, not a coverage workaround. Browser checks verify transitions but do not
|
|
86
|
+
replace the current static `covers` requirement; `exercises` does not waive it.
|
|
87
|
+
|
|
71
88
|
## Scenarios may consume verified public style helpers
|
|
72
89
|
|
|
73
90
|
A deliberately public helper can expose its owner's Linaria treatment:
|
|
@@ -8,6 +8,11 @@ the baseline. The page frame may use native controls, but those controls must
|
|
|
8
8
|
trigger the original component and store. Two pages importing the native component
|
|
9
9
|
cannot establish upstream parity.
|
|
10
10
|
|
|
11
|
+
Keep example-level sizing and configuration intact too. Changing a reference to
|
|
12
|
+
match the native result weakens the comparison even when its component CSS is
|
|
13
|
+
untouched. Use the [verification pitfalls](scenarios.md#verification-pitfalls)
|
|
14
|
+
for concrete baseline, API-visibility and conditional-control examples.
|
|
15
|
+
|
|
11
16
|
Use identical messages, options, counts, async delays/outcomes, action payloads,
|
|
12
17
|
and viewport/input settings. Align configuration explicitly rather than relying
|
|
13
18
|
on two different defaults. Compare brand/token differences separately from UX
|
|
@@ -66,10 +66,12 @@ For owner drafts, token-sample reconciliation, coupled transactions and local
|
|
|
66
66
|
constant namespaces, read [guarded-editing.md](references/guarded-editing.md).
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
For parent/child `covers`,
|
|
70
|
-
`scenario-render` / `showcase-class`
|
|
71
|
-
[scenario contracts](references/scenarios.md).
|
|
72
|
-
|
|
69
|
+
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
70
|
+
public style-helper use in scenarios, or `scenario-render` / `showcase-class`
|
|
71
|
+
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
72
|
+
examples explain API visibility, reference baselines and state-transition checks.
|
|
73
|
+
Traced parents can cover declared public children; verified public Linaria
|
|
74
|
+
helpers do not grant custom scenario CSS.
|
|
73
75
|
|
|
74
76
|
For atomic base/variant styling, helper/wrapper class composition, extracted
|
|
75
77
|
custom-property arithmetic, or an
|
|
@@ -6,6 +6,16 @@ tools, request `action:"diff"`, then apply the returned patchFile. Discard the
|
|
|
6
6
|
draft afterward. Remote clients can keep sending inline Git diffs. Neither draft
|
|
7
7
|
preparation nor diff generation validates or changes live source.
|
|
8
8
|
|
|
9
|
+
Shared provenance uses the existing `documentation` unit. Read its `filePolicy`
|
|
10
|
+
from `ads_units`: one patch can create `CREDITS.md`, shared `licenses/*.txt` and
|
|
11
|
+
README links together. Conventional root credits/license/notice names support
|
|
12
|
+
UTF-8 `.md`/`.txt` or extensionless notices; `licenses/` may also sit under
|
|
13
|
+
`docs/`, `doc/` or the ADS root. Preserve upstream notice text exactly. Keep
|
|
14
|
+
component/asset-local notices with their owner; reference shared notices instead
|
|
15
|
+
of duplicating them across units. Do not create an asset group or bypass a guard
|
|
16
|
+
to add these documents. Code/configuration and hidden/generated paths remain
|
|
17
|
+
outside documentation ownership.
|
|
18
|
+
|
|
9
19
|
For genuinely coupled changes, `ads_apply_transaction` accepts 2–8 distinct owner
|
|
10
20
|
patches (32 distinct files and 16 MiB combined). Each patch keeps its ownership and
|
|
11
21
|
companion restrictions. Patches apply in order; later shared-entry hunks match the
|
|
@@ -68,6 +68,23 @@ just to satisfy a guard. Static evidence does not establish successful mounting,
|
|
|
68
68
|
visibility, interaction, every state or visual parity. Verify those in the built
|
|
69
69
|
App and registered browser checks.
|
|
70
70
|
|
|
71
|
+
## Verification pitfalls
|
|
72
|
+
|
|
73
|
+
Preserve the intended API and the reference baseline when resolving a diagnostic.
|
|
74
|
+
These examples describe verification mistakes, not component-specific rules:
|
|
75
|
+
|
|
76
|
+
| Situation | Do not | Do instead |
|
|
77
|
+
|-----------|--------|------------|
|
|
78
|
+
| A reference example sets `width: 15rem`, while the native popup uses its default width. | Remove the reference width and claim the original example now matches. | Keep the baseline intact. Reproduce demo sizing through the project's public review/layout pattern or supported style helper. If a different native size is intentional, document it. Label any additional normalized comparison separately. |
|
|
79
|
+
| Static tracing cannot prove that a public clear control renders when a value is selected. | Remove its export, drop its required coverage, or change runtime behavior merely to pass the gate. | Preserve the intended public API. Try a meaningful selected-state fixture or another real scenario. If valid rendering remains untraceable, report the tooling limitation with a small reproduction. |
|
|
80
|
+
| A screenshot shows the clear control in a selected state. | Treat its presence as evidence that clearing works. | Add a browser check: start selected, activate Clear, assert the value and selection are empty, verify the control's resulting visibility and documented focus behavior, then select again. |
|
|
81
|
+
|
|
82
|
+
A private helper exposed through its parent's public prop can legitimately stay
|
|
83
|
+
private when that is the intended API. Verify the behavior through the parent;
|
|
84
|
+
do not export the helper solely for a test. Public/private ownership is a product
|
|
85
|
+
decision, not a coverage workaround. Browser checks verify transitions but do not
|
|
86
|
+
replace the current static `covers` requirement; `exercises` does not waive it.
|
|
87
|
+
|
|
71
88
|
## Scenarios may consume verified public style helpers
|
|
72
89
|
|
|
73
90
|
A deliberately public helper can expose its owner's Linaria treatment:
|
package/dist/units.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import ts from "typescript";
|
|
|
4
4
|
import postcss from "postcss";
|
|
5
5
|
import { isDevelopmentFile, isInside } from "./config.mjs";
|
|
6
6
|
import { importResolver } from "./boundaries.mjs";
|
|
7
|
-
import { isProjectDocument,
|
|
7
|
+
import { documentationFilePolicy, isProjectDocument, projectDocumentFiles } from "./project-documents.mjs";
|
|
8
8
|
import { foundationFiles, foundationImportTarget } from "./token-policy.mjs";
|
|
9
9
|
|
|
10
10
|
const source = /\.[cm]?[jt]sx?$/;
|
|
@@ -119,13 +119,13 @@ export function inspectUnits(options) {
|
|
|
119
119
|
function owner(relative) {
|
|
120
120
|
const projectFile = slash(path.relative(root, path.resolve(dsRoot, relative)));
|
|
121
121
|
if (setup.has(projectFile)) return "configuration";
|
|
122
|
-
if (
|
|
123
|
-
if (!isInside(dsRoot, path.resolve(dsRoot, relative))) return null;
|
|
122
|
+
if (!isInside(dsRoot, path.resolve(dsRoot, relative))) return isProjectDocument(projectFile) ? "documentation" : null;
|
|
124
123
|
if (relative === publicEntry) return null; // Controlled re-export bookkeeping.
|
|
125
124
|
if (relative.startsWith(tokenDir + "/")) return "tokens";
|
|
126
125
|
if (relative.startsWith("assets/")) return relative.split("/").length > 2 ? relative.split("/").slice(0, 2).join("/") : "assets";
|
|
126
|
+
if (isProjectDocument(relative)) return "documentation";
|
|
127
127
|
if (!relative.includes("/")) return /(?:\.(?:md|txt)$|^LICENSE$)/i.test(relative) ? "documentation" : "foundation";
|
|
128
|
-
if (!/^(?:components|patterns|controllers|composition)\//.test(relative)) return relative.split("/")[0];
|
|
128
|
+
if (!/^(?:components|patterns|controllers|composition)\//.test(relative)) return relative.split("/")[0] === "documentation" ? null : relative.split("/")[0];
|
|
129
129
|
for (const directory of directoryUnits) if (relative.startsWith(directory + "/")) return directory;
|
|
130
130
|
for (const unit of flatUnits) if (relative.startsWith(unit + "/") || relative.startsWith(unit + ".")) return unit;
|
|
131
131
|
const base = path.basename(relative).split(".")[0];
|
|
@@ -136,7 +136,8 @@ export function inspectUnits(options) {
|
|
|
136
136
|
for (const id of ["foundation", "documentation", "tokens", "assets/brand", "assets/fonts"]) units.set(id, { id, kind: id.split("/")[0], files: [] });
|
|
137
137
|
units.get("tokens").companionFiles = [{ path: slash(path.relative(root, path.join(dsRoot, stylesEntry))),
|
|
138
138
|
allowedChanges: "Only add/remove canonical foundation imports required by token foundation files created/deleted in this patch; preserve other imports and comments." }];
|
|
139
|
-
units.get("documentation").files =
|
|
139
|
+
units.get("documentation").files = projectDocumentFiles(root).filter(file => owner(slash(path.relative(dsRoot,path.resolve(root,file)))) === "documentation");
|
|
140
|
+
units.get("documentation").filePolicy = documentationFilePolicy;
|
|
140
141
|
for (const relative of files) {
|
|
141
142
|
const id = owner(relative);
|
|
142
143
|
if (!id) continue;
|
|
@@ -182,7 +183,7 @@ export function checkUnitFiles(options, unit, changes, inventory = inspectUnits(
|
|
|
182
183
|
if (unit === "tokens" && relative === inventory.stylesEntry) continue; // Controlled foundation import bookkeeping.
|
|
183
184
|
if (allowNew && change.originalContent === null && (relative.startsWith(unit + "/") || relative.startsWith(unit + "."))) continue;
|
|
184
185
|
const owner = inventory.owner(relative);
|
|
185
|
-
if (owner !== unit) throw fail(`This patch targets ${unit}; ${change.path} belongs to ${owner ?? "a different ADS layer"}. Submit a separate unit patch
|
|
186
|
+
if (owner !== unit) throw fail(`This patch targets ${unit}; ${change.path} belongs to ${owner ?? "a different ADS layer"}. Submit a separate unit patch.${unit === "documentation" ? ` ${documentationFilePolicy}` : ""}`, change.path);
|
|
186
187
|
}
|
|
187
188
|
return inventory;
|
|
188
189
|
}
|
package/docs/ADS.md
CHANGED
|
@@ -333,6 +333,10 @@ in each item's local README. Record source repository/file links, revision,
|
|
|
333
333
|
authors, concrete influences, and integration differences. Preserve applicable
|
|
334
334
|
license notices for copied/adapted source and assets. The project guide records
|
|
335
335
|
local implementation choices and links to the local item guides.
|
|
336
|
+
Shared `CREDITS.md`, conventional root notices and text files in `licenses/` use
|
|
337
|
+
the `documentation` mutation unit; its `filePolicy` describes supported new paths.
|
|
338
|
+
They can be added with README links in one guarded patch, without duplicating a
|
|
339
|
+
shared license into every component. Colocated notices retain their owning unit.
|
|
336
340
|
|
|
337
341
|
## Build contract
|
|
338
342
|
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -373,7 +373,11 @@ the isolated candidate project. Passing checks describe
|
|
|
373
373
|
their registered assertions, not every natural-language claim. This keeps edits
|
|
374
374
|
focused without requiring entire file bodies in model context. Peer units and
|
|
375
375
|
unrelated owners remain outside the selected unit's edit boundary. Shared foundation,
|
|
376
|
-
branding and guides have their own units.
|
|
376
|
+
branding and guides have their own units. Shared credits and text license notices
|
|
377
|
+
belong to the documentation unit, including conventional root notices and shared
|
|
378
|
+
`licenses/` collections. Colocated notices remain with their component or asset
|
|
379
|
+
owner. Documentation paths and UTF-8 validation do not grant code/configuration
|
|
380
|
+
ownership. Project configuration, registered guards
|
|
377
381
|
and compiler integration form an explicit configuration unit; their proposed
|
|
378
382
|
settings pass the same mandatory validation. Binary assets can travel as Git patch
|
|
379
383
|
artifacts without entering model context, and compiler configuration changes
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.12
|
|
4
|
+
|
|
5
|
+
- Let the documentation unit create shared credits, conventional root license
|
|
6
|
+
notices and text `licenses/` collections in one guarded owner patch. Expose its
|
|
7
|
+
new-file policy, discover readable provenance resources without enlarging
|
|
8
|
+
workflow guide context, preserve verbatim UTF-8 notices and keep code/peer/path
|
|
9
|
+
boundaries. Verify drafts, dry runs, publication, reads and rejection atomically.
|
|
10
|
+
- Add generic skill examples for preserving reference baselines and intended
|
|
11
|
+
public APIs while resolving coverage diagnostics; verify conditional controls
|
|
12
|
+
through browser state transitions instead of screenshots alone.
|
|
13
|
+
|
|
3
14
|
## 0.3.11
|
|
4
15
|
|
|
5
16
|
- Bind preview success to project input content as well as artifact bytes. Source
|
package/docs/MCP.md
CHANGED
|
@@ -294,10 +294,23 @@ The same discovery covers the rest of the project ADS:
|
|
|
294
294
|
| Unit | Scope |
|
|
295
295
|
|------|-------|
|
|
296
296
|
| `foundation` | Shared ADS entry styles and root helpers |
|
|
297
|
-
| `documentation` | ADS guides
|
|
297
|
+
| `documentation` | ADS/project guides, shared credits and license notices, and `licenses/` text collections |
|
|
298
298
|
| `assets/brand`, `assets/fonts`, other `assets/*` groups | Original SVG, image, font and other asset files |
|
|
299
299
|
| `configuration` | `ds.config.json`, package/TypeScript/bundler/lint configuration, registered ADS guard modules, compiler/check entrypoints and their static local dependencies |
|
|
300
300
|
|
|
301
|
+
The `documentation` manifest includes `filePolicy` for paths that can be created
|
|
302
|
+
before they exist. One documentation patch can add `CREDITS.md`,
|
|
303
|
+
`licenses/example.txt` and the required README links together. Conventional root
|
|
304
|
+
`LICENSE`/`LICENCE`, `NOTICE`, `COPYING`, `COPYRIGHT` and `CREDITS` notices accept
|
|
305
|
+
`.md`, `.txt`, or extensionless names, with optional `-`/`_` qualifiers. Shared
|
|
306
|
+
`licenses/` collections may also live under `docs/`, `doc/`, or the configured ADS
|
|
307
|
+
root. Their entries use `.md`/`.txt` or conventional extensionless notice names.
|
|
308
|
+
Content must be UTF-8 without NUL bytes; Git patches preserve exact text, Unicode,
|
|
309
|
+
line endings and final-newline state. Code/configuration, hidden/generated paths
|
|
310
|
+
and peer-owned files retain their boundaries. A component's colocated notice stays
|
|
311
|
+
in that component unit. Shared notices are listed as readable MCP resources, while
|
|
312
|
+
workflow guide discovery omits provenance inventories. No asset unit is needed.
|
|
313
|
+
|
|
301
314
|
Configuration ownership follows the project's registrations. It does not absorb
|
|
302
315
|
components merely because a guard or compiler reads them. Guard registration,
|
|
303
316
|
implementation, helpers and the associated check script can change together.
|