@astryxdesign/cli 0.6.3-canary.ccfce9a → 0.6.3-canary.e073c9f

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.
Files changed (105) hide show
  1. package/api/build/build.type.d.mts +2 -2
  2. package/api/build/build.type.mjs +2 -2
  3. package/api/component/component.type.d.mts +6 -6
  4. package/api/component/component.type.mjs +19 -19
  5. package/api/discover/discover.type.d.mts +4 -4
  6. package/api/discover/discover.type.mjs +10 -10
  7. package/api/docs/docs.type.d.mts +4 -4
  8. package/api/docs/docs.type.mjs +10 -10
  9. package/api/hook/hook.type.d.mts +3 -3
  10. package/api/hook/hook.type.mjs +11 -11
  11. package/api/integration/add-contribution.mjs +5 -3
  12. package/api/integration/add-contribution.test.mjs +4 -4
  13. package/api/integration/pack-check.mjs +49 -7
  14. package/api/integration/pack-check.test.mjs +249 -0
  15. package/api/search/search.type.d.mts +1 -1
  16. package/api/search/search.type.mjs +1 -1
  17. package/api/swizzle/swizzle.type.d.mts +2 -2
  18. package/api/swizzle/swizzle.type.mjs +2 -2
  19. package/api/template/template.type.d.mts +5 -5
  20. package/api/template/template.type.mjs +12 -12
  21. package/api/theme/build/build.mjs +20 -6
  22. package/api/theme/build/build.test.mjs +127 -0
  23. package/api/theme/palette/generate/generate.mjs +1 -1
  24. package/api/theme/palette/generate/generator.d.mts +10 -13
  25. package/api/theme/palette/generate/generator.mjs +7 -3
  26. package/api/theme/theme.type.d.mts +170 -11
  27. package/api/theme/theme.type.mjs +94 -27
  28. package/api/upgrade/upgrade.type.d.mts +4 -4
  29. package/api/upgrade/upgrade.type.mjs +10 -10
  30. package/assets/codemods/integration-discovery.mjs +40 -2
  31. package/assets/codemods/integration-discovery.test.mjs +58 -0
  32. package/assets/docs/cli-integrations.doc.mjs +9 -0
  33. package/assets/docs/styling-libraries.doc.mjs +1 -1
  34. package/assets/docs/working-with-ai.doc.mjs +1 -1
  35. package/authoring/_shared/contract.ts +22 -0
  36. package/authoring/codemod/codemod.doc.mjs +6 -1
  37. package/authoring/codemod/parse.d.mts +8 -8
  38. package/authoring/codemod/parse.mjs +8 -6
  39. package/authoring/config/parse.d.mts +13 -13
  40. package/authoring/config/parse.mjs +8 -8
  41. package/authoring/config/type.ts +3 -3
  42. package/authoring/debug/parse.d.mts +4 -4
  43. package/authoring/debug/parse.mjs +3 -3
  44. package/authoring/doctypes/_schema.d.mts +121 -11
  45. package/authoring/doctypes/_schema.mjs +144 -13
  46. package/authoring/doctypes/base/graph-fields.doc.mjs +11 -4
  47. package/authoring/doctypes/base/type.ts +8 -4
  48. package/authoring/doctypes/command/command.doc.mjs +3 -2
  49. package/authoring/doctypes/command/parse.d.mts +2 -2
  50. package/authoring/doctypes/command/parse.mjs +1 -1
  51. package/authoring/doctypes/command/type.ts +2 -2
  52. package/authoring/doctypes/component/component.doc.mjs +5 -2
  53. package/authoring/doctypes/component/parse.d.mts +2 -2
  54. package/authoring/doctypes/component/parse.mjs +1 -1
  55. package/authoring/doctypes/component/type.ts +1 -1
  56. package/authoring/doctypes/enum/parse.d.mts +2 -2
  57. package/authoring/doctypes/enum/parse.mjs +1 -1
  58. package/authoring/doctypes/enum/type.ts +1 -1
  59. package/authoring/doctypes/function/function.doc.mjs +4 -0
  60. package/authoring/doctypes/function/parse.d.mts +2 -2
  61. package/authoring/doctypes/function/parse.mjs +1 -1
  62. package/authoring/doctypes/function/type.ts +1 -1
  63. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  64. package/authoring/doctypes/hook/parse.d.mts +2 -2
  65. package/authoring/doctypes/hook/parse.mjs +1 -1
  66. package/authoring/doctypes/hook/type.ts +1 -1
  67. package/authoring/doctypes/legacy.d.mts +6 -6
  68. package/authoring/doctypes/legacy.mjs +3 -3
  69. package/authoring/doctypes/load-contract.test.mjs +207 -0
  70. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -3
  71. package/authoring/doctypes/namespace/parse.d.mts +2 -2
  72. package/authoring/doctypes/namespace/parse.mjs +1 -1
  73. package/authoring/doctypes/namespace/type.ts +2 -2
  74. package/authoring/doctypes/parse.d.mts +18 -18
  75. package/authoring/doctypes/parse.mjs +9 -9
  76. package/authoring/doctypes/reference/parse.d.mts +2 -2
  77. package/authoring/doctypes/reference/parse.mjs +1 -1
  78. package/authoring/doctypes/reference/reference.doc.mjs +6 -2
  79. package/authoring/doctypes/reference/type.ts +1 -1
  80. package/authoring/doctypes/schema/parse.d.mts +2 -2
  81. package/authoring/doctypes/schema/parse.mjs +1 -1
  82. package/authoring/doctypes/schema/type.ts +2 -2
  83. package/authoring/doctypes/template/parse.d.mts +92 -1
  84. package/authoring/doctypes/template/parse.mjs +33 -1
  85. package/authoring/doctypes/template/template.doc.mjs +4 -0
  86. package/authoring/doctypes/template/type.ts +4 -1
  87. package/authoring/doctypes/types.ts +10 -10
  88. package/authoring/gap-report/parse.d.mts +9 -9
  89. package/authoring/gap-report/parse.mjs +6 -6
  90. package/authoring/gap-report/type.ts +1 -1
  91. package/authoring/identity/identity.doc.mjs +3 -2
  92. package/authoring/identity/type.ts +10 -10
  93. package/authoring/index.d.ts +19 -19
  94. package/authoring/integration/parse.d.mts +2 -2
  95. package/authoring/integration/parse.mjs +1 -1
  96. package/authoring/integration/schema.d.mts +4 -4
  97. package/authoring/integration/schema.mjs +3 -3
  98. package/authoring/integration/type.ts +1 -1
  99. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  100. package/foundation/discovery/authoring-self-docs.test.mjs +71 -12
  101. package/foundation/discovery/docs-discovery.d.mts +4 -0
  102. package/foundation/discovery/docs-discovery.mjs +16 -2
  103. package/foundation/discovery/docs-discovery.test.mjs +47 -11
  104. package/foundation/discovery/theming-targets.test.mjs +4 -0
  105. package/package.json +9 -11
