@astryxdesign/cli 0.6.3-canary.e86aa19 → 0.6.3-canary.e9fbd0f
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 +1 -1
- package/api/integration/authoring-checks.mjs +42 -22
- package/api/integration/authoring-checks.test.mjs +8 -1
- package/api/integration/authoring-checks.type.d.mts +1 -3
- package/api/integration/authoring-checks.type.mjs +7 -4
- package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
- package/api/integration/integrationTemplateConflicts.doc.mjs +8 -6
- package/api/integration/template-conflict-compatibility.test.mjs +73 -0
- package/clients/cli/commands/doctor-integration.test.mjs +7 -0
- package/clients/cli/commands/doctor.mjs +39 -17
- package/foundation/discovery/template-conflict-release.d.mts +13 -0
- package/foundation/discovery/template-conflict-release.mjs +40 -0
- package/foundation/discovery/template-conflict-release.test.mjs +40 -0
- package/foundation/response/response-types.doc.d.mts +5 -1
- package/foundation/response/response-types.doc.mjs +7 -3
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -470,7 +470,7 @@ Every response has a `type` discriminant. The full set is below (generated from
|
|
|
470
470
|
| `integration.add` | A contribution-writer receipt: kind, name, optional root {path, created}, integration-manifest path, every affected project-relative path, written, and dryRun. |
|
|
471
471
|
| `integration.pack-check` | The packed-package check: name, version, packable, tarball {filename, fileCount, size, unpackedSize} or null, inventory {manifest, roots [{kind, path, expectedFiles, missingFiles, complete}], expectedFiles, packedFiles}, contributions {local, packed}, each null or {themes [{slug, exportName}], components, templates [{id, type, name}], codemods [{version, id}], docs, agentDocsAppend}, and issues [{code, severity, message}]. |
|
|
472
472
|
| `integration.validate` | The validation result: the package name and version (both null when no local manifest is found) plus issues, an AstryxIntegrationIssue[] of {code, severity: warning \| error, message}. |
|
|
473
|
-
| `integration.template-conflicts` | The integration identity, issues, and conflicts as {severity:
|
|
473
|
+
| `integration.template-conflicts` | The integration identity, structural issues, and non-blocking Core template-id conflicts as {id, severity: warning, integrationPackage, integrationType, integrationName, coreMatches, message, command}. |
|
|
474
474
|
| `integration.component-conflicts` | The integration identity, structural issues, and non-blocking conflicts where an integration component name is also owned by Core; each conflict includes the exact package-qualified command. |
|
|
475
475
|
| `integration.doc-conflicts` | The integration identity, structural issues, and Core doc overlaps. Each finding includes `severity` (`info` \| `error`) and `relationship` (`replaces` \| `extends` \| `accidental`). |
|
|
476
476
|
| `layout.expand` | The expansion: parsed form, generated TSX code, componentsUsed, states (count of useState hooks scaffolded), todos, blocksReferenced (each {name, mode}), warnings, and written (the output path, or null when nothing was written). |
|
|
@@ -4,8 +4,14 @@
|
|
|
4
4
|
* @file Integration authoring diagnostics against the built-in Core catalog.
|
|
5
5
|
*
|
|
6
6
|
* Templates may intentionally replace Core identities; undeclared same-id
|
|
7
|
-
* overlaps stay fail-closed and require package selection.
|
|
8
|
-
*
|
|
7
|
+
* overlaps stay fail-closed and require package selection. The CLI package
|
|
8
|
+
* version gates replacement-specific fields so 0.6.x keeps its released shape.
|
|
9
|
+
* Docs have explicit `replaces` / `extends` relationships with parallel
|
|
10
|
+
* validation semantics.
|
|
11
|
+
*
|
|
12
|
+
* @input Integration packages, built-in catalogs, and the CLI release boundary.
|
|
13
|
+
* @output Typed template, component, and documentation authoring diagnostics.
|
|
14
|
+
* @position Public integration-authoring API over private discovery adapters.
|
|
9
15
|
*/
|
|
10
16
|
|
|
11
17
|
import {getCliInvocation} from '../../foundation/env/package-manager.mjs';
|
|
@@ -24,6 +30,7 @@ import {
|
|
|
24
30
|
discoverCoreTemplates,
|
|
25
31
|
discoverIntegrationTemplatesForOne,
|
|
26
32
|
} from '../../foundation/discovery/template-adapter.mjs';
|
|
33
|
+
import {expandedTemplateConflictSchemaActive} from '../../foundation/discovery/template-conflict-release.mjs';
|
|
27
34
|
import {
|
|
28
35
|
validateInstalledIntegration,
|
|
29
36
|
validateLocalIntegration,
|
|
@@ -99,6 +106,7 @@ export async function integrationTemplateConflicts(pkg, options = {}) {
|
|
|
99
106
|
]);
|
|
100
107
|
addErrors(issues, errors, 'invalid_template');
|
|
101
108
|
|
|
109
|
+
const expandedConflictSchema = expandedTemplateConflictSchemaActive();
|
|
102
110
|
const replacementResolution = applyTemplateReplacements(
|
|
103
111
|
[...coreTemplates, ...templates],
|
|
104
112
|
errors.filter(error => error.replacementTarget != null),
|
|
@@ -144,21 +152,29 @@ export async function integrationTemplateConflicts(pkg, options = {}) {
|
|
|
144
152
|
const sameIdCore = coreById.get(template.dirName);
|
|
145
153
|
const replacementIsActive = activeReplacementIds.has(template.dirName);
|
|
146
154
|
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
if (
|
|
156
|
+
expandedConflictSchema &&
|
|
157
|
+
replacementIsActive &&
|
|
158
|
+
template.replaces != null
|
|
159
|
+
) {
|
|
160
|
+
// This branch is unreachable before the package reaches 0.7.0. Keep the
|
|
161
|
+
// published 0.6.x conflict typedef narrow until the activation change.
|
|
162
|
+
conflicts.push(
|
|
163
|
+
/** @type {any} */ ({
|
|
164
|
+
id: template.dirName,
|
|
165
|
+
severity: 'info',
|
|
166
|
+
relationship: 'replaces',
|
|
167
|
+
replaces: template.replaces,
|
|
168
|
+
integrationPackage: name,
|
|
169
|
+
integrationType: template.type,
|
|
170
|
+
integrationName: template.name,
|
|
171
|
+
coreMatches: coreById.get(template.replaces) ?? [],
|
|
172
|
+
message:
|
|
173
|
+
`Intentional replacement: "${template.dirName}" replaces the Core template ` +
|
|
174
|
+
`"${template.replaces}" for unqualified lookup.`,
|
|
175
|
+
command: `${run} template ${shellArg(template.replaces)} --package ${shellArg('@astryxdesign/core')}`,
|
|
176
|
+
}),
|
|
177
|
+
);
|
|
162
178
|
}
|
|
163
179
|
|
|
164
180
|
if (
|
|
@@ -174,20 +190,24 @@ export async function integrationTemplateConflicts(pkg, options = {}) {
|
|
|
174
190
|
conflicts.push({
|
|
175
191
|
id: template.dirName,
|
|
176
192
|
severity: 'warning',
|
|
177
|
-
relationship: 'accidental',
|
|
193
|
+
...(expandedConflictSchema ? {relationship: 'accidental'} : {}),
|
|
178
194
|
integrationPackage: name,
|
|
179
195
|
integrationType: template.type,
|
|
180
196
|
integrationName: template.name,
|
|
181
197
|
coreMatches: sameIdCore,
|
|
182
|
-
message:
|
|
183
|
-
?
|
|
184
|
-
|
|
198
|
+
message: expandedConflictSchema
|
|
199
|
+
? compatibleKind
|
|
200
|
+
? `Template id "${template.dirName}" conflicts with Core (${coreKinds}). Consider renaming it, or set replaces: ${JSON.stringify(template.dirName)} in its metadata to replace the Core template.`
|
|
201
|
+
: `Template id "${template.dirName}" conflicts with Core (${coreKinds}), but a ${template.type} template cannot replace a different template kind. Rename the integration template.`
|
|
202
|
+
: `Template id "${template.dirName}" conflicts with Core (${coreKinds}). Consider renaming the integration template. If you keep it, always select it with --package.`,
|
|
185
203
|
command: `${run} template ${shellArg(template.dirName)} --package ${shellArg(name)}`,
|
|
186
204
|
});
|
|
187
205
|
}
|
|
188
206
|
}
|
|
189
207
|
conflicts.sort((a, b) =>
|
|
190
|
-
`${a.id}:${a.relationship}`.localeCompare(
|
|
208
|
+
`${a.id}:${'relationship' in a ? a.relationship : ''}`.localeCompare(
|
|
209
|
+
`${b.id}:${'relationship' in b ? b.relationship : ''}`,
|
|
210
|
+
),
|
|
191
211
|
);
|
|
192
212
|
|
|
193
213
|
return {
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file Hermetic integration authoring checks against the real Core catalogs.
|
|
5
|
+
* @input Integration fixtures and the post-0.7 conflict projection.
|
|
6
|
+
* @output Coverage for replacement validation and public diagnostics.
|
|
7
|
+
* @position Unit coverage; the 0.6.x compatibility shape has its own fixture.
|
|
5
8
|
*/
|
|
6
9
|
|
|
7
|
-
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
10
|
+
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
|
11
|
+
|
|
12
|
+
vi.mock('../../foundation/discovery/template-conflict-release.mjs', () => ({
|
|
13
|
+
expandedTemplateConflictSchemaActive: () => true,
|
|
14
|
+
}));
|
|
8
15
|
import * as fs from 'node:fs';
|
|
9
16
|
import * as path from 'node:path';
|
|
10
17
|
import {discoverCoreTemplates} from '../../foundation/discovery/template-adapter.mjs';
|
|
@@ -10,9 +10,7 @@ export type CoreTemplateMatch = {
|
|
|
10
10
|
};
|
|
11
11
|
export type IntegrationTemplateConflict = {
|
|
12
12
|
id: string;
|
|
13
|
-
severity: "
|
|
14
|
-
relationship: "replaces" | "accidental";
|
|
15
|
-
replaces?: string | undefined;
|
|
13
|
+
severity: "warning";
|
|
16
14
|
integrationPackage: string;
|
|
17
15
|
integrationType: "page" | "block";
|
|
18
16
|
integrationName: string;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* @file Colocated public types for integration authoring diagnostics.
|
|
5
|
+
* @input Stable response fields exposed by integration-authoring APIs.
|
|
6
|
+
* @output JSDoc typedefs consumed by declarations, commands, and callers.
|
|
7
|
+
* @position Public type boundary for integration diagnostics.
|
|
8
|
+
*/
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* @typedef {object} IntegrationAuthoringOptions
|
|
@@ -16,9 +21,7 @@
|
|
|
16
21
|
/**
|
|
17
22
|
* @typedef {object} IntegrationTemplateConflict
|
|
18
23
|
* @property {string} id
|
|
19
|
-
* @property {'
|
|
20
|
-
* @property {'replaces' | 'accidental'} relationship
|
|
21
|
-
* @property {string} [replaces]
|
|
24
|
+
* @property {'warning'} severity
|
|
22
25
|
* @property {string} integrationPackage
|
|
23
26
|
* @property {'page' | 'block'} integrationType
|
|
24
27
|
* @property {string} integrationName
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @file FunctionDoc for integration template-conflict diagnostics.
|
|
6
|
+
* @input The stable 0.6.x `integrationTemplateConflicts` API contract.
|
|
7
|
+
* @output Generated CLI API reference metadata.
|
|
8
|
+
* @position Consumer-facing documentation for the public authoring API.
|
|
6
9
|
*/
|
|
7
10
|
/** @type {import('@astryxdesign/cli/authoring').FunctionDoc} */
|
|
8
11
|
export const doc: import("@astryxdesign/cli/authoring").FunctionDoc;
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file FunctionDoc for integration template-conflict diagnostics.
|
|
5
|
+
* @input The stable 0.6.x `integrationTemplateConflicts` API contract.
|
|
6
|
+
* @output Generated CLI API reference metadata.
|
|
7
|
+
* @position Consumer-facing documentation for the public authoring API.
|
|
5
8
|
*/
|
|
6
9
|
|
|
7
10
|
/** @type {import('@astryxdesign/cli/authoring').FunctionDoc} */
|
|
@@ -11,12 +14,11 @@ export const doc = {
|
|
|
11
14
|
name: 'integrationTemplateConflicts',
|
|
12
15
|
namespace: 'cli/api',
|
|
13
16
|
displayName: 'integrationTemplateConflicts()',
|
|
14
|
-
summary: '
|
|
17
|
+
summary: 'Find integration template ids that also exist in Core.',
|
|
15
18
|
description:
|
|
16
|
-
'Loads one local or installed integration,
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'mismatches, and undeclared same-id conflicts.',
|
|
19
|
+
'Loads one local or installed integration, compares its template ids with the ' +
|
|
20
|
+
'built-in Core page and block templates, and returns non-blocking conflicts with ' +
|
|
21
|
+
'the exact package-qualified CLI command required to keep an intentional overlap.',
|
|
20
22
|
importPath: '@astryxdesign/cli/api',
|
|
21
23
|
signature:
|
|
22
24
|
'integrationTemplateConflicts(pkg?: string, options?: IntegrationAuthoringOptions): Promise<IntegrationTemplateConflictResponse>',
|
|
@@ -39,7 +41,7 @@ export const doc = {
|
|
|
39
41
|
{
|
|
40
42
|
type: 'integration.template-conflicts',
|
|
41
43
|
description:
|
|
42
|
-
'The integration identity, structural
|
|
44
|
+
'The integration identity, structural issues, and every Core template-id conflict with a package-qualified command.',
|
|
43
45
|
},
|
|
44
46
|
],
|
|
45
47
|
examples: [
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Final-0.6.x compatibility coverage for integration-template conflicts.
|
|
5
|
+
* @input A future replacement declaration plus an ordinary released conflict.
|
|
6
|
+
* @output Proof that 0.6.x omits replacement-specific public fields.
|
|
7
|
+
* @position Regression fixture for the stable conflict response boundary.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import {discoverCoreTemplates} from '../../foundation/discovery/template-adapter.mjs';
|
|
14
|
+
import {integrationTemplateConflicts} from './authoring-checks.mjs';
|
|
15
|
+
|
|
16
|
+
let tmpDir;
|
|
17
|
+
|
|
18
|
+
function writeTemplate(pkgDir, id, type, replaces) {
|
|
19
|
+
const stem = path.join(pkgDir, 'templates', id);
|
|
20
|
+
fs.mkdirSync(path.dirname(stem), {recursive: true});
|
|
21
|
+
fs.writeFileSync(
|
|
22
|
+
`${stem}.doc.mjs`,
|
|
23
|
+
`export default {type: ${JSON.stringify(type)}, name: ${JSON.stringify(id)}, description: 'fixture'${replaces == null ? '' : `, replaces: ${JSON.stringify(replaces)}`}};\n`,
|
|
24
|
+
);
|
|
25
|
+
fs.writeFileSync(
|
|
26
|
+
`${stem}.tsx`,
|
|
27
|
+
`export default function Fixture() { return ${JSON.stringify(id)}; }\n`,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
tmpDir = fs.mkdtempSync(
|
|
33
|
+
path.join(process.cwd(), '.astryx-template-conflict-compat-'),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('integration-template conflict compatibility on 0.6.x', () => {
|
|
42
|
+
it('preserves the released warning-only conflict shape', async () => {
|
|
43
|
+
const corePages = (await discoverCoreTemplates()).filter(
|
|
44
|
+
candidate => candidate.type === 'page',
|
|
45
|
+
);
|
|
46
|
+
const target = corePages[0];
|
|
47
|
+
const accidental = corePages[1];
|
|
48
|
+
expect(target).toBeDefined();
|
|
49
|
+
expect(accidental).toBeDefined();
|
|
50
|
+
|
|
51
|
+
fs.writeFileSync(
|
|
52
|
+
path.join(tmpDir, 'package.json'),
|
|
53
|
+
JSON.stringify({name: '@acme/widgets', version: '1.0.0'}),
|
|
54
|
+
);
|
|
55
|
+
fs.writeFileSync(
|
|
56
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
57
|
+
`export default {templates: './templates'};\n`,
|
|
58
|
+
);
|
|
59
|
+
writeTemplate(tmpDir, 'acme-future-shell', target.type, target.dirName);
|
|
60
|
+
writeTemplate(tmpDir, accidental.dirName, accidental.type);
|
|
61
|
+
|
|
62
|
+
const report = await integrationTemplateConflicts(undefined, {cwd: tmpDir});
|
|
63
|
+
|
|
64
|
+
expect(report.data.issues).toEqual([]);
|
|
65
|
+
expect(report.data.conflicts).toHaveLength(1);
|
|
66
|
+
expect(report.data.conflicts[0]).toMatchObject({
|
|
67
|
+
id: accidental.dirName,
|
|
68
|
+
severity: 'warning',
|
|
69
|
+
});
|
|
70
|
+
expect(report.data.conflicts[0]).not.toHaveProperty('relationship');
|
|
71
|
+
expect(report.data.conflicts[0]).not.toHaveProperty('replaces');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file Command-level coverage for `astryx doctor integration` authoring checks.
|
|
5
|
+
* @input Integration fixtures and the post-0.7 conflict projection.
|
|
6
|
+
* @output Assertions for human and typed command responses.
|
|
7
|
+
* @position CLI adapter coverage; 0.6.x API shape is verified separately.
|
|
5
8
|
*/
|
|
6
9
|
|
|
7
10
|
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
|
11
|
+
|
|
12
|
+
vi.mock('../../../foundation/discovery/template-conflict-release.mjs', () => ({
|
|
13
|
+
expandedTemplateConflictSchemaActive: () => true,
|
|
14
|
+
}));
|
|
8
15
|
import * as fs from 'node:fs';
|
|
9
16
|
import * as path from 'node:path';
|
|
10
17
|
import {Command} from 'commander';
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file `astryx doctor` project health and integration-authoring diagnostics.
|
|
5
5
|
* Human output uses plain stable tokens; every leaf also has a typed JSON
|
|
6
|
-
* response.
|
|
6
|
+
* response. Template-conflict fields follow the package release boundary.
|
|
7
|
+
* Exit 1 means a check found an error, while warnings remain exit 0.
|
|
8
|
+
*
|
|
9
|
+
* @input Typed Doctor and integration-authoring API responses.
|
|
10
|
+
* @output Human-readable records or pass-through typed JSON.
|
|
11
|
+
* @position CLI presentation adapter for project and integration health.
|
|
7
12
|
*/
|
|
8
13
|
|
|
9
14
|
import {runChecks} from '../../../api/doctor/doctor.mjs';
|
|
@@ -126,26 +131,41 @@ function printTemplateConflicts(data) {
|
|
|
126
131
|
...issueBlocks(data.issues),
|
|
127
132
|
];
|
|
128
133
|
if (data.conflicts.length === 0 && data.issues.length === 0) {
|
|
129
|
-
output.push(
|
|
130
|
-
text('[ok] No template replacements or id conflicts with Core.'),
|
|
131
|
-
);
|
|
134
|
+
output.push(text('[ok] No template ids conflict with Core.'));
|
|
132
135
|
} else if (data.conflicts.length > 0) {
|
|
136
|
+
const expanded = data.conflicts.some(
|
|
137
|
+
conflict => 'relationship' in conflict,
|
|
138
|
+
);
|
|
133
139
|
output.push(
|
|
134
140
|
records(data.conflicts, {
|
|
135
|
-
fields:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
fields: expanded
|
|
142
|
+
? [
|
|
143
|
+
'severity',
|
|
144
|
+
'relationship',
|
|
145
|
+
'id',
|
|
146
|
+
'replaces',
|
|
147
|
+
'integrationPackage',
|
|
148
|
+
'integrationType',
|
|
149
|
+
'integrationName',
|
|
150
|
+
'message',
|
|
151
|
+
'command',
|
|
152
|
+
]
|
|
153
|
+
: [
|
|
154
|
+
'severity',
|
|
155
|
+
'id',
|
|
156
|
+
'integrationPackage',
|
|
157
|
+
'integrationType',
|
|
158
|
+
'integrationName',
|
|
159
|
+
'message',
|
|
160
|
+
'command',
|
|
161
|
+
],
|
|
146
162
|
format: {severity: statusToken},
|
|
147
163
|
}),
|
|
148
|
-
text(
|
|
164
|
+
text(
|
|
165
|
+
expanded
|
|
166
|
+
? `${data.conflicts.length} Core template relationship(s).`
|
|
167
|
+
: `${data.conflicts.length} Core template conflict(s). Renaming is recommended but optional; keep the package-qualified command if the overlap is intentional.`,
|
|
168
|
+
),
|
|
149
169
|
);
|
|
150
170
|
}
|
|
151
171
|
emit(...output);
|
|
@@ -199,7 +219,9 @@ function printDocConflicts(data) {
|
|
|
199
219
|
issue => issue.severity === 'error' || issue.code === 'invalid_doc_graph',
|
|
200
220
|
)
|
|
201
221
|
) {
|
|
202
|
-
output.push(
|
|
222
|
+
output.push(
|
|
223
|
+
text('[ok] The docs tree and every link in these docs check out.'),
|
|
224
|
+
);
|
|
203
225
|
}
|
|
204
226
|
if (data.findings.length === 0) {
|
|
205
227
|
output.push(text('[ok] No doc topics overlap with Core.'));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether this release exposes replacement relationships in the public conflict API.
|
|
6
|
+
* Both the supported version and a deliberate projection update are required;
|
|
7
|
+
* a routine package-version bump cannot expand the public shape by itself.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} [version]
|
|
10
|
+
* @param {'warning-only' | 'expanded'} [projection]
|
|
11
|
+
* @returns {boolean}
|
|
12
|
+
*/
|
|
13
|
+
export function expandedTemplateConflictSchemaActive(version?: string, projection?: "warning-only" | "expanded"): boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Release boundary for the expanded integration-template conflict schema.
|
|
5
|
+
*
|
|
6
|
+
* @input The CLI package version and an explicit public-schema projection.
|
|
7
|
+
* @output Whether replacement-specific conflict fields may reach the stable API.
|
|
8
|
+
* @position Private compatibility gate for integration authoring diagnostics.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import {semverCompare} from '../env/semver.mjs';
|
|
14
|
+
import {CLI_ROOT} from '../fs/paths.mjs';
|
|
15
|
+
|
|
16
|
+
const EXPANDED_TEMPLATE_CONFLICT_SCHEMA_CLI = '0.7.0';
|
|
17
|
+
/** @type {'warning-only' | 'expanded'} */
|
|
18
|
+
const TEMPLATE_CONFLICT_SCHEMA_PROJECTION = 'warning-only';
|
|
19
|
+
const CLI_VERSION = JSON.parse(
|
|
20
|
+
fs.readFileSync(path.join(CLI_ROOT, 'package.json'), 'utf8'),
|
|
21
|
+
).version;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Whether this release exposes replacement relationships in the public conflict API.
|
|
25
|
+
* Both the supported version and a deliberate projection update are required;
|
|
26
|
+
* a routine package-version bump cannot expand the public shape by itself.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} [version]
|
|
29
|
+
* @param {'warning-only' | 'expanded'} [projection]
|
|
30
|
+
* @returns {boolean}
|
|
31
|
+
*/
|
|
32
|
+
export function expandedTemplateConflictSchemaActive(
|
|
33
|
+
version = CLI_VERSION,
|
|
34
|
+
projection = TEMPLATE_CONFLICT_SCHEMA_PROJECTION,
|
|
35
|
+
) {
|
|
36
|
+
return (
|
|
37
|
+
projection === 'expanded' &&
|
|
38
|
+
semverCompare(version, EXPANDED_TEMPLATE_CONFLICT_SCHEMA_CLI) >= 0
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Unit coverage for the integration-template conflict release boundary.
|
|
5
|
+
* @input CLI versions and explicit warning-only or expanded projections.
|
|
6
|
+
* @output Boolean activation assertions for the expanded conflict schema.
|
|
7
|
+
* @position Colocated coverage for the private release gate.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {describe, expect, it} from 'vitest';
|
|
11
|
+
import {expandedTemplateConflictSchemaActive} from './template-conflict-release.mjs';
|
|
12
|
+
|
|
13
|
+
describe('expandedTemplateConflictSchemaActive', () => {
|
|
14
|
+
it.each(['0.6.3', '0.6.4', '0.6.99'])(
|
|
15
|
+
'keeps %s narrow even when the expanded projection is requested',
|
|
16
|
+
version => {
|
|
17
|
+
expect(expandedTemplateConflictSchemaActive(version, 'expanded')).toBe(
|
|
18
|
+
false,
|
|
19
|
+
);
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
it.each(['0.7.0-rc.1', '0.7.0', '0.8.0'])(
|
|
24
|
+
'does not let version %s expand the warning-only projection',
|
|
25
|
+
version => {
|
|
26
|
+
expect(
|
|
27
|
+
expandedTemplateConflictSchemaActive(version, 'warning-only'),
|
|
28
|
+
).toBe(false);
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
it.each(['0.7.0-rc.1', '0.7.0', '0.8.0'])(
|
|
33
|
+
'allows the deliberate expanded projection in %s',
|
|
34
|
+
version => {
|
|
35
|
+
expect(expandedTemplateConflictSchemaActive(version, 'expanded')).toBe(
|
|
36
|
+
true,
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
});
|
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
* @file EnumDoc for the `type` discriminant carried on every --json success
|
|
6
6
|
* envelope. The vocabulary mirrors the RESPONSE_TYPES map (each command's
|
|
7
7
|
* `jsonOut(...)` call sites) in `clients/cli/lib/manifest.mjs`; a consumer
|
|
8
|
-
* switches on `type` to narrow the `data` payload.
|
|
8
|
+
* switches on `type` to narrow the `data` payload. Descriptions follow the
|
|
9
|
+
* currently published response projection, not a future package-version boundary.
|
|
10
|
+
*
|
|
11
|
+
* @input Public response discriminants and their currently released payloads.
|
|
12
|
+
* @output Generated consumer reference for every typed JSON success response.
|
|
9
13
|
* @position packages/cli/foundation/response — enum documentation
|
|
10
14
|
*/
|
|
11
15
|
/** @type {import('@astryxdesign/cli/authoring').EnumDoc} */
|
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
* @file EnumDoc for the `type` discriminant carried on every --json success
|
|
5
5
|
* envelope. The vocabulary mirrors the RESPONSE_TYPES map (each command's
|
|
6
6
|
* `jsonOut(...)` call sites) in `clients/cli/lib/manifest.mjs`; a consumer
|
|
7
|
-
* switches on `type` to narrow the `data` payload.
|
|
7
|
+
* switches on `type` to narrow the `data` payload. Descriptions follow the
|
|
8
|
+
* currently published response projection, not a future package-version boundary.
|
|
9
|
+
*
|
|
10
|
+
* @input Public response discriminants and their currently released payloads.
|
|
11
|
+
* @output Generated consumer reference for every typed JSON success response.
|
|
8
12
|
* @position packages/cli/foundation/response — enum documentation
|
|
9
13
|
*/
|
|
10
14
|
|
|
@@ -61,7 +65,7 @@ export const doc = {
|
|
|
61
65
|
{
|
|
62
66
|
value: 'docs.list',
|
|
63
67
|
description:
|
|
64
|
-
|
|
68
|
+
"All reference-doc topics as DocsListEntry[] ({topic, description, package, replaces?}), in read order; meta.namespaces lists the docs tree's top-level namespaces, and meta.notLoaded each package whose docs did not load.",
|
|
65
69
|
},
|
|
66
70
|
{
|
|
67
71
|
value: 'docs.detail',
|
|
@@ -291,7 +295,7 @@ export const doc = {
|
|
|
291
295
|
{
|
|
292
296
|
value: 'integration.template-conflicts',
|
|
293
297
|
description:
|
|
294
|
-
'The integration identity, issues, and conflicts as {severity:
|
|
298
|
+
'The integration identity, structural issues, and non-blocking Core template-id conflicts as {id, severity: warning, integrationPackage, integrationType, integrationName, coreMatches, message, command}.',
|
|
295
299
|
},
|
|
296
300
|
{
|
|
297
301
|
value: 'integration.component-conflicts',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/cli",
|
|
3
|
-
"version": "0.6.3-canary.
|
|
3
|
+
"version": "0.6.3-canary.e9fbd0f",
|
|
4
4
|
"displayName": "CLI",
|
|
5
5
|
"description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -101,10 +101,10 @@
|
|
|
101
101
|
"zod": "^4.4.3"
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
|
-
"@astryxdesign/charts": "0.6.3-canary.
|
|
105
|
-
"@astryxdesign/core": "0.6.3-canary.
|
|
106
|
-
"@astryxdesign/lab": "0.6.3-canary.
|
|
107
|
-
"@astryxdesign/theme-neutral": "0.6.3-canary.
|
|
104
|
+
"@astryxdesign/charts": "0.6.3-canary.e9fbd0f",
|
|
105
|
+
"@astryxdesign/core": "0.6.3-canary.e9fbd0f",
|
|
106
|
+
"@astryxdesign/lab": "0.6.3-canary.e9fbd0f",
|
|
107
|
+
"@astryxdesign/theme-neutral": "0.6.3-canary.e9fbd0f"
|
|
108
108
|
},
|
|
109
109
|
"peerDependenciesMeta": {
|
|
110
110
|
"@astryxdesign/charts": {
|
|
@@ -121,10 +121,10 @@
|
|
|
121
121
|
}
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
|
-
"@astryxdesign/charts": "0.6.3-canary.
|
|
125
|
-
"@astryxdesign/core": "0.6.3-canary.
|
|
126
|
-
"@astryxdesign/lab": "0.6.3-canary.
|
|
127
|
-
"@astryxdesign/theme-neutral": "0.6.3-canary.
|
|
124
|
+
"@astryxdesign/charts": "0.6.3-canary.e9fbd0f",
|
|
125
|
+
"@astryxdesign/core": "0.6.3-canary.e9fbd0f",
|
|
126
|
+
"@astryxdesign/lab": "0.6.3-canary.e9fbd0f",
|
|
127
|
+
"@astryxdesign/theme-neutral": "0.6.3-canary.e9fbd0f",
|
|
128
128
|
"@heroicons/react": "^2.2.0",
|
|
129
129
|
"@stylexjs/stylex": "^0.19.0",
|
|
130
130
|
"@types/babel__core": "^7.20.5",
|