@astryxdesign/cli 0.7.2-canary.e26723d → 0.7.2-canary.e4bdd70
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 +9 -8
- package/api/docs/_adapter.d.mts +11 -0
- package/api/docs/_adapter.mjs +37 -0
- package/api/index.d.mts +2 -0
- package/api/index.mjs +2 -0
- package/api/integration/add-contribution.mjs +1 -1
- package/api/integration/add-contribution.test.mjs +4 -2
- package/api/integration/check/check.d.mts +96 -0
- package/api/integration/check/check.mjs +357 -0
- package/api/integration/check/check.test.mjs +489 -0
- package/api/integration/integration-check.type.d.mts +118 -0
- package/api/integration/integration-check.type.mjs +84 -0
- package/api/integration/integrationCheck.doc.d.mts +10 -0
- package/api/integration/integrationCheck.doc.mjs +73 -0
- package/api/integration/integrationComponentConflicts.doc.mjs +19 -4
- package/api/integration/validate-integration.mjs +8 -0
- package/api/integration/validate-integration.type.d.mts +8 -0
- package/api/integration/validate-integration.type.mjs +12 -1
- package/api/integration/validateIntegration.doc.mjs +17 -3
- package/api/search/search.d.mts +13 -6
- package/api/search/search.domain-priority.test.mjs +93 -18
- package/api/search/search.integration-check.test.mjs +24 -0
- package/api/search/search.mjs +33 -9
- package/api/theme/build/build.family.test.mjs +54 -6
- package/api/theme/build/build.mjs +110 -13
- package/api/theme/themeBuild.doc.mjs +4 -4
- package/assets/docs/styling-overview.doc.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +1 -1
- package/assets/docs/tree/add-a-theme.doc.mjs +1 -1
- package/assets/docs/tree/add-a-topic.doc.mjs +10 -7
- package/assets/docs/tree/agent-guidance.doc.mjs +2 -2
- package/assets/docs/tree/block-template.doc.mjs +8 -20
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/check-the-props.doc.mjs +51 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +51 -5
- package/assets/docs/tree/checks.doc.mjs +21 -13
- package/assets/docs/tree/codemods.doc.mjs +4 -4
- package/assets/docs/tree/component-family.doc.mjs +3 -5
- package/assets/docs/tree/component-imports.doc.mjs +2 -2
- package/assets/docs/tree/components.doc.mjs +1 -1
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +7 -18
- package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
- package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
- package/assets/docs/tree/docs.doc.mjs +3 -3
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +1 -1
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +6 -6
- package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
- package/assets/docs/tree/generate-a-palette.doc.mjs +5 -3
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +1 -1
- package/assets/docs/tree/integrations.doc.mjs +8 -0
- package/assets/docs/tree/links.doc.mjs +5 -4
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +4 -8
- package/assets/docs/tree/publishing.doc.mjs +1 -1
- package/assets/docs/tree/quick-start.doc.mjs +37 -21
- package/assets/docs/tree/replace-a-core-component.doc.mjs +4 -6
- package/assets/docs/tree/replace-a-core-template.doc.mjs +6 -8
- package/assets/docs/tree/sections-and-placement.doc.mjs +4 -6
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +4 -2
- package/assets/docs/tree/short-and-findable.doc.mjs +6 -5
- package/assets/docs/tree/single-component.doc.mjs +12 -4
- package/assets/docs/tree/start-a-template.doc.mjs +3 -3
- package/assets/docs/tree/subcomponent.doc.mjs +6 -6
- package/assets/docs/tree/template-assets.doc.mjs +2 -2
- package/assets/docs/tree/template-doc-overview.doc.mjs +4 -15
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-icons.doc.mjs +1 -1
- package/assets/docs/tree/template-images-media.doc.mjs +1 -1
- package/assets/docs/tree/template-styles.doc.mjs +2 -2
- package/assets/docs/tree/templates.doc.mjs +1 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +3 -3
- package/assets/docs/tree/test-template-in-app.doc.mjs +1 -1
- package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
- package/assets/docs/tree/troubleshooting.doc.mjs +4 -4
- package/assets/docs/tree/upgrading.doc.mjs +3 -3
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +3 -1
- package/assets/docs/tree/verify-packed-template.doc.mjs +1 -1
- package/assets/docs/tree/versioning.doc.mjs +6 -6
- package/assets/docs/tree/write-the-template-file.doc.mjs +2 -2
- package/authoring/codemod/codemod.doc.mjs +7 -3
- package/authoring/config/config.doc.mjs +9 -6
- package/authoring/config/type.ts +4 -2
- package/authoring/discover/discover.doc.mjs +1 -1
- package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
- package/authoring/doctypes/command/command.doc.mjs +14 -12
- package/authoring/doctypes/component/component.doc.mjs +28 -25
- package/authoring/doctypes/component/type.ts +7 -5
- package/authoring/doctypes/enum/enum.doc.mjs +7 -4
- package/authoring/doctypes/function/function.doc.mjs +9 -8
- package/authoring/doctypes/hook/hook.doc.mjs +5 -4
- package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
- package/authoring/doctypes/reference/reference.doc.mjs +11 -10
- package/authoring/doctypes/schema/schema.doc.mjs +9 -9
- package/authoring/doctypes/template/integration-template.doc.mjs +1 -1
- package/authoring/doctypes/template/template.doc.mjs +3 -3
- package/authoring/doctypes/theme/theme.doc.mjs +2 -2
- package/authoring/gap-report/gap-report.doc.mjs +2 -2
- package/authoring/identity/identity.doc.mjs +3 -3
- package/authoring/integration/integration.doc.mjs +4 -3
- package/clients/cli/commands/build-theme.path-safety.test.mjs +155 -21
- package/clients/cli/commands/doctor-integration-components.doc.mjs +8 -3
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +11 -2
- package/clients/cli/commands/doctor-integration.test.mjs +447 -2
- package/clients/cli/commands/doctor.mjs +116 -0
- package/clients/cli/commands/integration-check.doc.mjs +85 -0
- package/clients/cli/commands/integration-check.test.mjs +267 -0
- package/clients/cli/commands/integration.doc.mjs +6 -2
- package/clients/cli/commands/integration.mjs +107 -1
- package/clients/cli/commands/text-json-parity.test.mjs +5 -0
- package/clients/cli/commands/theme-build.doc.mjs +2 -2
- package/clients/cli/index.mjs +1 -0
- package/foundation/discovery/authoring-self-docs.mjs +1 -1
- package/foundation/discovery/doc-types.mjs +2 -2
- package/foundation/discovery/integration-doc-files.d.mts +22 -0
- package/foundation/discovery/integration-doc-files.mjs +231 -0
- package/foundation/discovery/integration-doc-files.test.mjs +246 -0
- package/foundation/discovery/prop-drift.d.mts +61 -3
- package/foundation/discovery/prop-drift.mjs +559 -61
- package/foundation/discovery/prop-drift.test.mjs +1032 -10
- package/foundation/doc-compiler/doc-loads.test.mjs +2 -0
- package/foundation/response/response-types.doc.mjs +7 -2
- package/package.json +9 -9
|
@@ -27,8 +27,10 @@
|
|
|
27
27
|
* files; an internal callback lets the CLI make only the process status fail.
|
|
28
28
|
* Human progress is emitted through the shared `logger` (silent by default), so
|
|
29
29
|
* the CLI keeps its exact output while a programmatic caller stays quiet.
|
|
30
|
-
* Every output, explicit or beside the theme file, stays inside
|
|
31
|
-
* (`ERR_PATH_TRAVERSAL` otherwise)
|
|
30
|
+
* Every output a build writes, explicit or beside the theme file, stays inside
|
|
31
|
+
* `cwd` (`ERR_PATH_TRAVERSAL` otherwise). Check mode writes nothing, so it
|
|
32
|
+
* compares outputs outside `cwd` read-only; only a relative `out` path that
|
|
33
|
+
* escapes `cwd` is refused there too.
|
|
32
34
|
*
|
|
33
35
|
* The installed `@astryxdesign/core` is an independently versioned optional
|
|
34
36
|
* peer, so it can be older than the CLI. A theme that uses only baseline
|
|
@@ -60,7 +62,10 @@ import {isBuiltin} from 'node:module';
|
|
|
60
62
|
import {fileURLToPath, pathToFileURL} from 'node:url';
|
|
61
63
|
import {parse} from '@babel/parser';
|
|
62
64
|
import {createJiti} from 'jiti';
|
|
63
|
-
import {
|
|
65
|
+
import {
|
|
66
|
+
formatCliCommand,
|
|
67
|
+
getCliInvocation,
|
|
68
|
+
} from '../../../foundation/env/package-manager.mjs';
|
|
64
69
|
import {
|
|
65
70
|
CLI_ROOT,
|
|
66
71
|
findCoreDir,
|
|
@@ -568,6 +573,86 @@ function confineOutputs(writes, root, remedy) {
|
|
|
568
573
|
for (const write of writes) confineOutput(write.dest, root, remedy);
|
|
569
574
|
}
|
|
570
575
|
|
|
576
|
+
/** @param {string} dest absolute output path @param {string} root @returns {boolean} whether a build at `root` refuses to write `dest` */
|
|
577
|
+
function refusedOutput(dest, root) {
|
|
578
|
+
try {
|
|
579
|
+
confineOutput(dest, root, '');
|
|
580
|
+
return false;
|
|
581
|
+
} catch (err) {
|
|
582
|
+
if (
|
|
583
|
+
err instanceof AstryxError &&
|
|
584
|
+
err.code === ERROR_CODES.ERR_PATH_TRAVERSAL
|
|
585
|
+
)
|
|
586
|
+
return true;
|
|
587
|
+
throw err;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/** @param {string[]} dirs absolute directories @returns {string | null} the deepest directory containing all of them, or null across roots */
|
|
592
|
+
function commonDirectory(dirs) {
|
|
593
|
+
let common = dirs[0];
|
|
594
|
+
for (const dir of dirs.slice(1)) {
|
|
595
|
+
while (
|
|
596
|
+
path.relative(common, dir).startsWith('..') ||
|
|
597
|
+
path.isAbsolute(path.relative(common, dir))
|
|
598
|
+
) {
|
|
599
|
+
const parent = path.dirname(common);
|
|
600
|
+
if (parent === common) return null;
|
|
601
|
+
common = parent;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return common;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/** @param {string} value @returns {string} `value` as one shell word */
|
|
608
|
+
function shellWord(value) {
|
|
609
|
+
if (/^[A-Za-z0-9@%+=:,./_-]+$/.test(value)) return value;
|
|
610
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* How a stale check report ends when outputs sit outside the write root. A
|
|
615
|
+
* build there refuses them, and each output's `Source:` header records the
|
|
616
|
+
* directory its build ran from, so the build and the check both run from the
|
|
617
|
+
* nearest directory that contains every theme file and output.
|
|
618
|
+
* @param {Array<{dest: string}>} writes
|
|
619
|
+
* @param {string[]} sources absolute theme files the build reads
|
|
620
|
+
* @param {string} root the directory a build here keeps its writes inside
|
|
621
|
+
* @param {(relative: (file: string) => string) => string[]} args the arguments after `theme build`, given each path relative to the directory to run from
|
|
622
|
+
* @returns {string[] | null} report lines, or null when every output is inside `root`
|
|
623
|
+
*/
|
|
624
|
+
function outsideCheckRemedy(writes, sources, root, args) {
|
|
625
|
+
if (!writes.some(write => refusedOutput(write.dest, root))) return null;
|
|
626
|
+
const real = (/** @type {string} */ file) => realLocation(path.resolve(file));
|
|
627
|
+
const dir = commonDirectory([
|
|
628
|
+
...sources.map(file => path.dirname(real(file))),
|
|
629
|
+
...writes.map(write => path.dirname(real(write.dest))),
|
|
630
|
+
]);
|
|
631
|
+
if (!dir) {
|
|
632
|
+
return [
|
|
633
|
+
'These outputs are outside the working directory, so a build here refuses them. Build and check them from one directory that contains the theme files and the outputs.',
|
|
634
|
+
];
|
|
635
|
+
}
|
|
636
|
+
const command = (/** @type {string[]} */ extra) =>
|
|
637
|
+
formatCliCommand(
|
|
638
|
+
[
|
|
639
|
+
'theme',
|
|
640
|
+
'build',
|
|
641
|
+
...args(file => path.relative(dir, real(file))),
|
|
642
|
+
...extra,
|
|
643
|
+
]
|
|
644
|
+
.map(shellWord)
|
|
645
|
+
.join(' '),
|
|
646
|
+
dir,
|
|
647
|
+
);
|
|
648
|
+
return [
|
|
649
|
+
'These outputs are outside the working directory, so a build here refuses them, and each output records the directory it was built from. Build and check them from a directory that contains them:',
|
|
650
|
+
` cd ${shellWord(dir)}`,
|
|
651
|
+
` ${command([])}`,
|
|
652
|
+
` ${command(['--check'])}`,
|
|
653
|
+
];
|
|
654
|
+
}
|
|
655
|
+
|
|
571
656
|
/** @param {Array<{dest: string, content: string}>} writes */
|
|
572
657
|
function writeBuildOutputs(writes) {
|
|
573
658
|
if (writes.length === 0) return;
|
|
@@ -2859,9 +2944,13 @@ async function themeBuildInternal(
|
|
|
2859
2944
|
const writeRoot = options.__writeRoot ?? cwd;
|
|
2860
2945
|
let outPath;
|
|
2861
2946
|
if (options.out) {
|
|
2862
|
-
// Relative or absolute, the explicit output stays inside the write root.
|
|
2863
2947
|
outPath = path.resolve(cwd, options.out);
|
|
2864
|
-
|
|
2948
|
+
// A build keeps the explicit output inside the write root, relative or
|
|
2949
|
+
// absolute. Check mode writes nothing, so it refuses only a relative path
|
|
2950
|
+
// that escapes cwd.
|
|
2951
|
+
if (!options.check || !path.isAbsolute(options.out)) {
|
|
2952
|
+
confineOutput(outPath, writeRoot, OUT_REMEDY, options.out);
|
|
2953
|
+
}
|
|
2865
2954
|
} else {
|
|
2866
2955
|
outPath = path.join(path.dirname(filePath), `${baseName}.css`);
|
|
2867
2956
|
}
|
|
@@ -2957,10 +3046,12 @@ async function themeBuildInternal(
|
|
|
2957
3046
|
writes.push({dest: variantDtsPath, content: variantContent});
|
|
2958
3047
|
}
|
|
2959
3048
|
|
|
2960
|
-
// Every output stays inside cwd, including the defaults
|
|
2961
|
-
// file. Check mode
|
|
2962
|
-
//
|
|
2963
|
-
|
|
3049
|
+
// Every output a build writes stays inside cwd, including the defaults
|
|
3050
|
+
// beside the theme file. Check mode writes nothing, so it compares outputs
|
|
3051
|
+
// outside cwd read-only.
|
|
3052
|
+
if (!options.check) {
|
|
3053
|
+
confineOutputs(writes, writeRoot, options.out ? OUT_REMEDY : SOURCE_REMEDY);
|
|
3054
|
+
}
|
|
2964
3055
|
|
|
2965
3056
|
// Check mode: compare generated content against what's on disk instead of
|
|
2966
3057
|
// writing. A file is "stale" if it's missing or its content differs once the
|
|
@@ -2980,7 +3071,10 @@ async function themeBuildInternal(
|
|
|
2980
3071
|
` ${s.reason === 'missing' ? 'missing' : 'stale'}: ${s.path}`,
|
|
2981
3072
|
);
|
|
2982
3073
|
}
|
|
2983
|
-
|
|
3074
|
+
// prettier-ignore
|
|
3075
|
+
const remedy = outsideCheckRemedy(writes, [filePath], writeRoot, relative => [relative(filePath), ...(options.out ? ['--out', relative(outPath)] : []), ...(options.iconsSpecifier ? ['--icons-specifier', options.iconsSpecifier] : [])]);
|
|
3076
|
+
if (remedy) logger.error(`\n ${remedy.join('\n ')}`);
|
|
3077
|
+
else logger.error(`\n Rebuild with: ${buildCommand}`);
|
|
2984
3078
|
}
|
|
2985
3079
|
return {
|
|
2986
3080
|
type: 'theme.build.check',
|
|
@@ -3506,8 +3600,8 @@ export async function themeBuildFamily(
|
|
|
3506
3600
|
js: path.relative(cwd, jsPath),
|
|
3507
3601
|
dts: path.relative(cwd, dtsPath),
|
|
3508
3602
|
};
|
|
3509
|
-
//
|
|
3510
|
-
confineOutputs(writes, cwd, FAMILY_REMEDY);
|
|
3603
|
+
// A family build's outputs stay inside cwd too; check mode only reads them.
|
|
3604
|
+
if (!options.check) confineOutputs(writes, cwd, FAMILY_REMEDY);
|
|
3511
3605
|
if (options.check) {
|
|
3512
3606
|
const stale = staleBuildOutputs(writes, cwd);
|
|
3513
3607
|
const upToDate = stale.length === 0;
|
|
@@ -3524,7 +3618,10 @@ export async function themeBuildFamily(
|
|
|
3524
3618
|
` ${entry.reason === 'missing' ? 'missing' : 'stale'}: ${entry.path}`,
|
|
3525
3619
|
);
|
|
3526
3620
|
}
|
|
3527
|
-
|
|
3621
|
+
// prettier-ignore
|
|
3622
|
+
const remedy = outsideCheckRemedy(writes, members.map(member => member.filePath), cwd, relative => ['--family', ...members.map(member => relative(member.filePath)), '--family-key', baseName, ...(options.iconsSpecifier ? ['--icons-specifier', options.iconsSpecifier] : [])]);
|
|
3623
|
+
if (remedy) logger.error(`\n ${remedy.join('\n ')}`);
|
|
3624
|
+
else logger.error(`\n Rebuild with: ${buildCommand}`);
|
|
3528
3625
|
}
|
|
3529
3626
|
return {
|
|
3530
3627
|
type: 'theme.build.check',
|
|
@@ -58,13 +58,13 @@ export const doc = {
|
|
|
58
58
|
name: 'options.out',
|
|
59
59
|
type: 'string',
|
|
60
60
|
description:
|
|
61
|
-
'Override the output CSS path, relative or absolute;
|
|
61
|
+
'Override the output CSS path, relative or absolute; a build refuses a path outside cwd, and check mode refuses only a relative path that escapes cwd. The .js, .d.ts and any .variants.d.ts are written in the same directory, named after the theme (<name>.js), not after the CSS file.',
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
name: 'options.check',
|
|
65
65
|
type: 'boolean',
|
|
66
66
|
description:
|
|
67
|
-
'Compile in memory and compare each output against what is on disk instead of writing: the CI drift guard.',
|
|
67
|
+
'Compile in memory and compare each output against what is on disk instead of writing: the CI drift guard. Because it writes nothing, it also compares outputs outside cwd; when those are stale, the report names the directory that contains them and the build and check commands to run from there, since a build refuses them and each output records the directory it was built from.',
|
|
68
68
|
default: 'false',
|
|
69
69
|
},
|
|
70
70
|
{
|
|
@@ -77,7 +77,7 @@ export const doc = {
|
|
|
77
77
|
name: 'ctx.cwd',
|
|
78
78
|
type: 'string',
|
|
79
79
|
description:
|
|
80
|
-
'Directory the theme file, a relative out path, and the returned output paths resolve against. Every output is
|
|
80
|
+
'Directory the theme file, a relative out path, and the returned output paths resolve against. Every output a build writes is inside it, including the default outputs beside the theme file.',
|
|
81
81
|
default: 'process.cwd()',
|
|
82
82
|
},
|
|
83
83
|
],
|
|
@@ -105,7 +105,7 @@ export const doc = {
|
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
code: 'ERR_PATH_TRAVERSAL',
|
|
108
|
-
when: 'the theme name contains a path separator or traversal marker, or
|
|
108
|
+
when: 'the theme name contains a path separator or traversal marker, or a written output resolves outside cwd (including through a symlink): an `out` path, relative or absolute, or the default outputs beside a theme file outside cwd. Check mode writes nothing, so it refuses only a relative `out` path that escapes cwd',
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
111
|
code: 'ERR_CORE_NOT_FOUND',
|
|
@@ -158,7 +158,7 @@ export const docs = {
|
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
160
|
type: 'prose',
|
|
161
|
-
text:
|
|
161
|
+
text: "If importing a swizzled component throws an error that starts `Unexpected 'stylex.create' call at runtime` and the page does not render, the app is missing a StyleX compiler. See the StyleX Build Setup section of {@link generic:tokens-and-setup} for bundler config examples.",
|
|
162
162
|
},
|
|
163
163
|
],
|
|
164
164
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx docs cli/integrations/components/add-a-component`: choose a
|
|
4
|
+
* @file `astryx docs cli/integrations/building-blocks/components/add-a-component`: choose a
|
|
5
5
|
* component name and generate its first source and doc files.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -44,7 +44,7 @@ Declare theme root ./themes in astryx.integration.mjs.
|
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
type: 'prose',
|
|
47
|
-
text:
|
|
47
|
+
text: '`oceanTheme.ts` exports `oceanTheme`, a `defineTheme` source, and `oceanTheme.doc.mjs` is the descriptor that `theme list` reads. The command also declares `./themes/ocean` and `./themes/ocean.css` package exports. Every field is in {@link schema:theme-doc}.',
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
type: 'prose',
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx docs cli/integrations/docs/add-a-topic`: add a
|
|
5
|
-
* integration package, write its sections, and pick the doc
|
|
6
|
-
* thing the package ships.
|
|
4
|
+
* @file `astryx docs cli/integrations/building-blocks/docs/add-a-topic`: add a
|
|
5
|
+
* doc topic to an integration package, write its sections, and pick the doc
|
|
6
|
+
* kind for each thing the package ships.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
|
|
@@ -40,7 +40,7 @@ export const docs = {
|
|
|
40
40
|
items: [
|
|
41
41
|
'Name the topic in lowercase kebab-case, such as `deploying`. Readers type the name as a command argument, so it holds only letters, digits, `_`, and `-`.',
|
|
42
42
|
'Keep the name stable: readers and links find the topic by it.',
|
|
43
|
-
'Pick a name no Core topic
|
|
43
|
+
'Pick a name that `astryx docs` does not already list: no Core topic, and no section such as `tokens` or `layout`. To take over or add to a Core topic, see {@link generic:extend-or-replace}.',
|
|
44
44
|
],
|
|
45
45
|
},
|
|
46
46
|
],
|
|
@@ -59,13 +59,16 @@ export const docs = {
|
|
|
59
59
|
label: 'docs/deploying.doc.mjs',
|
|
60
60
|
code: "/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */\nexport default {\n type: 'generic',\n name: 'deploying',\n title: 'Deploying',\n description: 'Ship an app built with Acme widgets.',\n sections: [{\n id: 'build-before-you-ship',\n title: 'Build before you ship',\n content: [\n {type: 'prose', text: 'Build the app, then upload the `dist` folder.'},\n {type: 'code', lang: 'bash', code: 'npm run build'},\n {type: 'list', style: 'unordered', items: ['Keep `dist` out of git.']},\n {type: 'table', headers: ['Variable', 'Value'], rows: [['`NODE_ENV`', '`production`']]},\n ],\n }],\n};",
|
|
61
61
|
},
|
|
62
|
+
{
|
|
63
|
+
type: 'prose',
|
|
64
|
+
text: 'The sample sets a section `id`, so `package.json` needs the CLI peer `"@astryxdesign/cli": ">=0.6.4"`. Published 0.6.3 and earlier reject `id` and hide every doc topic your package ships, and `integration verify` fails without that peer; see {@link generic:versioning}.',
|
|
65
|
+
},
|
|
62
66
|
{
|
|
63
67
|
type: 'list',
|
|
64
68
|
style: 'unordered',
|
|
65
69
|
items: [
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'Replace the `Overview` placeholder that `integration add` writes. Every field is in {@link generic:authoring}.',
|
|
70
|
+
'Replace the `Overview` placeholder that `integration add` writes.',
|
|
71
|
+
'Every field is in {@link schema:reference-doc}.',
|
|
69
72
|
],
|
|
70
73
|
},
|
|
71
74
|
],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx docs cli/integrations/agent-guidance`: add short lines of
|
|
4
|
+
* @file `astryx docs cli/integrations/building-blocks/configuration/agent-guidance`: add short lines of
|
|
5
5
|
* guidance that apps put in front of their AI agents, within the limits.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -121,7 +121,7 @@ export default {
|
|
|
121
121
|
lang: 'bash',
|
|
122
122
|
code: `npx astryx init --features agents
|
|
123
123
|
# Or: --from takes the Core version the app had before
|
|
124
|
-
npx astryx upgrade --from
|
|
124
|
+
npx astryx upgrade --from <version> --apply`,
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
type: 'code',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx docs cli/integrations/templates/document-the-template/block-template`:
|
|
4
|
+
* @file `astryx docs cli/integrations/building-blocks/templates/document-the-template/block-template`:
|
|
5
5
|
* the block-only fields: component relationships and the preview shape.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -31,7 +31,7 @@ export const docs = {
|
|
|
31
31
|
type: 'code',
|
|
32
32
|
lang: 'javascript',
|
|
33
33
|
label: 'templates/acme-stat-card.doc.mjs',
|
|
34
|
-
code: `/** @type {import('@astryxdesign/cli/authoring').
|
|
34
|
+
code: `/** @type {import('@astryxdesign/cli/authoring').IntegrationTemplateDoc} */
|
|
35
35
|
export default {
|
|
36
36
|
type: 'block',
|
|
37
37
|
name: 'acme-stat-card',
|
|
@@ -54,18 +54,8 @@ export default {
|
|
|
54
54
|
title: 'Choose the component relationship',
|
|
55
55
|
content: [
|
|
56
56
|
{
|
|
57
|
-
type: '
|
|
58
|
-
|
|
59
|
-
projection: {
|
|
60
|
-
fields: [
|
|
61
|
-
'exampleFor',
|
|
62
|
-
'alsoExampleFor',
|
|
63
|
-
'alsoShowcaseFor',
|
|
64
|
-
'componentsUsed',
|
|
65
|
-
'isShowcase',
|
|
66
|
-
],
|
|
67
|
-
},
|
|
68
|
-
presentation: 'full',
|
|
57
|
+
type: 'prose',
|
|
58
|
+
text: 'Every field is in {@link schema:template-doc}.',
|
|
69
59
|
},
|
|
70
60
|
{
|
|
71
61
|
type: 'prose',
|
|
@@ -75,7 +65,7 @@ export default {
|
|
|
75
65
|
type: 'code',
|
|
76
66
|
lang: 'javascript',
|
|
77
67
|
label: 'templates/acme-status-card-showcase.doc.mjs',
|
|
78
|
-
code: `/** @type {import('@astryxdesign/cli/authoring').
|
|
68
|
+
code: `/** @type {import('@astryxdesign/cli/authoring').IntegrationTemplateDoc} */
|
|
79
69
|
export default {
|
|
80
70
|
type: 'block',
|
|
81
71
|
name: 'acme-status-card-showcase',
|
|
@@ -101,14 +91,12 @@ export default {
|
|
|
101
91
|
title: 'Choose a useful preview',
|
|
102
92
|
content: [
|
|
103
93
|
{
|
|
104
|
-
type: '
|
|
105
|
-
|
|
106
|
-
projection: {fields: ['aspectRatio']},
|
|
107
|
-
presentation: 'full',
|
|
94
|
+
type: 'prose',
|
|
95
|
+
text: 'Every field is in {@link schema:template-doc}.',
|
|
108
96
|
},
|
|
109
97
|
{
|
|
110
98
|
type: 'prose',
|
|
111
|
-
text: '
|
|
99
|
+
text: 'Set `aspectRatio` from the value for the closest shape below, render the block at that ratio, and adjust it until it neither clips nor leaves large empty space. These are starting points, not contract defaults.',
|
|
112
100
|
},
|
|
113
101
|
{
|
|
114
102
|
type: 'table',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx docs cli/integrations/templates/build-the-template`:
|
|
4
|
+
* @file `astryx docs cli/integrations/building-blocks/templates/build-the-template`:
|
|
5
5
|
* author portable template source and every asset that source needs.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -91,8 +91,59 @@ docType: boolean
|
|
|
91
91
|
'`required` disagrees with the code',
|
|
92
92
|
'Set `required: true` exactly when every caller must pass the prop. One your `defaultProps` fills counts as optional, as it is to JSX callers, and so does one only some members of a union require, since a caller can leave it out: say in its description which variants need it. An entry that names several props (`value / onChange`) makes the same claim about each: give them separate entries when they differ',
|
|
93
93
|
],
|
|
94
|
+
[
|
|
95
|
+
'`type_mismatch`',
|
|
96
|
+
"The documented `type` differs from the code's, where both read exactly",
|
|
97
|
+
'Copy the type from the source, or fix the code. The next section says which types are judged',
|
|
98
|
+
],
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'write-types-the-check-can-judge',
|
|
105
|
+
title: 'Write types the check can judge',
|
|
106
|
+
content: [
|
|
107
|
+
{
|
|
108
|
+
type: 'prose',
|
|
109
|
+
text: 'For a prop your package declares, the check also compares the documented `type`, but only where both sides read exactly. It never guesses, so a type it cannot judge is listed, not reported. It needs TypeScript 4.8 or later: with an older one it prints `[skip] Prop types not judged` and judges none.',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: 'code',
|
|
113
|
+
lang: 'text',
|
|
114
|
+
code: `severity: [warn]
|
|
115
|
+
component: AcmeCarousel
|
|
116
|
+
prop: interval
|
|
117
|
+
kind: type_mismatch
|
|
118
|
+
message: "interval" is documented as string, but the code declares number.
|
|
119
|
+
doc: components/AcmeCarousel.doc.mjs
|
|
120
|
+
source: components/AcmeCarousel.tsx
|
|
121
|
+
docType: string
|
|
122
|
+
codeType: number`,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: 'list',
|
|
126
|
+
style: 'unordered',
|
|
127
|
+
items: [
|
|
128
|
+
"Write the type as the source writes it, such as `ReactNode[]` or `(index: number) => void`. Parameter names, member order, quotes and whitespace may differ. Text that writes `readonly` must match exactly, parameter names included; only whitespace may differ. `React.X` names React's own `X` where the prop is declared, so it matches a bare `X` only where that name is React's: `React.KeyboardEvent` is not the DOM's `KeyboardEvent`.",
|
|
129
|
+
"Name a type as the file that declares the prop names it, so an import renamed there (`Item as BaseItem`) is written as that file writes it. A field (`cfg.level`) takes its prop's file, even when the field's own type is declared in another file.",
|
|
130
|
+
'A type written another way is judged only when both sides are built from exact parts: primitives such as `string` and `number`, string, number and boolean literals, string enum members, arrays and unions of these, and type names that stand for them. Union members may come in any order, and a member another covers adds nothing, as TypeScript passes it there: `undefined` beside `void`, or `string[]` beside `(string | number)[]`.',
|
|
131
|
+
'A mutable array type matches a readonly one, because callers can pass it. A readonly one documented for a mutable array is a mismatch.',
|
|
132
|
+
"When a prop's variants give a field different types, as `{value: string} | {value: number}` does, document every variant's type (`string | number`). The types of only some variants are listed: the prop's variants give this field different types. With more than six variant types, any other type is listed too.",
|
|
133
|
+
"To name an alias and show its values, write `AcmeSize = 'sm' | 'md'` or `AcmeSize ('sm' | 'md')`. Both parts must match.",
|
|
134
|
+
"An optional prop's `undefined` is set aside on both sides. With `exactOptionalPropertyTypes`, the doc shows `undefined` exactly when the code declares it.",
|
|
135
|
+
'Anything else, such as an object, a tuple, a generic with arguments, `keyof`, an intersection, or a mapped or conditional type written another way, is not compared.',
|
|
94
136
|
],
|
|
95
137
|
},
|
|
138
|
+
{
|
|
139
|
+
type: 'prose',
|
|
140
|
+
text: "The check prints how many documented types it judged, then lists the rest by reason: not a form the check judges exactly, a field the prop's variants give different types, a standard prop, or a prop declared outside the package. With `--json`, they are in `data.propDrift.typesNotCompared`.",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: 'code',
|
|
144
|
+
lang: 'text',
|
|
145
|
+
code: '[info] Documented prop types judged: 2; not compared: 0. A type is judged when the doc writes it the same as the source (exactly, if it contains `readonly`), or when both are primitives, literals, arrays and unions of those, or names for them.',
|
|
146
|
+
},
|
|
96
147
|
],
|
|
97
148
|
},
|
|
98
149
|
{
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx docs cli/integrations/docs/check-your-docs`:
|
|
5
|
-
* proves about an integration's docs: the docs check,
|
|
6
|
-
* CLI peer.
|
|
4
|
+
* @file `astryx docs cli/integrations/building-blocks/docs/check-your-docs`:
|
|
5
|
+
* what each check proves about an integration's docs: the docs check, each
|
|
6
|
+
* doc's fields, the read size, and the CLI peer.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
|
|
@@ -13,7 +13,8 @@ export const docs = {
|
|
|
13
13
|
placement: {parent: 'namespace:docs', slot: 'guides', order: 60},
|
|
14
14
|
title: 'Check your docs',
|
|
15
15
|
category: 'guide',
|
|
16
|
-
description:
|
|
16
|
+
description:
|
|
17
|
+
'Check the docs tree, links, overlaps, doc fields, read size, and CLI peer.',
|
|
17
18
|
sections: [
|
|
18
19
|
{
|
|
19
20
|
id: 'run-the-docs-check',
|
|
@@ -45,7 +46,7 @@ export const docs = {
|
|
|
45
46
|
content: [
|
|
46
47
|
{
|
|
47
48
|
type: 'prose',
|
|
48
|
-
text: 'A doc that does not load, an accidental Core overlap, or a failed namespace or placement fails the check with exit code 1. A link that names no doc only warns, and the exit code stays 0.',
|
|
49
|
+
text: 'A doc that does not load, an accidental Core overlap, a `reference` block that names no doc, or a failed namespace or placement fails the check with exit code 1. A link that names no doc only warns, and the exit code stays 0.',
|
|
49
50
|
},
|
|
50
51
|
{
|
|
51
52
|
type: 'table',
|
|
@@ -66,6 +67,11 @@ export const docs = {
|
|
|
66
67
|
'`[fail]` `invalid_doc_graph`',
|
|
67
68
|
'1',
|
|
68
69
|
],
|
|
70
|
+
[
|
|
71
|
+
'A `reference` block whose target names no doc',
|
|
72
|
+
'`[fail]` `invalid_doc_reference`',
|
|
73
|
+
'1',
|
|
74
|
+
],
|
|
69
75
|
['A link that names no doc', '`[warn]` `invalid_doc_graph`', '0'],
|
|
70
76
|
[
|
|
71
77
|
'A topic that sets `replaces` or `extends`',
|
|
@@ -80,6 +86,46 @@ export const docs = {
|
|
|
80
86
|
},
|
|
81
87
|
],
|
|
82
88
|
},
|
|
89
|
+
{
|
|
90
|
+
id: 'check-each-doc-against-its-type',
|
|
91
|
+
title: 'Check each doc against its type',
|
|
92
|
+
content: [
|
|
93
|
+
{
|
|
94
|
+
type: 'prose',
|
|
95
|
+
text: "`doctor integration validate` reads every doc your package ships against the type `@astryxdesign/cli/authoring` publishes for its kind, the way `tsc` would: a `hidden` doc and a second doc for one name too. Test fixtures under `__tests__` in the components or docs root, which those readers skip, are counted, not checked. It reports a field the type does not have (`unknown_field`), a missing required field (`missing_field`), and a value outside the field's type (`wrong_type`).",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
type: 'code',
|
|
99
|
+
lang: 'bash',
|
|
100
|
+
code: 'npx astryx doctor integration validate',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: 'code',
|
|
104
|
+
lang: 'text',
|
|
105
|
+
code: `Checking 1 doc(s) against the authoring types (TypeScript 6.0.3)
|
|
106
|
+
|
|
107
|
+
severity: [warn]
|
|
108
|
+
doc: components/AcmeCarousel.doc.mjs
|
|
109
|
+
line: 7
|
|
110
|
+
export: default
|
|
111
|
+
type: ComponentDoc
|
|
112
|
+
field: summary
|
|
113
|
+
problem: unknown_field
|
|
114
|
+
message: Object literal may only specify known properties, and 'summary' does not exist in type 'SingleComponentDoc'.
|
|
115
|
+
fix: Remove \`summary\`: SingleComponentDoc has no field \`summary\`.`,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
type: 'list',
|
|
119
|
+
style: 'unordered',
|
|
120
|
+
items: [
|
|
121
|
+
"The folder decides the type: `ComponentDoc` in your components root, `IntegrationTemplateDoc` in your templates root, `ThemeDoc` in your themes root, and in your docs root the type the doc's `type` names. Keep the `@type` comment above each doc's export too, so your editor shows the same problems as you type.",
|
|
122
|
+
'Every finding is a warning, so the exit code stays 0. With `--json`, they are in `data.docTypes.findings`.',
|
|
123
|
+
'It uses the `typescript` your package installs. Without it, it prints `[skip] Docs not type-checked` and the reason.',
|
|
124
|
+
'Every field of every doc type is in `astryx docs authoring`.',
|
|
125
|
+
],
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
83
129
|
{
|
|
84
130
|
id: 'check-read-size',
|
|
85
131
|
title: 'Check read size',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx docs cli/integrations/checks`: what each package check
|
|
4
|
+
* @file `astryx docs cli/integrations/ship/checks`: what each package check
|
|
5
5
|
* proves, what fails and what only warns, and one command to run them all.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ export const docs = {
|
|
|
12
12
|
placement: {parent: 'namespace:ship', slot: 'guides', order: 20},
|
|
13
13
|
title: 'Check an integration',
|
|
14
14
|
category: 'guide',
|
|
15
|
-
keywords: ['check before publishing', 'validate an integration'
|
|
15
|
+
keywords: ['check before publishing', 'validate an integration'],
|
|
16
16
|
description:
|
|
17
17
|
'Pick the check for each problem, learn what fails and what only warns, and run every check in CI.',
|
|
18
18
|
sections: [
|
|
@@ -22,7 +22,7 @@ export const docs = {
|
|
|
22
22
|
content: [
|
|
23
23
|
{
|
|
24
24
|
type: 'prose',
|
|
25
|
-
text: 'Run these in the package folder. The four `doctor integration` checks read your source; `integration verify` checks the package npm would publish.',
|
|
25
|
+
text: 'Run these in the package folder. The four `doctor integration` checks read your source, and `integration check` runs all four; `integration verify` checks the package npm would publish.',
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
type: 'table',
|
|
@@ -30,15 +30,15 @@ export const docs = {
|
|
|
30
30
|
rows: [
|
|
31
31
|
[
|
|
32
32
|
'`npx astryx doctor integration validate`',
|
|
33
|
-
'The manifest loads,
|
|
33
|
+
'The manifest loads, each root holds contributions the CLI can read, and each doc matches its authoring type',
|
|
34
34
|
'A declared root is missing (`missing_root`), a contribution does not load (`invalid_doc`, `invalid_component`, `invalid_theme`), or two templates in the package replace one Core id (`ambiguous_template_replacement`)',
|
|
35
|
-
|
|
35
|
+
"The manifest has a key this CLI does not know (`unknown_manifest_key`), or a doc field does not match the doc's authoring type: a field the type does not have, a missing required field, or a value outside the field's type. It checks docs with your installed `typescript`; without it, it prints `[skip] Docs not type-checked`. With no `astryx.integration.mjs` it prints a hint and exits 0",
|
|
36
36
|
],
|
|
37
37
|
[
|
|
38
38
|
'`npx astryx doctor integration components`',
|
|
39
39
|
"No component name clashes with a Core component, each `replaces` names one Core component, and each component doc's props match the component's TypeScript props",
|
|
40
40
|
'Core is not installed (`core_not_found`). In a package that declares the CLI range that turns replacement on, a `replaces` target is missing (`missing_component_replacement_target`) or invalid (`invalid_component_replacement`), or two components replace one Core component (`ambiguous_component_replacement`)',
|
|
41
|
-
'A name clashes with Core, a component sets `replaces` in a package without that range (`inactive_component_replacement`, plus any missing, invalid, or duplicate `replaces` reported as a warning), or a documented prop differs from the code: it is missing there (`not_in_code`), the doc omits a prop the package declares (`not_in_doc`), or its `required`
|
|
41
|
+
'A name clashes with Core, a component sets `replaces` in a package without that range (`inactive_component_replacement`, plus any missing, invalid, or duplicate `replaces` reported as a warning), or a documented prop differs from the code: it is missing there (`not_in_code`), the doc omits a prop the package declares (`not_in_doc`), or its `required` (`required_mismatch`) or type (`type_mismatch`) disagrees. It reads props with your installed `typescript`; without it, it prints `[skip] Props not compared`',
|
|
42
42
|
],
|
|
43
43
|
[
|
|
44
44
|
'`npx astryx doctor integration templates`',
|
|
@@ -52,6 +52,12 @@ export const docs = {
|
|
|
52
52
|
'A topic takes a Core topic name without `replaces` or `extends`, a doc is invalid (`invalid_doc`), or a namespace or placement fails, which hides the doc (`invalid_doc_graph`)',
|
|
53
53
|
'A link names no doc (`invalid_doc_graph`)',
|
|
54
54
|
],
|
|
55
|
+
[
|
|
56
|
+
'`npx astryx integration check`',
|
|
57
|
+
'Everything the four `doctor integration` checks prove, in one command, for your build',
|
|
58
|
+
'Any of the four would exit 1 on its own. With `--strict`, also any warning, and any check that did not run, such as a package with no `astryx.integration.*`',
|
|
59
|
+
'Anything the four warn about, unless you pass `--strict`',
|
|
60
|
+
],
|
|
55
61
|
[
|
|
56
62
|
'`npx astryx integration verify`',
|
|
57
63
|
'The packed package holds every file, shows the same contributions, resolves every public import, and declares the CLI it needs',
|
|
@@ -68,23 +74,25 @@ export const docs = {
|
|
|
68
74
|
},
|
|
69
75
|
{
|
|
70
76
|
id: 'run-every-check-in-ci',
|
|
71
|
-
title: 'Run every check in
|
|
77
|
+
title: 'Run every check in every build (required)',
|
|
72
78
|
content: [
|
|
73
79
|
{
|
|
74
80
|
type: 'prose',
|
|
75
|
-
text: '
|
|
81
|
+
text: 'Every integration runs `integration check --strict` in its own build, so every build keeps your docs, types, and links in sync; this is required, not optional. Run `integration verify` before you publish. Install devDependencies first, because the components check needs Core, and `tsc --noEmit` needs `typescript` and a `tsconfig.json`. In package.json:',
|
|
76
82
|
},
|
|
77
83
|
{
|
|
78
84
|
type: 'code',
|
|
79
|
-
lang: '
|
|
80
|
-
code: '
|
|
85
|
+
lang: 'json',
|
|
86
|
+
code: '"typecheck": "tsc --noEmit && astryx integration check --strict"',
|
|
81
87
|
},
|
|
82
88
|
{
|
|
83
89
|
type: 'list',
|
|
84
90
|
style: 'unordered',
|
|
85
91
|
items: [
|
|
86
|
-
'`integration
|
|
87
|
-
'
|
|
92
|
+
'`integration check` runs `validate`, `components`, `templates`, and `docs` in that order, prints each result, then a summary, and exits 1 when any of them would.',
|
|
93
|
+
'`--strict` also exits 1 on any warning and on any check that did not run. Without it, warnings keep exit code 0: use that while you fix the warnings a package already has.',
|
|
94
|
+
'Its exit codes and JSON are a contract for your build: a new check, or a new failure code, joins only in a minor release that names it in the release notes. A patch can still ship a Core component, template, or CLI topic whose name conflicts with one of yours.',
|
|
95
|
+
'`integration verify` runs `validate` but none of the other three: a Core name clash, a `replaces` that names no Core template, a topic that takes a Core name, or a hidden guide still passes it. Run both before you publish: `npx astryx integration check --strict && npx astryx integration verify`.',
|
|
88
96
|
'Bare `npx astryx doctor` in the package also warns about a doc section over 32 KB, which no check above measures.',
|
|
89
97
|
],
|
|
90
98
|
},
|
|
@@ -112,7 +120,7 @@ export const docs = {
|
|
|
112
120
|
},
|
|
113
121
|
{
|
|
114
122
|
type: 'prose',
|
|
115
|
-
text: '`integration pack --check`, the name this check had
|
|
123
|
+
text: '`integration pack --check`, the name this check had before published 0.6.5, still runs it and prints a note; it will be removed in a later release. The options and exit codes are in {@link command:integration verify}.',
|
|
116
124
|
},
|
|
117
125
|
],
|
|
118
126
|
},
|