@@ -2,7 +2,7 @@
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
4
  /**
5
- * xds --json build (no query) — the "how to build a page" playbook signal.
5
+ * astryx --json build (no query) — the "how to build a page" playbook signal.
6
6
  */
7
7
  export type BuildHelpResponse = {
8
8
  type: "build.help";
@@ -11,7 +11,7 @@ export type BuildHelpResponse = {
11
11
  };
12
12
  };
13
13
  /**
14
- * xds --json build "<idea>" — the composition kit for what you're building.
14
+ * astryx --json build "<idea>" — the composition kit for what you're building.
15
15
  *
16
16
  * Entries are raw `SearchResultEntry` objects (no package-manager-prefixed
17
17
  * command strings — the CLI adds those); `frame`/`foundation` are static
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  /**
10
- * xds --json build (no query) — the "how to build a page" playbook signal.
10
+ * astryx --json build (no query) — the "how to build a page" playbook signal.
11
11
  *
12
12
  * @typedef {object} BuildHelpResponse
13
13
  * @property {'build.help'} type
@@ -16,7 +16,7 @@
16
16
  */
17
17
 
18
18
  /**
19
- * xds --json build "<idea>" — the composition kit for what you're building.
19
+ * astryx --json build "<idea>" — the composition kit for what you're building.
20
20
  *
21
21
  * Entries are raw `SearchResultEntry` objects (no package-manager-prefixed
22
22
  * command strings — the CLI adds those); `frame`/`foundation` are static
@@ -2,7 +2,7 @@
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
4
  /**
5
- * xds --json component [--list] [--category X] [--detail names|compact|full]
5
+ * astryx --json component [--list] [--category X] [--detail names|compact|full]
6
6
  *
7
7
  * The list view emits ONE `component.list` type across all three detail levels;
8
8
  * the depth is carried in `data.detail` and `data.components` holds the grouped
@@ -55,7 +55,7 @@ export type ComponentBriefEntry = {
55
55
  import: string;
56
56
  };
57
57
  /**
58
- * xds --json component <name>
58
+ * astryx --json component <name>
59
59
  */
