@astryxdesign/cli 0.1.0 → 0.1.1-canary.080d887
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/CHANGELOG.md +68 -0
- package/README.md +117 -75
- package/bin/astryx.mjs +22 -7
- package/docs/getting-started.doc.mjs +11 -11
- package/docs/icons.doc.mjs +1 -1
- package/docs/migration.doc.mjs +2 -2
- package/docs/shape.doc.mjs +1 -1
- package/docs/styling.doc.mjs +3 -4
- package/docs/theme.doc.dense.mjs +2 -2
- package/docs/theme.doc.mjs +14 -0
- package/docs/theme.doc.zh.mjs +2 -2
- package/docs/working-with-ai.doc.mjs +4 -4
- package/package.json +20 -9
- package/src/api/discover.mjs +78 -26
- package/src/api/doctor.mjs +3 -3
- package/src/api/layout.mjs +301 -0
- package/src/api/layout.test.mjs +238 -0
- package/src/api/search.mjs +207 -13
- package/src/api/template.mjs +193 -51
- package/src/api/template.test.mjs +2 -0
- package/src/codemods/__tests__/registry.test.mjs +1 -0
- package/src/codemods/registry.mjs +1 -0
- package/src/codemods/runner.mjs +105 -51
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +116 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +51 -0
- package/src/codemods/transforms/v0.1.0/index.mjs +28 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +230 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +84 -0
- package/src/commands/agent-docs.mjs +119 -66
- package/src/commands/agent-docs.path-safety.test.mjs +1 -1
- package/src/commands/agent-docs.test.mjs +87 -31
- package/src/commands/build-theme.import-path.test.mjs +1 -1
- package/src/commands/build-theme.path-safety.test.mjs +1 -1
- package/src/commands/build-theme.prose.test.mjs +1 -1
- package/src/commands/build.mjs +196 -0
- package/src/commands/component-package.test.mjs +1 -1
- package/src/commands/component.test.mjs +1 -1
- package/src/commands/docs.test.mjs +1 -1
- package/src/commands/doctor.test.mjs +1 -1
- package/src/commands/external-showcase.test.mjs +1 -1
- package/src/commands/gap-report.mjs +17 -9
- package/src/commands/gap-report.test.mjs +21 -16
- package/src/commands/init.mjs +43 -9
- package/src/commands/init.next-steps.test.mjs +46 -0
- package/src/commands/interactive-guard.test.mjs +1 -1
- package/src/commands/json-contract.test.mjs +10 -3
- package/src/commands/layout.mjs +139 -0
- package/src/commands/swizzle-gap-safety.test.mjs +1 -1
- package/src/commands/swizzle.mjs +51 -23
- package/src/commands/swizzle.path-safety.test.mjs +1 -1
- package/src/commands/template.path-safety.test.mjs +1 -1
- package/src/commands/template.test.mjs +1 -1
- package/src/commands/upgrade.mjs +292 -177
- package/src/commands/upgrade.test.mjs +41 -27
- package/src/config.mjs +31 -0
- package/src/config.test.mjs +24 -0
- package/src/index.mjs +5 -0
- package/src/lib/config-schema.mjs +119 -0
- package/src/lib/config.mjs +45 -6
- package/src/lib/config.test.mjs +91 -0
- package/src/lib/error-codes.mjs +11 -0
- package/src/lib/integrations.mjs +155 -0
- package/src/lib/integrations.test.mjs +154 -0
- package/src/lib/levenshtein.mjs +29 -0
- package/src/lib/manifest.mjs +6 -0
- package/src/lib/package-scanner.mjs +31 -7
- package/src/lib/string-utils.mjs +5 -14
- package/src/lib/xle/browser.d.ts +91 -0
- package/src/lib/xle/browser.mjs +120 -0
- package/src/lib/xle/expand.mjs +622 -0
- package/src/lib/xle/parse.mjs +581 -0
- package/src/lib/xle/print.mjs +174 -0
- package/src/lib/xle/registry-core.mjs +170 -0
- package/src/lib/xle/registry.mjs +237 -0
- package/src/lib/xle/splice.mjs +137 -0
- package/src/lib/xle/validate.mjs +356 -0
- package/src/lib/xle/xle.test.mjs +333 -0
- package/src/types/config.d.ts +99 -0
- package/src/types/error-codes.d.ts +1 -0
- package/src/utils/github.mjs +12 -27
- package/src/utils/interactive.mjs +1 -1
- package/src/utils/interactive.test.mjs +2 -0
- package/src/utils/package-manager.mjs +1 -1
- package/src/utils/package-manager.test.mjs +1 -1
- package/src/utils/path-safety.test.mjs +1 -1
- package/src/utils/paths.test.mjs +8 -8
- package/src/utils/update-check.mjs +4 -26
- package/src/utils/update-check.test.mjs +2 -64
- package/templates/blocks/components/AppShell/AppShellContentOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellShowcase.tsx +1 -10
- package/templates/blocks/components/AppShell/AppShellSideNavOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellTopNavOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellTopNavWithSideNav.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellWithBanner.tsx +1 -9
- package/templates/blocks/components/AspectRatio/AspectRatioShowcase.tsx +12 -19
- package/templates/blocks/components/Banner/BannerShowcase.tsx +1 -8
- package/templates/blocks/components/Blockquote/BlockquoteShowcase.tsx +1 -8
- package/templates/blocks/components/Carousel/CarouselShowcase.tsx +2 -12
- package/templates/blocks/components/ChatComposerDrawer/ChatComposerDrawerShowcase.tsx +6 -9
- package/templates/blocks/components/ChatLayout/ChatLayoutPanelChat.tsx +10 -12
- package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +1 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListShowcase.tsx +1 -9
- package/templates/blocks/components/ChatMessageMetadata/ChatMessageMetadataShowcase.tsx +1 -8
- package/templates/blocks/components/ChatSendButton/ChatSendButtonInComposer.tsx +1 -8
- package/templates/blocks/components/Citation/CitationInlineText.tsx +4 -4
- package/templates/blocks/components/Code/CodeInlineInParagraph.tsx +1 -8
- package/templates/blocks/components/CodeBlock/CodeBlockBashCommand.tsx +1 -1
- package/templates/blocks/components/CodeBlock/CodeBlockJSONConfig.tsx +1 -1
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.doc.mjs +15 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.tsx +26 -0
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemShowcase.tsx +9 -12
- package/templates/blocks/components/ContextMenu/ContextMenuShowcase.tsx +13 -15
- package/templates/blocks/components/DateInput/DateInputDateRange.doc.mjs +2 -2
- package/templates/blocks/components/Divider/DividerShowcase.tsx +1 -8
- package/templates/blocks/components/Divider/DividerVertical.tsx +7 -9
- package/templates/blocks/components/Field/FieldShowcase.tsx +1 -8
- package/templates/blocks/components/FormLayout/FormLayoutHorizontal.tsx +1 -6
- package/templates/blocks/components/Grid/GridResponsiveAutoFit.tsx +1 -9
- package/templates/blocks/components/HoverCard/HoverCardInlineTextHoverCard.tsx +4 -6
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +1 -6
- package/templates/blocks/components/HoverCard/HoverCardProfileHoverCard.tsx +2 -8
- package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -8
- package/templates/blocks/components/OverflowList/OverflowListOverflowBadges.tsx +8 -11
- package/templates/blocks/components/OverflowList/OverflowListOverflowDropdownActions.tsx +9 -12
- package/templates/blocks/components/Overlay/OverlayBottomStrip.tsx +4 -17
- package/templates/blocks/components/Overlay/OverlayHoverReveal.tsx +15 -16
- package/templates/blocks/components/Overlay/OverlayShowcase.tsx +5 -21
- package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -14
- package/templates/blocks/components/Pagination/PaginationPageSize.tsx +12 -14
- package/templates/blocks/components/Pagination/PaginationVariants.tsx +1 -8
- package/templates/blocks/components/Pagination/PaginationWithTable.tsx +2 -14
- package/templates/blocks/components/Slider/SliderShowcase.tsx +10 -1
- package/templates/blocks/components/ToggleButton/ToggleButtonGroup.doc.mjs +1 -1
- package/templates/blocks/components/Tokenizer/TokenizerClear.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerCreatable.tsx +2 -7
- package/templates/blocks/components/Tokenizer/TokenizerEndContent.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerIcon.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerMaxEntries.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerOverflow.tsx +2 -7
- package/templates/blocks/components/Tokenizer/TokenizerShowcase.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerStates.tsx +4 -9
- package/templates/blocks/components/Toolbar/ToolbarCardHeader.tsx +1 -10
- package/templates/blocks/components/Toolbar/ToolbarSizes.tsx +1 -8
- package/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +1 -8
- package/templates/blocks/components/Toolbar/ToolbarThreeSlot.tsx +1 -10
- package/templates/blocks/components/Toolbar/ToolbarWithTabs.tsx +8 -11
- package/templates/pages/ai-chat/page.tsx +71 -64
- package/templates/pages/ai-chat-landing/page.tsx +8 -12
- package/templates/pages/centered-hero/page.tsx +13 -15
- package/templates/pages/classic-gallery/page.tsx +27 -34
- package/templates/pages/detail-page/page.tsx +18 -18
- package/templates/pages/documentation/page.tsx +42 -58
- package/templates/pages/documentation-design/page.tsx +82 -60
- package/templates/pages/documentation-technical/page.tsx +101 -60
- package/templates/pages/editor/page.tsx +42 -54
- package/templates/pages/file-explorer/page.tsx +13 -16
- package/templates/pages/form-two-column/page.tsx +13 -17
- package/templates/pages/gallery-hero/page.tsx +13 -15
- package/templates/pages/ide/page.tsx +188 -264
- package/templates/pages/library/page.tsx +16 -23
- package/templates/pages/login/page.tsx +14 -18
- package/templates/pages/login-card/page.tsx +14 -18
- package/templates/pages/login-split/page.tsx +50 -48
- package/templates/pages/login-sso/page.tsx +9 -13
- package/templates/pages/mixed-gallery/page.tsx +51 -45
- package/templates/pages/payment-form/page.tsx +56 -70
- package/templates/pages/product-detail/page.tsx +27 -33
- package/templates/pages/product-gallery/page.tsx +7 -13
- package/templates/pages/settings-dialog/page.tsx +35 -43
- package/templates/pages/settings-sidebar/page.tsx +39 -47
- package/templates/pages/side-gallery/page.tsx +6 -9
- package/templates/pages/table-grouped/page.tsx +11 -15
- package/templates/pages/theme-showcase/page.tsx +33 -37
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.doc.mjs +0 -14
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +0 -67
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file layout command — thin CLI wrapper around api/layout.mjs.
|
|
5
|
+
*
|
|
6
|
+
* Subcommands:
|
|
7
|
+
* astryx layout expand "<expr>" [path] compressed expression → validated TSX
|
|
8
|
+
* astryx layout check "<expr>" validate + echo both canonical surfaces
|
|
9
|
+
* astryx layout grammar agent cheatsheet (alias table is branch-generated)
|
|
10
|
+
*
|
|
11
|
+
* The expression argument may also come from --file or stdin (`-`),
|
|
12
|
+
* which is how multi-line outline (XLO) input usually arrives.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import * as fs from 'node:fs';
|
|
16
|
+
import {jsonOut, humanLog} from '../lib/json.mjs';
|
|
17
|
+
import {cliError} from '../lib/cli-error.mjs';
|
|
18
|
+
import {layoutExpand, layoutCheck, layoutGrammar} from '../api/layout.mjs';
|
|
19
|
+
|
|
20
|
+
/** Resolve the expression from arg, --file, or stdin ('-'). */
|
|
21
|
+
async function readExpression(expr, options) {
|
|
22
|
+
if (options.file) return fs.readFileSync(options.file, 'utf-8');
|
|
23
|
+
if (expr === '-' || (!expr && !process.stdin.isTTY)) {
|
|
24
|
+
const chunks = [];
|
|
25
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
26
|
+
return Buffer.concat(chunks).toString('utf-8');
|
|
27
|
+
}
|
|
28
|
+
return expr;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function registerLayout(program) {
|
|
32
|
+
const layoutCmd = program
|
|
33
|
+
.command('layout')
|
|
34
|
+
.description('Generate XDS layouts from compressed expressions (XLE/XLO)');
|
|
35
|
+
|
|
36
|
+
layoutCmd
|
|
37
|
+
.command('expand [expression] [path]')
|
|
38
|
+
.description('Expand a layout expression into validated XDS TSX')
|
|
39
|
+
.option('--file <file>', 'Read the expression from a file')
|
|
40
|
+
.option('--form <form>', 'Input surface: compact, outline, or auto', 'auto')
|
|
41
|
+
.option('--name <name>', 'Generated component name (PascalCase)', 'GeneratedLayout')
|
|
42
|
+
.option('--loose', 'Downgrade unknown {block} hints to TODO placeholders')
|
|
43
|
+
.action(async (expression, targetPath, options) => {
|
|
44
|
+
const json = program.opts().json || false;
|
|
45
|
+
const source = await readExpression(expression, options);
|
|
46
|
+
if (!source || source.trim() === '') {
|
|
47
|
+
cliError('No layout expression given — pass it as an argument, via --file, or on stdin');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let result;
|
|
51
|
+
try {
|
|
52
|
+
result = await layoutExpand(source, {
|
|
53
|
+
targetPath,
|
|
54
|
+
form: options.form,
|
|
55
|
+
loose: options.loose || false,
|
|
56
|
+
name: options.name,
|
|
57
|
+
cwd: process.cwd(),
|
|
58
|
+
});
|
|
59
|
+
} catch (e) {
|
|
60
|
+
cliError(e.message, {suggestions: e.suggestions || [], code: e.code});
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (json) return jsonOut(result.type, result.data);
|
|
64
|
+
|
|
65
|
+
for (const warning of result.data.warnings) humanLog(`⚠ ${warning}`);
|
|
66
|
+
if (result.data.written) {
|
|
67
|
+
humanLog(`\n✓ Expanded to ${result.data.written}`);
|
|
68
|
+
humanLog(` Components: ${result.data.componentsUsed.join(', ')}`);
|
|
69
|
+
if (result.data.todos.length > 0) {
|
|
70
|
+
humanLog(` TODOs: ${result.data.todos.length} (search for "TODO(xle)")`);
|
|
71
|
+
}
|
|
72
|
+
humanLog('');
|
|
73
|
+
} else {
|
|
74
|
+
humanLog(result.data.code);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
layoutCmd
|
|
79
|
+
.command('check [expression]')
|
|
80
|
+
.description('Validate a layout expression and echo canonical compact/outline forms')
|
|
81
|
+
.option('--file <file>', 'Read the expression from a file')
|
|
82
|
+
.option('--form <form>', 'Input surface: compact, outline, or auto', 'auto')
|
|
83
|
+
.option('--loose', 'Downgrade unknown {block} hints to TODO placeholders')
|
|
84
|
+
.action(async (expression, options) => {
|
|
85
|
+
const json = program.opts().json || false;
|
|
86
|
+
const source = await readExpression(expression, options);
|
|
87
|
+
if (!source || source.trim() === '') {
|
|
88
|
+
cliError('No layout expression given — pass it as an argument, via --file, or on stdin');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
let result;
|
|
92
|
+
try {
|
|
93
|
+
result = await layoutCheck(source, {
|
|
94
|
+
form: options.form,
|
|
95
|
+
loose: options.loose || false,
|
|
96
|
+
cwd: process.cwd(),
|
|
97
|
+
});
|
|
98
|
+
} catch (e) {
|
|
99
|
+
cliError(e.message, {suggestions: e.suggestions || [], code: e.code});
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (json) return jsonOut(result.type, result.data);
|
|
103
|
+
|
|
104
|
+
const {valid, form, errors, warnings, compact, outline} = result.data;
|
|
105
|
+
if (!valid) {
|
|
106
|
+
humanLog(`\n✗ Invalid (${errors.length} error${errors.length === 1 ? '' : 's'}):`);
|
|
107
|
+
for (const e of errors) {
|
|
108
|
+
humanLog(` - ${e.formatted}`);
|
|
109
|
+
if (e.suggestions?.length > 0) humanLog(` did you mean: ${e.suggestions.join(', ')}?`);
|
|
110
|
+
}
|
|
111
|
+
humanLog('');
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
humanLog(`\n✓ Valid (parsed as ${form})`);
|
|
116
|
+
for (const warning of warnings) humanLog(`⚠ ${warning}`);
|
|
117
|
+
humanLog('\ncompact:');
|
|
118
|
+
humanLog(` ${compact}`);
|
|
119
|
+
humanLog('\noutline:');
|
|
120
|
+
humanLog(outline.split('\n').map(l => ` ${l}`).join('\n'));
|
|
121
|
+
humanLog('');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
layoutCmd
|
|
125
|
+
.command('grammar')
|
|
126
|
+
.description('Print the XLE/XLO cheatsheet (alias table generated from this branch)')
|
|
127
|
+
.action(async () => {
|
|
128
|
+
const json = program.opts().json || false;
|
|
129
|
+
let result;
|
|
130
|
+
try {
|
|
131
|
+
result = await layoutGrammar({cwd: process.cwd()});
|
|
132
|
+
} catch (e) {
|
|
133
|
+
cliError(e.message, {suggestions: e.suggestions || [], code: e.code});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (json) return jsonOut(result.type, result.data);
|
|
137
|
+
humanLog(result.data.text);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
@@ -36,7 +36,7 @@ let markerFile;
|
|
|
36
36
|
let baseEnv;
|
|
37
37
|
|
|
38
38
|
beforeAll(() => {
|
|
39
|
-
shimDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
39
|
+
shimDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-gh-shim-'));
|
|
40
40
|
markerFile = path.join(shimDir, 'gh-issue-create-was-called.marker');
|
|
41
41
|
|
|
42
42
|
// Sabotaged `gh` shim. Records ONLY `gh issue create` invocations to the
|
package/src/commands/swizzle.mjs
CHANGED
|
@@ -15,7 +15,11 @@ import * as fs from 'node:fs';
|
|
|
15
15
|
import * as path from 'node:path';
|
|
16
16
|
import * as p from '@clack/prompts';
|
|
17
17
|
import {findCoreDir, listComponents} from '../utils/paths.mjs';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
assertWithin,
|
|
20
|
+
PathSafetyError,
|
|
21
|
+
isNonInteractive,
|
|
22
|
+
} from '../utils/path-safety.mjs';
|
|
19
23
|
import {isInteractive} from '../utils/interactive.mjs';
|
|
20
24
|
import {jsonOut, humanLog} from '../lib/json.mjs';
|
|
21
25
|
import {cliError} from '../lib/cli-error.mjs';
|
|
@@ -104,7 +108,9 @@ export function registerSwizzle(program) {
|
|
|
104
108
|
}
|
|
105
109
|
humanLog(`\nUsage: astryx swizzle <component>\n`);
|
|
106
110
|
humanLog('Example: astryx swizzle Button');
|
|
107
|
-
humanLog(
|
|
111
|
+
humanLog(
|
|
112
|
+
' astryx swizzle XDSButton (XDS prefix also works)\n',
|
|
113
|
+
);
|
|
108
114
|
return;
|
|
109
115
|
}
|
|
110
116
|
|
|
@@ -112,10 +118,10 @@ export function registerSwizzle(program) {
|
|
|
112
118
|
const componentDir = path.join(coreDir, 'src', dirName);
|
|
113
119
|
|
|
114
120
|
if (!fs.existsSync(componentDir)) {
|
|
115
|
-
cliError(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
);
|
|
121
|
+
cliError(`Component "${component}" not found.`, {
|
|
122
|
+
suggestions: components.slice(0, 10).map(n => ({name: n})),
|
|
123
|
+
code: ERROR_CODES.ERR_UNKNOWN_COMPONENT,
|
|
124
|
+
});
|
|
119
125
|
return;
|
|
120
126
|
}
|
|
121
127
|
|
|
@@ -196,11 +202,16 @@ export function registerSwizzle(program) {
|
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
const relOutput = path.relative(process.cwd(), outputDir);
|
|
199
|
-
const copiedFiles = files.filter(
|
|
205
|
+
const copiedFiles = files.filter(
|
|
206
|
+
f =>
|
|
207
|
+
!f.includes('.test.') &&
|
|
208
|
+
f !== 'README.md' &&
|
|
209
|
+
fs.statSync(path.join(componentDir, f)).isFile(),
|
|
210
|
+
);
|
|
200
211
|
|
|
201
212
|
// --- Gap reporting ---
|
|
202
213
|
|
|
203
|
-
const gapConfig = loadGapReportConfig();
|
|
214
|
+
const gapConfig = await loadGapReportConfig();
|
|
204
215
|
let gapReportUrl = null;
|
|
205
216
|
let gapDryRunPreview = null;
|
|
206
217
|
|
|
@@ -224,7 +235,7 @@ export function registerSwizzle(program) {
|
|
|
224
235
|
json,
|
|
225
236
|
});
|
|
226
237
|
|
|
227
|
-
const preview = buildGapReportPreview(previewArgs);
|
|
238
|
+
const preview = await buildGapReportPreview(previewArgs);
|
|
228
239
|
|
|
229
240
|
if (!willFile) {
|
|
230
241
|
// Dry-run: do NOT call gh. Surface what would have been filed.
|
|
@@ -239,10 +250,12 @@ export function registerSwizzle(program) {
|
|
|
239
250
|
};
|
|
240
251
|
} else if (gapConfig.command || checkGhCli()) {
|
|
241
252
|
try {
|
|
242
|
-
gapReportUrl = createGapReport(previewArgs);
|
|
253
|
+
gapReportUrl = await createGapReport(previewArgs);
|
|
243
254
|
} catch (err) {
|
|
244
255
|
if (!json)
|
|
245
|
-
console.error(
|
|
256
|
+
console.error(
|
|
257
|
+
`Warning: Could not file gap report: ${err.message}`,
|
|
258
|
+
);
|
|
246
259
|
}
|
|
247
260
|
}
|
|
248
261
|
}
|
|
@@ -259,17 +272,23 @@ export function registerSwizzle(program) {
|
|
|
259
272
|
gapReportSuppressed: reportingSuppressed || !gapConfig.enabled,
|
|
260
273
|
});
|
|
261
274
|
humanLog(`\n✓ Copied ${copied} files to ${relOutput}/\n`);
|
|
262
|
-
humanLog(
|
|
275
|
+
humanLog(
|
|
276
|
+
'Relative imports have been rewritten to use @astryxdesign/core.',
|
|
277
|
+
);
|
|
263
278
|
humanLog('You can now customize the component source freely.\n');
|
|
264
279
|
if (gapReportUrl) {
|
|
265
280
|
humanLog(`✓ Gap report filed: ${gapReportUrl}\n`);
|
|
266
281
|
} else if (gapDryRunPreview) {
|
|
267
|
-
humanLog(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
282
|
+
humanLog(
|
|
283
|
+
formatPreview(
|
|
284
|
+
await buildGapReportPreview({
|
|
285
|
+
component: dirName,
|
|
286
|
+
category: options.gapCategory || 'other',
|
|
287
|
+
intention: options.gap,
|
|
288
|
+
source: 'llm-auto',
|
|
289
|
+
}),
|
|
290
|
+
),
|
|
291
|
+
);
|
|
273
292
|
humanLog(
|
|
274
293
|
'\n[dry-run] No gap report was filed. Re-run with --commit to file.',
|
|
275
294
|
);
|
|
@@ -283,10 +302,18 @@ export function registerSwizzle(program) {
|
|
|
283
302
|
return;
|
|
284
303
|
}
|
|
285
304
|
|
|
286
|
-
if (json)
|
|
305
|
+
if (json)
|
|
306
|
+
return jsonOut('swizzle.copy', {
|
|
307
|
+
component: dirName,
|
|
308
|
+
outputDir: relOutput,
|
|
309
|
+
filesCopied: copied,
|
|
310
|
+
files: copiedFiles.map(f => f),
|
|
311
|
+
});
|
|
287
312
|
|
|
288
313
|
humanLog(`\n✓ Copied ${copied} files to ${relOutput}/\n`);
|
|
289
|
-
humanLog(
|
|
314
|
+
humanLog(
|
|
315
|
+
'Relative imports have been rewritten to use @astryxdesign/core.',
|
|
316
|
+
);
|
|
290
317
|
humanLog('You can now customize the component source freely.\n');
|
|
291
318
|
|
|
292
319
|
if (reportingSuppressed || !gapConfig.enabled) {
|
|
@@ -330,7 +357,8 @@ export function registerSwizzle(program) {
|
|
|
330
357
|
placeholder:
|
|
331
358
|
'e.g. "Need a compact variant for use in dense data tables"',
|
|
332
359
|
validate: val => {
|
|
333
|
-
if (!val.trim())
|
|
360
|
+
if (!val.trim())
|
|
361
|
+
return 'Please describe what you were trying to do';
|
|
334
362
|
},
|
|
335
363
|
}),
|
|
336
364
|
);
|
|
@@ -350,7 +378,7 @@ export function registerSwizzle(program) {
|
|
|
350
378
|
source: 'interactive',
|
|
351
379
|
};
|
|
352
380
|
|
|
353
|
-
const preview = buildGapReportPreview(previewArgs);
|
|
381
|
+
const preview = await buildGapReportPreview(previewArgs);
|
|
354
382
|
|
|
355
383
|
p.note(
|
|
356
384
|
`${preview.mode === 'github' ? `Repo: ${preview.repo}` : `Custom command: ${preview.command}`}\n\n` +
|
|
@@ -378,7 +406,7 @@ export function registerSwizzle(program) {
|
|
|
378
406
|
s.start('Filing gap report');
|
|
379
407
|
|
|
380
408
|
try {
|
|
381
|
-
const url = createGapReport(previewArgs);
|
|
409
|
+
const url = await createGapReport(previewArgs);
|
|
382
410
|
s.stop('Gap report filed');
|
|
383
411
|
humanLog(`✓ ${url}\n`);
|
|
384
412
|
} catch (err) {
|
|
@@ -58,7 +58,7 @@ function runCli(args, cwd) {
|
|
|
58
58
|
|
|
59
59
|
let tmpDir;
|
|
60
60
|
beforeEach(() => {
|
|
61
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
61
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-swizzle-paths-'));
|
|
62
62
|
});
|
|
63
63
|
afterEach(() => {
|
|
64
64
|
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
@@ -17,7 +17,7 @@ let tmpDir;
|
|
|
17
17
|
let templateApi;
|
|
18
18
|
|
|
19
19
|
beforeEach(async () => {
|
|
20
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
20
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-template-paths-'));
|
|
21
21
|
templateApi = (await import('../api/template.mjs')).template;
|
|
22
22
|
});
|
|
23
23
|
afterEach(() => {
|