60
60
  export type ComponentDetailResponse = {
61
61
  type: "component.detail";
@@ -81,14 +81,14 @@ export type ComponentOwnership = {
81
81
  sourceAvailable: boolean;
82
82
  };
83
83
  /**
84
- * xds --json component <name> --props
84
+ * astryx --json component <name> --props
85
85
  */
86
86
  export type ComponentDetailPropsResponse = {
87
87
  type: "component.detail.props";
88
88
  data: import("@astryxdesign/cli/authoring").ComponentPropDoc[];
89
89
  };
90
90
  /**
91
- * xds --json component <name> --source
91
+ * astryx --json component <name> --source
92
92
  */
93
93
  export type ComponentDetailSourceResponse = {
94
94
  type: "component.detail.source";
@@ -98,7 +98,7 @@ export type ComponentDetailSourceResponse = {
98
98
  };
99
99
  };
100
100
  /**
101
- * xds --json component <name> --showcase
101
+ * astryx --json component <name> --showcase
102
102
  */
103
103
  export type ComponentDetailShowcaseResponse = {
104
104
  type: "component.detail.showcase";
@@ -109,7 +109,7 @@ export type ComponentDetailShowcaseResponse = {
109
109
  };
110
110
  };
111
111
  /**
112
- * xds --json component <name> --blocks
112
+ * astryx --json component <name> --blocks
113
113
  */
114
114
  export type ComponentDetailBlocksResponse = {
115
115
  type: "component.detail.blocks";
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * @file Colocated types for the `component` command — source of truth for the
5
5
  * component command's JSON responses. These typedefs describe the `{type, data}`
6
- * envelopes emitted by `xds --json component` and returned by the `component()`
6
+ * envelopes emitted by `astryx --json component` and returned by the `component()`
7
7
  * API; the `types/component.d.ts` barrel re-exports them for consumers.
8
8
  *
9
9
  * Detail-level contract for list views (brief < compact < full):
@@ -11,23 +11,23 @@
11
11
  * --detail compact Names + 1-line description + import path.
12
12
  * --detail full Full ComponentDoc per entry (props, theming, examples, etc.).
13
13
  *
14
- * Invocation -> type discriminator
14
+ * Invocation -> type discriminator
15
15
  * ------------------------------------------------------------------
16
- * xds --json component -> component.list (data.detail='names')
17
- * xds --json component --list -> component.list (data.detail='names')
18
- * xds --json component --category Form -> component.list (filtered)
19
- * xds --json component --list --detail compact -> component.list (data.detail='compact')
20
- * xds --json component --list --detail full -> component.list (data.detail='full')
21
- * xds --json component Button -> component.detail
22
- * xds --json component Button --props -> component.detail.props
23
- * xds --json component Button --source -> component.detail.source
24
- * xds --json component Button --showcase -> component.detail.showcase
25
- * xds --json component Button --blocks -> component.detail.blocks
26
- * (not found) -> CLIError
16
+ * astryx --json component -> component.list (data.detail='names')
17
+ * astryx --json component --list -> component.list (data.detail='names')
18
+ * astryx --json component --category Form -> component.list (filtered)
19
+ * astryx --json component --list --detail compact -> component.list (data.detail='compact')
20
+ * astryx --json component --list --detail full -> component.list (data.detail='full')
21
+ * astryx --json component Button -> component.detail
22
+ * astryx --json component Button --props -> component.detail.props
23
+ * astryx --json component Button --source -> component.detail.source
24
+ * astryx --json component Button --showcase -> component.detail.showcase
25
+ * astryx --json component Button --blocks -> component.detail.blocks
26
+ * (not found) -> CLIError
27
27
  */
28
28
 
29
29
  /**
30
- * xds --json component [--list] [--category X] [--detail names|compact|full]
30
+ * astryx --json component [--list] [--category X] [--detail names|compact|full]
31
31
  *
32
32
  * The list view emits ONE `component.list` type across all three detail levels;
33
33
  * the depth is carried in `data.detail` and `data.components` holds the grouped
@@ -70,7 +70,7 @@
70
70
  */
71
71
 
72
72
  /**
73
- * xds --json component <name>
73
+ * astryx --json component <name>
74
74
  * @typedef {object} ComponentDetailResponse
75
75
  * @property {'component.detail'} type
76
76
  * @property {import('@astryxdesign/cli/authoring').ComponentDoc & ComponentOwnership} data
@@ -87,28 +87,28 @@
87
87
  */
88
88
 
89
89
  /**
90
- * xds --json component <name> --props
90
+ * astryx --json component <name> --props
91
91
  * @typedef {object} ComponentDetailPropsResponse
92
92
  * @property {'component.detail.props'} type
93
93
  * @property {import('@astryxdesign/cli/authoring').ComponentPropDoc[]} data
94
94
  */
95
95
 
96
96
  /**
97
- * xds --json component <name> --source
97
+ * astryx --json component <name> --source
98
98
  * @typedef {object} ComponentDetailSourceResponse
99
99
  * @property {'component.detail.source'} type
100
100
  * @property {{component: string; source: string}} data
101
101
  */
102
102
 
103
103
  /**
104
- * xds --json component <name> --showcase
104
+ * astryx --json component <name> --showcase
105
105
  * @typedef {object} ComponentDetailShowcaseResponse
106
106
  * @property {'component.detail.showcase'} type
107
107
  * @property {{component: string; aspectRatio: number; source: string}} data
108
108
  */
109
109
 
110
110
  /**
111
- * xds --json component <name> --blocks
111
+ * astryx --json component <name> --blocks
112
112
  * @typedef {object} ComponentDetailBlocksResponse
113
113
  * @property {'component.detail.blocks'} type
114
114
  * @property {{component: string; showcase: BlockEntry | null; examples: BlockEntry[]; related: BlockEntry[]}} data
@@ -2,7 +2,7 @@
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
4
  /**
5
- * xds --json discover
5
+ * astryx --json discover
6
6
  */
7
7
  export type DiscoverListResponse = {
8
8
  type: "discover.list";
@@ -25,21 +25,21 @@ export type DiscoverListEntry = {
25
25
  displayName?: string | undefined;
26
26
  };
27
27
  /**
28
- * xds --json discover
28
+ * astryx --json discover
29
29
  */
30
30
  export type DiscoverDetailResponse = {
31
31
  type: "discover.detail";
32
32
  data: DiscoverListEntry;
33
33
  };
34
34
  /**
35
- * xds --json discover
35
+ * astryx --json discover
36
36
  */
37
37
  export type DiscoverDetailDocResponse = {
38
38
  type: "discover.detail.doc";
39
39
  data: import("@astryxdesign/cli/authoring").ComponentDoc;
40
40
  };
41
41
  /**
42
- * xds --json discover <searchterm> (multiple matches)
42
+ * astryx --json discover <searchterm> (multiple matches)
43
43
  */
44
44
  export type DiscoverSearchResponse = {
45
45
  type: "discover.search";
@@ -6,16 +6,16 @@
6
6
  *
7
7
  * Invocation -> type discriminator
8
8
  * ------------------------------------------------------------------
9
- * xds --json discover -> discover.list
10
- * xds --json discover @scope/name -> discover.detail
11
- * xds --json discover @scope/name/Component -> discover.detail.doc
12
- * xds --json discover <searchterm> (1 match) -> discover.detail.doc
13
- * xds --json discover <searchterm> (N matches) -> discover.search
14
- * (not found) -> CLIError
9
+ * astryx --json discover -> discover.list
10
+ * astryx --json discover @scope/name -> discover.detail
11
+ * astryx --json discover @scope/name/Component -> discover.detail.doc
12
+ * astryx --json discover <searchterm> (1 match) -> discover.detail.doc
13
+ * astryx --json discover <searchterm> (N matches) -> discover.search
14
+ * (not found) -> CLIError
15
15
  */
16
16
 
17
17
  /**
18
- * xds --json discover
18
+ * astryx --json discover
19
19
  * @typedef {object} DiscoverListResponse
20
20
  * @property {'discover.list'} type
21
21
  * @property {DiscoverListEntry[]} data
@@ -35,21 +35,21 @@
35
35
  */
36
36
 
37
37
  /**
38
- * xds --json discover @scope/name
38
+ * astryx --json discover @scope/name
39
39
  * @typedef {object} DiscoverDetailResponse
40
40
  * @property {'discover.detail'} type
41
41
  * @property {DiscoverListEntry} data
42
42
  */
43
43
 
44
44
  /**
45
- * xds --json discover @scope/name/Component
45
+ * astryx --json discover @scope/name/Component
46
46
  * @typedef {object} DiscoverDetailDocResponse
47
47
  * @property {'discover.detail.doc'} type
48
48
  * @property {import('@astryxdesign/cli/authoring').ComponentDoc} data
49
49
  */
50
50
 
51
51
  /**
52
- * xds --json discover <searchterm> (multiple matches)
52
+ * astryx --json discover <searchterm> (multiple matches)
53
53
  * @typedef {object} DiscoverSearchResponse
54
54
  * @property {'discover.search'} type
55
55
  * @property {{query: string, matches: DiscoverSearchEntry[]}} data
@@ -2,7 +2,7 @@
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
4
  /**
5
- * xds --json docs
5
+ * astryx --json docs
6
6
  */
7
7
  export type DocsListResponse = {
8
8
  type: "docs.list";
@@ -23,14 +23,14 @@ export type DocsListEntry = {
23
23
  replaces?: string | undefined;
24
24
  };
25
25
  /**
26
- * xds --json docs <topic> --index
26
+ * astryx --json docs <topic> --index
27
27
  */
28
28
  export type DocsIndexResponse = {
29
29
  type: "docs.index";
30
30
  data: DocsIndex;
31
31
  };
32
32
  /**
33
- * xds --json docs <topic>
33
+ * astryx --json docs <topic>
34
34
  */
35
35
  export type DocsDetailResponse = {
36
36
  type: "docs.detail";
@@ -62,7 +62,7 @@ export type DocsIndexSection = {
62
62
  summary: string;
63
63
  };
64
64
  /**
65
- * xds --json docs <topic> <section>
65
+ * astryx --json docs <topic> <section>
66
66
  */
67
67
  export type DocsDetailSectionResponse = {
68
68
  type: "docs.detail.section";
@@ -4,17 +4,17 @@
4
4
  * @file Colocated types for the `docs` command — source of truth for the docs
5
5
  * command JSON responses. `types/docs.d.ts` re-exports these.
6
6
  *
7
- * Invocation -> type discriminator
7
+ * Invocation -> type discriminator
8
8
  * ------------------------------------------------------------
9
- * xds --json docs -> docs.list
10
- * xds --json docs <topic> -> docs.detail
11
- * xds --json docs <topic> --index -> docs.index
12
- * xds --json docs <topic> <section> -> docs.detail.section
13
- * (unknown topic/section) -> CLIError
9
+ * astryx --json docs -> docs.list
10
+ * astryx --json docs <topic> -> docs.detail
11
+ * astryx --json docs <topic> --index -> docs.index
12
+ * astryx --json docs <topic> <section> -> docs.detail.section
13
+ * (unknown topic/section) -> CLIError
14
14
  */
15
15
 
16
16
  /**
17
- * xds --json docs
17
+ * astryx --json docs
18
18
  * @typedef {object} DocsListResponse
19
19
  * @property {'docs.list'} type
20
20
  * @property {DocsListEntry[]} data
@@ -31,14 +31,14 @@
31
31
  */
32
32
 
33
33
  /**
34
- * xds --json docs <topic> --index
34
+ * astryx --json docs <topic> --index
35
35
  * @typedef {object} DocsIndexResponse
36
36
  * @property {'docs.index'} type
37
37
  * @property {DocsIndex} data
38
38
  */
39
39
 
40
40
  /**
41
- * xds --json docs <topic>
41
+ * astryx --json docs <topic>
42
42
  * @typedef {object} DocsDetailResponse
43
43
  * @property {'docs.detail'} type
44
44
  * @property {import('@astryxdesign/cli/authoring').ReferenceDoc} data
@@ -63,7 +63,7 @@
63
63
  */
64
64
 
65
65
  /**
66
- * xds --json docs <topic> <section>
66
+ * astryx --json docs <topic> <section>
67
67
  * @typedef {object} DocsDetailSectionResponse
68
68
  * @property {'docs.detail.section'} type
69
69
  * @property {import('@astryxdesign/cli/authoring').ReferenceSection} data
@@ -4,7 +4,7 @@
4
4
  export type HookDoc = import("@astryxdesign/cli/authoring").HookDoc;
5
5
  export type HookParamDoc = import("@astryxdesign/cli/authoring").HookParamDoc;
6
6
  /**
7
- * xds --json hook [--list] [--category X] [--detail names|compact|full]
7
+ * astryx --json hook [--list] [--category X] [--detail names|compact|full]
8
8
  *
9
9
  * The list view emits ONE `hook.list` type across all three detail levels; the
10
10
  * depth is carried in `data.detail` and `data.components` holds the grouped map
@@ -39,14 +39,14 @@ export type HookBriefEntry = {
39
39
  import: string;
40
40
  };
41
41
  /**
42
- * xds --json hook <name>
42
+ * astryx --json hook <name>
43
43
  */
44
44
  export type HookDetailResponse = {
45
45
  type: "hook.detail";
46
46
  data: HookDoc;
47
47
  };
48
48
  /**
49
- * xds --json hook <name> --params
49
+ * astryx --json hook <name> --params
50
50
  */
51
51
  export type HookDetailParamsResponse = {
52
52
  type: "hook.detail.params";
@@ -11,14 +11,14 @@
11
11
  *
12
12
  * Invocation -> type discriminator
13
13
  * ------------------------------------------------------------------
14
- * xds --json hook -> hook.list (data.detail='names')
15
- * xds --json hook --list -> hook.list (data.detail='names')
16
- * xds --json hook --category State -> hook.list (filtered)
17
- * xds --json hook --list --detail compact -> hook.list (data.detail='compact')
18
- * xds --json hook --list --detail full -> hook.list (data.detail='full')
19
- * xds --json hook useMediaQuery -> hook.detail
20
- * xds --json hook useMediaQuery --params -> hook.detail.params
21
- * (not found) -> CLIError
14
+ * astryx --json hook -> hook.list (data.detail='names')
15
+ * astryx --json hook --list -> hook.list (data.detail='names')
16
+ * astryx --json hook --category State -> hook.list (filtered)
17
+ * astryx --json hook --list --detail compact -> hook.list (data.detail='compact')
18
+ * astryx --json hook --list --detail full -> hook.list (data.detail='full')
19
+ * astryx --json hook useMediaQuery -> hook.detail
20
+ * astryx --json hook useMediaQuery --params -> hook.detail.params
21
+ * (not found) -> CLIError
22
22
  */
23
23
 
24
24
  // Re-export the authored-doc types from core so the hook leaves reference these
@@ -28,7 +28,7 @@
28
28
  /** @typedef {import('@astryxdesign/cli/authoring').HookParamDoc} HookParamDoc */
29
29
 
30
30
  /**
31
- * xds --json hook [--list] [--category X] [--detail names|compact|full]
31
+ * astryx --json hook [--list] [--category X] [--detail names|compact|full]
32
32
  *
33
33
  * The list view emits ONE `hook.list` type across all three detail levels; the
34
34
  * depth is carried in `data.detail` and `data.components` holds the grouped map
@@ -56,14 +56,14 @@
56
56
  */
57
57
 
58
58
  /**
59
- * xds --json hook <name>
59
+ * astryx --json hook <name>
60
60
  * @typedef {object} HookDetailResponse
61
61
  * @property {'hook.detail'} type
62
62
  * @property {HookDoc} data
63
63
  */
64
64
 
65
65
  /**
66
- * xds --json hook <name> --params
66
+ * astryx --json hook <name> --params
67
67
  * @typedef {object} HookDetailParamsResponse
68
68
  * @property {'hook.detail.params'} type
69
69
  * @property {HookParamDoc[]} data
@@ -250,7 +250,8 @@ async function addComponent(name, options) {
250
250
  }
251
251
 
252
252
  const sourcePath = projectPath(path.relative(packageDir, sourceFile));
253
- const importSpecifier = `${owner}/${sourcePath}`;
253
+ const extensionlessPath = sourcePath.replace(/\.tsx?$/u, '');
254
+ const importSpecifier = `${owner}/${extensionlessPath}`;
254
255
  const docContents = `export default {\n type: 'component',\n name: '${name}',\n import: ${JSON.stringify(importSpecifier)},\n description: '${name} component.',\n props: [],\n};\n`;
255
256
  const sourceContents = `export function ${name}() {\n return <div>${name}</div>;\n}\n`;
256
257
 
@@ -263,7 +264,7 @@ async function addComponent(name, options) {
263
264
  packageFile,
264
265
  rootPath,
265
266
  path.basename(manifestFile),
266
- [{subpath: sourcePath, target: sourcePath}],
267
+ [{subpath: extensionlessPath, target: sourcePath}],
267
268
  );
268
269
  if (pkgUpdate != null) {
269
270
  plans.push({
@@ -576,6 +577,7 @@ async function addTemplate(name, options) {
576
577
 
577
578
  const pascalName = kebabToPascal(name);
578
579
  const sourcePath = projectPath(path.relative(packageDir, sourceFile));
580
+ const extensionlessPath = sourcePath.replace(/\.tsx?$/u, '');
579
581
  const specContents = `export default {\n type: '${templateType}',\n name: '${name}',\n description: '${kebabToTitle(name)} template.',\n};\n`;
580
582
  const sourceContents = `export default function ${pascalName}() {\n return <div>${kebabToTitle(name)}</div>;\n}\n`;
581
583
 
@@ -588,7 +590,7 @@ async function addTemplate(name, options) {
588
590
  packageFile,
589
591
  rootPath,
590
592
  path.basename(manifestFile),
591
- [{subpath: sourcePath, target: sourcePath}],
593
+ [{subpath: extensionlessPath, target: sourcePath}],
592
594
  );
593
595
  if (pkgUpdate != null) {
594
596
  plans.push({
@@ -118,14 +118,14 @@ describe('integrationAdd component', () => {
118
118
  );
119
119
  expect(pkg.exports).toEqual({
120
120
  '.': './index.mjs',
121
- './components/MyWidget.tsx': './components/MyWidget.tsx',
121
+ './components/MyWidget': './components/MyWidget.tsx',
122
122
  });
123
123
  expect(
124
124
  fs.readFileSync(
125
125
  path.join(tmpDir, 'components/MyWidget.doc.mjs'),
126
126
  'utf-8',
127
127
  ),
128
- ).toContain('import: "@acme/integration/components/MyWidget.tsx"');
128
+ ).toContain('import: "@acme/integration/components/MyWidget"');
129
129
  });
130
130
 
131
131
  it('does not create exports when the package has no exports map', async () => {
@@ -143,7 +143,7 @@ describe('integrationAdd component', () => {
143
143
  setup({
144
144
  exports: {
145
145
  '.': './index.mjs',
146
- './components/MyWidget.tsx': './different.tsx',
146
+ './components/MyWidget': './different.tsx',
147
147
  },
148
148
  });
149
149
 
@@ -421,7 +421,7 @@ describe('integrationAdd template', () => {
421
421
  );
422
422
  expect(pkg.exports).toEqual({
423
423
  '.': './index.mjs',
424
- './templates/my-widget.tsx': './templates/my-widget.tsx',
424
+ './templates/my-widget': './templates/my-widget.tsx',
425
425
  });
426
426
  });
427
427
 
@@ -388,6 +388,14 @@ async function validatePackedComponentExports(integration, scratchBase) {
388
388
  components.map(component => component.specifier),
389
389
  scratchBase,
390
390
  );
391
+ issues.push(
392
+ ...validateSpecifierExtensions(
393
+ components.map(({name, specifier}) => ({
394
+ label: `Component "${name}"`,
395
+ specifier,
396
+ })),
397
+ ),
398
+ );
391
399
  for (const {name, specifier} of components) {
392
400
  const result = resolved.get(specifier);
393
401
  if (!result?.url || result.error) {
@@ -427,19 +435,27 @@ async function validatePackedComponentExports(integration, scratchBase) {
427
435
  */
428
436
  async function validatePackedTemplateExports(integration, scratchBase) {
429
437
  const {templates} = await discoverIntegrationTemplatesForOne(integration);
430
- const entries = templates.map(template => ({
431
- id: template.dirName,
432
- specifier: `${integration.name}/${path
438
+ const entries = templates.map(template => {
439
+ const relPath = path
433
440
  .relative(integration.__packageDir, template.filePath)
434
441
  .split(path.sep)
435
- .join('/')}`,
436
- }));
442
+ .join('/');
443
+ const extensionless = relPath.replace(/\.tsx?$/u, '');
444
+ return {
445
+ id: template.dirName,
446
+ specifier: `${integration.name}/${extensionless}`,
447
+ };
448
+ });
437
449
  const resolved = resolveConsumerSpecifiers(
438
450
  entries.map(entry => entry.specifier),
439
451
  scratchBase,
440
452
  );
441
- /** @type {Issue[]} */
442
- const issues = [];
453
+ const issues = validateSpecifierExtensions(
454
+ entries.map(({id, specifier}) => ({
455
+ label: `Template "${id}"`,
456
+ specifier,
457
+ })),
458
+ );
443
459
  for (const {id, specifier} of entries) {
444
460
  const result = resolved.get(specifier);
445
461
  if (!result?.url || result.error) {
@@ -469,6 +485,32 @@ async function validatePackedTemplateExports(integration, scratchBase) {
469
485
  return issues;
470
486
  }
471
487
 
488
+ const TS_EXTENSION_RE = /\.tsx?$/u;
489
+
490
+ /**
491
+ * Reject specifiers that end in a TypeScript extension — they fail under
492
+ * default `moduleResolution` with TS5097/TS2307 unless the consumer enables
493
+ * `allowImportingTsExtensions`.
494
+ *
495
+ * @param {Array<{label: string, specifier: string}>} entries
496
+ * @returns {Issue[]}
497
+ */
498
+ function validateSpecifierExtensions(entries) {
499
+ /** @type {Issue[]} */
500
+ const issues = [];
501
+ for (const {label, specifier} of entries) {
502
+ if (TS_EXTENSION_RE.test(specifier)) {
503
+ issues.push(
504
+ error(
505
+ 'typescript_extension_in_specifier',
506
+ `${label} advertises import "${specifier}", which ends in a TypeScript extension. A consumer with default moduleResolution will reject it (TS5097). Use an extensionless specifier mapped through the package exports.`,
507
+ ),
508
+ );
509
+ }
510
+ }
511
+ return issues;
512
+ }
513
+
472
514
  /**
473
515
  * Verify an integration package is ready to publish.
474
516
  *