@agents-inc/cli 0.34.1 → 0.38.0
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 +45 -0
- package/config/skills-matrix.yaml +26 -26
- package/config/stacks.yaml +8 -8
- package/dist/{chunk-HTTPKSL6.js → chunk-2XX4TMCI.js} +2 -2
- package/dist/{chunk-CEWNZQMH.js → chunk-3E2V5YL3.js} +8 -2
- package/dist/chunk-3E2V5YL3.js.map +1 -0
- package/dist/{chunk-QC37C32G.js → chunk-3NQJOJZL.js} +3 -3
- package/dist/chunk-54ZZCWN4.js +51 -0
- package/dist/chunk-54ZZCWN4.js.map +1 -0
- package/dist/{chunk-VEZ2GZEK.js → chunk-ATLRUR3B.js} +2 -2
- package/dist/{chunk-ZI5EBHCC.js → chunk-CYFU3ARY.js} +38 -17
- package/dist/chunk-CYFU3ARY.js.map +1 -0
- package/dist/{chunk-X7SPCWY6.js → chunk-DUQFF45G.js} +14 -9
- package/dist/chunk-DUQFF45G.js.map +1 -0
- package/dist/{chunk-CB7GYRUP.js → chunk-EISBUEBL.js} +101 -52
- package/dist/chunk-EISBUEBL.js.map +1 -0
- package/dist/chunk-EXFVAEPY.js +80 -0
- package/dist/chunk-EXFVAEPY.js.map +1 -0
- package/dist/{chunk-ANGAZ444.js → chunk-FWQK3HWB.js} +4 -4
- package/dist/chunk-FWQK3HWB.js.map +1 -0
- package/dist/{chunk-DC5AK3LW.js → chunk-GG4BSB6S.js} +5 -11
- package/dist/chunk-GG4BSB6S.js.map +1 -0
- package/dist/{chunk-GGHH3KR2.js → chunk-HKDE4LJW.js} +2 -2
- package/dist/{chunk-R3AD6XBJ.js → chunk-HRMQ2RGY.js} +81 -26
- package/dist/chunk-HRMQ2RGY.js.map +1 -0
- package/dist/{chunk-YPJKOM42.js → chunk-HRW7BIDE.js} +2 -2
- package/dist/{chunk-LFHZBF6N.js → chunk-IVIK776Y.js} +4 -3
- package/dist/chunk-IVIK776Y.js.map +1 -0
- package/dist/{chunk-ALS7SH7X.js → chunk-IWNPFIGY.js} +38 -48
- package/dist/chunk-IWNPFIGY.js.map +1 -0
- package/dist/{chunk-GIFEDW27.js → chunk-IZRVFC2Z.js} +7 -7
- package/dist/chunk-IZRVFC2Z.js.map +1 -0
- package/dist/chunk-K77I4XGL.js +47 -0
- package/dist/chunk-K77I4XGL.js.map +1 -0
- package/dist/{chunk-JMVWYAHT.js → chunk-KUV24B5M.js} +4 -4
- package/dist/chunk-KUV24B5M.js.map +1 -0
- package/dist/{chunk-KENWMEKN.js → chunk-M6PGIZNS.js} +6 -6
- package/dist/{chunk-B47QYIUL.js → chunk-NFV4SKH5.js} +4 -4
- package/dist/chunk-NI2RSNWB.js +156 -0
- package/dist/chunk-NI2RSNWB.js.map +1 -0
- package/dist/{chunk-ZP4BI6J2.js → chunk-OEX5JDQD.js} +7 -7
- package/dist/chunk-OEX5JDQD.js.map +1 -0
- package/dist/{chunk-OKILA27U.js → chunk-TA6IIQI4.js} +86 -99
- package/dist/chunk-TA6IIQI4.js.map +1 -0
- package/dist/{chunk-JZOLJVWA.js → chunk-TBDIR6LY.js} +12 -11
- package/dist/chunk-TBDIR6LY.js.map +1 -0
- package/dist/{chunk-XYCN2GCV.js → chunk-TNFACSWF.js} +3 -3
- package/dist/{chunk-ZE355C6C.js → chunk-TY5GELDB.js} +9 -4
- package/dist/chunk-TY5GELDB.js.map +1 -0
- package/dist/{chunk-TM4I4EHK.js → chunk-U5OB5ADP.js} +2829 -2793
- package/dist/chunk-U5OB5ADP.js.map +1 -0
- package/dist/{chunk-JXMRTHDT.js → chunk-UOMMQ5M6.js} +2 -2
- package/dist/{chunk-A5CYQQVG.js → chunk-UV6JUGIY.js} +2 -2
- package/dist/{chunk-5YNZJ5TP.js → chunk-VAHVSQIG.js} +2 -2
- package/dist/{chunk-TKB4O2RY.js → chunk-VAK5PX72.js} +5 -5
- package/dist/chunk-WSGGJKD5.js +113 -0
- package/dist/chunk-WSGGJKD5.js.map +1 -0
- package/dist/{chunk-GVMA2EKC.js → chunk-YHQNTBBN.js} +2 -2
- package/dist/{chunk-NLR6Z37M.js → chunk-YJIJTBSX.js} +81 -97
- package/dist/chunk-YJIJTBSX.js.map +1 -0
- package/dist/{chunk-YCS7GF6Y.js → chunk-ZBJQXDQN.js} +3 -1
- package/dist/{chunk-YCS7GF6Y.js.map → chunk-ZBJQXDQN.js.map} +1 -1
- package/dist/cli/defaults/agent-mappings.yaml +4 -4
- package/dist/commands/build/marketplace.js +3 -3
- package/dist/commands/build/plugins.js +5 -5
- package/dist/commands/build/stack.js +5 -5
- package/dist/commands/compile.js +25 -19
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/get.js +8 -8
- package/dist/commands/config/get.js.map +1 -1
- package/dist/commands/config/index.js +5 -5
- package/dist/commands/config/path.js +4 -4
- package/dist/commands/config/set-project.js +7 -7
- package/dist/commands/config/set-project.js.map +1 -1
- package/dist/commands/config/show.js +5 -5
- package/dist/commands/config/unset-project.js +5 -5
- package/dist/commands/config/unset-project.js.map +1 -1
- package/dist/commands/diff.js +8 -8
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +4 -4
- package/dist/commands/edit.js +37 -28
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +6 -6
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +16 -16
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +5 -5
- package/dist/commands/init.js +31 -26
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +4 -4
- package/dist/commands/new/agent.js +5 -5
- package/dist/commands/new/skill.js +8 -8
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +4 -4
- package/dist/commands/search.js +7 -7
- package/dist/commands/uninstall.js +181 -97
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +6 -6
- package/dist/commands/validate.js +5 -5
- package/dist/commands/version/bump.js +4 -4
- package/dist/commands/version/index.js +4 -4
- package/dist/commands/version/set.js +4 -4
- package/dist/commands/version/show.js +4 -4
- package/dist/components/skill-search/skill-search.js +3 -3
- package/dist/components/wizard/category-grid.js +3 -3
- package/dist/components/wizard/category-grid.test.js +42 -21
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +10 -0
- package/dist/components/wizard/checkbox-grid.test.js +260 -0
- package/dist/components/wizard/checkbox-grid.test.js.map +1 -0
- package/dist/components/wizard/domain-selection.js +7 -5
- package/dist/components/wizard/help-modal.js +2 -2
- package/dist/components/wizard/menu-item.js +2 -2
- package/dist/components/wizard/search-modal.js +3 -3
- package/dist/components/wizard/search-modal.test.js +3 -3
- package/dist/components/wizard/section-progress.js +2 -2
- package/dist/components/wizard/section-progress.test.js +2 -2
- package/dist/components/wizard/source-grid.js +5 -5
- package/dist/components/wizard/source-grid.test.js +5 -5
- package/dist/components/wizard/stack-selection.js +8 -7
- package/dist/components/wizard/step-agents.js +16 -0
- package/dist/components/wizard/step-agents.js.map +1 -0
- package/dist/components/wizard/step-agents.test.js +185 -0
- package/dist/components/wizard/step-agents.test.js.map +1 -0
- package/dist/components/wizard/step-build.js +9 -7
- package/dist/components/wizard/step-build.test.js +25 -22
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +2 -2
- package/dist/components/wizard/step-confirm.test.js +6 -5
- package/dist/components/wizard/step-confirm.test.js.map +1 -1
- package/dist/components/wizard/step-refine.js +2 -2
- package/dist/components/wizard/step-refine.test.js +2 -2
- package/dist/components/wizard/step-settings.js +6 -6
- package/dist/components/wizard/step-settings.test.js +9 -9
- package/dist/components/wizard/step-sources.js +12 -10
- package/dist/components/wizard/step-sources.test.js +14 -12
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +11 -9
- package/dist/components/wizard/step-stack.test.js +12 -10
- package/dist/components/wizard/step-stack.test.js.map +1 -1
- package/dist/components/wizard/view-title.js +2 -2
- package/dist/components/wizard/wizard-layout.js +8 -7
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard-tabs.test.js +6 -4
- package/dist/components/wizard/wizard-tabs.test.js.map +1 -1
- package/dist/components/wizard/wizard.js +27 -23
- package/dist/config/skills-matrix.yaml +26 -26
- package/dist/config/stacks.yaml +8 -8
- package/dist/hooks/init.js +5 -3
- package/dist/hooks/init.js.map +1 -1
- package/dist/{source-manager-WJYANKDI.js → source-manager-FEGVYDFZ.js} +4 -4
- package/dist/source-manager-FEGVYDFZ.js.map +1 -0
- package/dist/stores/wizard-store.js +5 -4
- package/dist/stores/wizard-store.test.js +287 -15
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +1 -1
- package/src/schemas/agent.schema.json +3 -3
- package/src/schemas/metadata.schema.json +14 -14
- package/src/schemas/project-config.schema.json +46 -2
- package/src/schemas/project-source-config.schema.json +17 -5
- package/src/schemas/skills-matrix.schema.json +4 -4
- package/src/schemas/stack.schema.json +1 -1
- package/src/schemas/stacks.schema.json +42 -1
- package/dist/chunk-2LUXM5FB.js +0 -277
- package/dist/chunk-2LUXM5FB.js.map +0 -1
- package/dist/chunk-ALS7SH7X.js.map +0 -1
- package/dist/chunk-ANGAZ444.js.map +0 -1
- package/dist/chunk-CB7GYRUP.js.map +0 -1
- package/dist/chunk-CEWNZQMH.js.map +0 -1
- package/dist/chunk-DC5AK3LW.js.map +0 -1
- package/dist/chunk-GIFEDW27.js.map +0 -1
- package/dist/chunk-JMVWYAHT.js.map +0 -1
- package/dist/chunk-JZOLJVWA.js.map +0 -1
- package/dist/chunk-LFHZBF6N.js.map +0 -1
- package/dist/chunk-NLR6Z37M.js.map +0 -1
- package/dist/chunk-OKILA27U.js.map +0 -1
- package/dist/chunk-R3AD6XBJ.js.map +0 -1
- package/dist/chunk-TM4I4EHK.js.map +0 -1
- package/dist/chunk-X7SPCWY6.js.map +0 -1
- package/dist/chunk-ZE355C6C.js.map +0 -1
- package/dist/chunk-ZI5EBHCC.js.map +0 -1
- package/dist/chunk-ZP4BI6J2.js.map +0 -1
- /package/dist/{chunk-HTTPKSL6.js.map → chunk-2XX4TMCI.js.map} +0 -0
- /package/dist/{chunk-QC37C32G.js.map → chunk-3NQJOJZL.js.map} +0 -0
- /package/dist/{chunk-VEZ2GZEK.js.map → chunk-ATLRUR3B.js.map} +0 -0
- /package/dist/{chunk-GGHH3KR2.js.map → chunk-HKDE4LJW.js.map} +0 -0
- /package/dist/{chunk-YPJKOM42.js.map → chunk-HRW7BIDE.js.map} +0 -0
- /package/dist/{chunk-KENWMEKN.js.map → chunk-M6PGIZNS.js.map} +0 -0
- /package/dist/{chunk-B47QYIUL.js.map → chunk-NFV4SKH5.js.map} +0 -0
- /package/dist/{chunk-XYCN2GCV.js.map → chunk-TNFACSWF.js.map} +0 -0
- /package/dist/{chunk-JXMRTHDT.js.map → chunk-UOMMQ5M6.js.map} +0 -0
- /package/dist/{chunk-A5CYQQVG.js.map → chunk-UV6JUGIY.js.map} +0 -0
- /package/dist/{chunk-5YNZJ5TP.js.map → chunk-VAHVSQIG.js.map} +0 -0
- /package/dist/{chunk-TKB4O2RY.js.map → chunk-VAK5PX72.js.map} +0 -0
- /package/dist/{chunk-GVMA2EKC.js.map → chunk-YHQNTBBN.js.map} +0 -0
- /package/dist/{source-manager-WJYANKDI.js.map → components/wizard/checkbox-grid.js.map} +0 -0
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SourceGrid
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EISBUEBL.js";
|
|
5
|
+
import {
|
|
6
|
+
useMeasuredHeight
|
|
7
|
+
} from "./chunk-K77I4XGL.js";
|
|
5
8
|
import {
|
|
6
9
|
ViewTitle
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2XX4TMCI.js";
|
|
8
11
|
import {
|
|
9
12
|
useWizardStore
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-HRMQ2RGY.js";
|
|
11
14
|
import {
|
|
12
15
|
resolveAllSources,
|
|
13
16
|
searchExtraSources
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-U5OB5ADP.js";
|
|
15
18
|
import {
|
|
16
19
|
CLI_COLORS,
|
|
17
20
|
DEFAULT_BRANDING
|
|
18
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ZBJQXDQN.js";
|
|
19
22
|
import {
|
|
20
23
|
init_esm_shims
|
|
21
24
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -35,6 +38,7 @@ var StepSources = ({
|
|
|
35
38
|
const [view, setView] = useState("choice");
|
|
36
39
|
const [choiceIndex, setChoiceIndex] = useState(0);
|
|
37
40
|
const [isGridSearching, setIsGridSearching] = useState(false);
|
|
41
|
+
const { ref: gridRef, measuredHeight: gridHeight } = useMeasuredHeight();
|
|
38
42
|
const handleGridSelect = useCallback(
|
|
39
43
|
(skillId, sourceId) => {
|
|
40
44
|
store.setSourceSelection(skillId, sourceId);
|
|
@@ -97,18 +101,19 @@ var StepSources = ({
|
|
|
97
101
|
});
|
|
98
102
|
if (view === "customize") {
|
|
99
103
|
const rows2 = store.buildSourceRows(matrix);
|
|
100
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "100%", children: [
|
|
104
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "100%", flexGrow: 1, flexBasis: 0, children: [
|
|
101
105
|
/* @__PURE__ */ jsx(ViewTitle, { children: "Customize skill sources" }),
|
|
102
|
-
/* @__PURE__ */ jsx(
|
|
106
|
+
/* @__PURE__ */ jsx(Box, { ref: gridRef, flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsx(
|
|
103
107
|
SourceGrid,
|
|
104
108
|
{
|
|
105
109
|
rows: rows2,
|
|
110
|
+
availableHeight: gridHeight,
|
|
106
111
|
onSelect: handleGridSelect,
|
|
107
112
|
onSearch: handleSearch,
|
|
108
113
|
onBind: handleBind,
|
|
109
114
|
onSearchStateChange: handleSearchStateChange
|
|
110
115
|
}
|
|
111
|
-
)
|
|
116
|
+
) })
|
|
112
117
|
] });
|
|
113
118
|
}
|
|
114
119
|
const selectedTechnologies = store.getAllSelectedTechnologies();
|
|
@@ -186,4 +191,4 @@ var StepSources = ({
|
|
|
186
191
|
export {
|
|
187
192
|
StepSources
|
|
188
193
|
};
|
|
189
|
-
//# sourceMappingURL=chunk-
|
|
194
|
+
//# sourceMappingURL=chunk-DUQFF45G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/step-sources.tsx"],"sourcesContent":["import React, { useState, useCallback } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport type {\n BoundSkillCandidate,\n MergedSkillsMatrix,\n SkillAlias,\n SkillId,\n} from \"../../types/index.js\";\nimport { CLI_COLORS, DEFAULT_BRANDING } from \"../../consts.js\";\nimport { useMeasuredHeight } from \"../hooks/use-measured-height.js\";\nimport { SourceGrid } from \"./source-grid.js\";\nimport { ViewTitle } from \"./view-title.js\";\nimport { searchExtraSources } from \"../../lib/loading/multi-source-loader.js\";\nimport { resolveAllSources } from \"../../lib/configuration/index.js\";\n\nexport type StepSourcesProps = {\n matrix: MergedSkillsMatrix;\n projectDir?: string;\n onContinue: () => void;\n onBack: () => void;\n};\n\ntype SourcesView = \"choice\" | \"customize\";\n\nexport const StepSources: React.FC<StepSourcesProps> = ({\n matrix,\n projectDir,\n onContinue,\n onBack,\n}) => {\n const store = useWizardStore();\n const [view, setView] = useState<SourcesView>(\"choice\");\n const [choiceIndex, setChoiceIndex] = useState(0);\n const [isGridSearching, setIsGridSearching] = useState(false);\n const { ref: gridRef, measuredHeight: gridHeight } = useMeasuredHeight();\n\n const handleGridSelect = useCallback(\n (skillId: SkillId, sourceId: string) => {\n store.setSourceSelection(skillId, sourceId);\n },\n [store],\n );\n\n const handleSearch = useCallback(\n async (alias: SkillAlias): Promise<BoundSkillCandidate[]> => {\n if (!projectDir) return [];\n try {\n const sources = await resolveAllSources(projectDir);\n return await searchExtraSources(alias, sources.extras);\n } catch {\n return [];\n }\n },\n [projectDir],\n );\n\n const handleBind = useCallback(\n (candidate: BoundSkillCandidate) => {\n store.bindSkill({\n id: candidate.id,\n sourceUrl: candidate.sourceUrl,\n sourceName: candidate.sourceName,\n boundTo: candidate.alias,\n description: candidate.description,\n });\n },\n [store],\n );\n\n const handleSearchStateChange = useCallback((active: boolean) => {\n setIsGridSearching(active);\n }, []);\n\n useInput((_input, key) => {\n if (view === \"choice\") {\n if (key.return) {\n if (choiceIndex === 0) {\n onContinue();\n } else {\n store.setCustomizeSources(true);\n setView(\"customize\");\n }\n }\n if (key.escape) {\n onBack();\n }\n if (key.upArrow || key.downArrow) {\n setChoiceIndex((prev) => (prev === 0 ? 1 : 0));\n }\n } else if (view === \"customize\") {\n if (isGridSearching) return;\n\n if (key.return) {\n onContinue();\n }\n if (key.escape) {\n store.setCustomizeSources(false);\n setView(\"choice\");\n }\n }\n });\n\n if (view === \"customize\") {\n const rows = store.buildSourceRows(matrix);\n return (\n <Box flexDirection=\"column\" width=\"100%\" flexGrow={1} flexBasis={0}>\n <ViewTitle>Customize skill sources</ViewTitle>\n <Box ref={gridRef} flexGrow={1} flexBasis={0}>\n <SourceGrid\n rows={rows}\n availableHeight={gridHeight}\n onSelect={handleGridSelect}\n onSearch={handleSearch}\n onBind={handleBind}\n onSearchStateChange={handleSearchStateChange}\n />\n </Box>\n </Box>\n );\n }\n\n const selectedTechnologies = store.getAllSelectedTechnologies();\n const rows = store.buildSourceRows(matrix);\n const isRecommendedSelected = choiceIndex === 0;\n const hasLocalSkills = rows.some((row) =>\n row.options.some((o) => o.installed && o.id === \"local\"),\n );\n\n return (\n <Box flexDirection=\"column\" paddingX={2}>\n <Text>\n Your stack includes{\" \"}\n <Text color={CLI_COLORS.PRIMARY} bold>\n {selectedTechnologies.length}\n </Text>{\" \"}\n technologies.\n </Text>\n <Text> </Text>\n\n <Box\n borderStyle=\"round\"\n borderColor={isRecommendedSelected ? CLI_COLORS.SUCCESS : CLI_COLORS.NEUTRAL}\n paddingX={2}\n paddingY={1}\n marginBottom={1}\n >\n <Box flexDirection=\"column\">\n <Text\n color={isRecommendedSelected ? CLI_COLORS.SUCCESS : undefined}\n bold={isRecommendedSelected}\n >\n {isRecommendedSelected ? \">\" : \"\\u25CB\"}{\" \"}\n {hasLocalSkills\n ? \"Use installed skill sources\"\n : \"Use all recommended skills (verified)\"}\n </Text>\n <Text> </Text>\n <Text dimColor>\n {hasLocalSkills\n ? \"Keep your current local and public skill selections.\"\n : \"This is the fastest option. All skills are verified and\"}\n </Text>\n {!hasLocalSkills && <Text dimColor>maintained by {DEFAULT_BRANDING.NAME}</Text>}\n </Box>\n </Box>\n\n <Box\n borderStyle=\"round\"\n borderColor={!isRecommendedSelected ? CLI_COLORS.SUCCESS : CLI_COLORS.NEUTRAL}\n paddingX={2}\n paddingY={1}\n >\n <Box flexDirection=\"column\">\n <Text\n color={!isRecommendedSelected ? CLI_COLORS.SUCCESS : undefined}\n bold={!isRecommendedSelected}\n >\n {!isRecommendedSelected ? \">\" : \"\\u25CB\"} Customize skill sources\n </Text>\n <Text> </Text>\n <Text dimColor>Choose alternative skills for each technology</Text>\n </Box>\n </Box>\n </Box>\n );\n};\n"],"mappings":"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","names":["rows"]}
|
|
@@ -2,24 +2,24 @@
|
|
|
2
2
|
import {
|
|
3
3
|
useModalState
|
|
4
4
|
} from "./chunk-7SOPVGDV.js";
|
|
5
|
-
import {
|
|
6
|
-
useFocusedListItem
|
|
7
|
-
} from "./chunk-DC5AK3LW.js";
|
|
8
5
|
import {
|
|
9
6
|
SearchModal
|
|
10
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3NQJOJZL.js";
|
|
8
|
+
import {
|
|
9
|
+
useFocusedListItem
|
|
10
|
+
} from "./chunk-GG4BSB6S.js";
|
|
11
11
|
import {
|
|
12
12
|
CLI_COLORS,
|
|
13
|
-
|
|
14
|
-
} from "./chunk-
|
|
13
|
+
SCROLL_VIEWPORT
|
|
14
|
+
} from "./chunk-ZBJQXDQN.js";
|
|
15
15
|
import {
|
|
16
16
|
init_esm_shims
|
|
17
17
|
} from "./chunk-DHET7RCE.js";
|
|
18
18
|
|
|
19
19
|
// src/cli/components/wizard/source-grid.tsx
|
|
20
20
|
init_esm_shims();
|
|
21
|
-
import { useCallback as useCallback2 } from "react";
|
|
22
|
-
import { Box, Text, useInput } from "ink";
|
|
21
|
+
import { useCallback as useCallback2, useEffect, useRef, useState as useState2 } from "react";
|
|
22
|
+
import { Box, Text, measureElement, useInput } from "ink";
|
|
23
23
|
|
|
24
24
|
// src/cli/components/hooks/use-source-grid-search-modal.ts
|
|
25
25
|
init_esm_shims();
|
|
@@ -87,18 +87,28 @@ var SourceTag = ({
|
|
|
87
87
|
option,
|
|
88
88
|
isFocused
|
|
89
89
|
}) => {
|
|
90
|
-
const
|
|
91
|
-
|
|
90
|
+
const getBorderColor = () => {
|
|
91
|
+
if (isFocused) {
|
|
92
|
+
return option.selected ? CLI_COLORS.PRIMARY : CLI_COLORS.UNFOCUSED;
|
|
93
|
+
}
|
|
94
|
+
return CLI_COLORS.NEUTRAL;
|
|
95
|
+
};
|
|
96
|
+
const textColor = option.selected ? CLI_COLORS.PRIMARY : CLI_COLORS.NEUTRAL;
|
|
92
97
|
const isBold = isFocused || option.selected;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
return /* @__PURE__ */ jsx(
|
|
99
|
+
Box,
|
|
100
|
+
{
|
|
101
|
+
marginRight: 1,
|
|
102
|
+
borderColor: getBorderColor(),
|
|
103
|
+
borderStyle: "single",
|
|
104
|
+
borderDimColor: !isFocused,
|
|
105
|
+
children: /* @__PURE__ */ jsxs(Text, { color: textColor, bold: isBold, dimColor: false, children: [
|
|
106
|
+
" ",
|
|
107
|
+
option.label,
|
|
108
|
+
" "
|
|
109
|
+
] })
|
|
110
|
+
}
|
|
111
|
+
);
|
|
102
112
|
};
|
|
103
113
|
var SourceSection = ({
|
|
104
114
|
row,
|
|
@@ -127,6 +137,7 @@ var getNavigableCount = (row, showSearchPill) => {
|
|
|
127
137
|
};
|
|
128
138
|
var SourceGrid = ({
|
|
129
139
|
rows,
|
|
140
|
+
availableHeight = 0,
|
|
130
141
|
onSelect,
|
|
131
142
|
onSearch,
|
|
132
143
|
onBind,
|
|
@@ -157,10 +168,49 @@ var SourceGrid = ({
|
|
|
157
168
|
initialRow: defaultFocusedRow,
|
|
158
169
|
initialCol: defaultFocusedCol
|
|
159
170
|
});
|
|
171
|
+
const sectionRefs = useRef([]);
|
|
172
|
+
const [sectionHeights, setSectionHeights] = useState2([]);
|
|
173
|
+
const [scrollTopPx, setScrollTopPx] = useState2(0);
|
|
174
|
+
const setSectionRef = useCallback2((index, el) => {
|
|
175
|
+
sectionRefs.current[index] = el;
|
|
176
|
+
}, []);
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
const heights = sectionRefs.current.map((el) => {
|
|
179
|
+
if (el) {
|
|
180
|
+
const { height } = measureElement(el);
|
|
181
|
+
return height;
|
|
182
|
+
}
|
|
183
|
+
return 0;
|
|
184
|
+
});
|
|
185
|
+
setSectionHeights((prev) => {
|
|
186
|
+
if (prev.length === heights.length && prev.every((h, i) => h === heights[i])) {
|
|
187
|
+
return prev;
|
|
188
|
+
}
|
|
189
|
+
return heights;
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
const scrollEnabled = availableHeight > 0 && availableHeight >= SCROLL_VIEWPORT.MIN_VIEWPORT_ROWS;
|
|
193
|
+
useEffect(() => {
|
|
194
|
+
if (!scrollEnabled || sectionHeights.length === 0) return;
|
|
195
|
+
let topOfFocused = 0;
|
|
196
|
+
for (let i = 0; i < focusedRow; i++) {
|
|
197
|
+
topOfFocused += sectionHeights[i] ?? 0;
|
|
198
|
+
}
|
|
199
|
+
const focusedHeight = sectionHeights[focusedRow] ?? 0;
|
|
200
|
+
const bottomOfFocused = topOfFocused + focusedHeight;
|
|
201
|
+
setScrollTopPx((prev) => {
|
|
202
|
+
if (topOfFocused < prev) {
|
|
203
|
+
return topOfFocused;
|
|
204
|
+
}
|
|
205
|
+
if (bottomOfFocused > prev + availableHeight) {
|
|
206
|
+
return bottomOfFocused - availableHeight;
|
|
207
|
+
}
|
|
208
|
+
return prev;
|
|
209
|
+
});
|
|
210
|
+
}, [focusedRow, sectionHeights, scrollEnabled, availableHeight]);
|
|
160
211
|
useInput(
|
|
161
212
|
useCallback2(
|
|
162
213
|
(input, key) => {
|
|
163
|
-
if (searchModal.isOpen) return;
|
|
164
214
|
if (input === " ") {
|
|
165
215
|
const currentRow = rows[focusedRow];
|
|
166
216
|
if (!currentRow) return;
|
|
@@ -190,45 +240,44 @@ var SourceGrid = ({
|
|
|
190
240
|
moveFocus("down");
|
|
191
241
|
}
|
|
192
242
|
},
|
|
193
|
-
[
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
focusedCol,
|
|
197
|
-
onSelect,
|
|
198
|
-
showSearchPill,
|
|
199
|
-
searchModal.isOpen,
|
|
200
|
-
handleSearchTrigger,
|
|
201
|
-
moveFocus
|
|
202
|
-
]
|
|
203
|
-
)
|
|
243
|
+
[rows, focusedRow, focusedCol, onSelect, showSearchPill, handleSearchTrigger, moveFocus]
|
|
244
|
+
),
|
|
245
|
+
{ isActive: !searchModal.isOpen }
|
|
204
246
|
);
|
|
205
247
|
if (rows.length === 0) {
|
|
206
248
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No skills to display." }) });
|
|
207
249
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
250
|
+
const sectionElements = rows.map((row, rowIndex) => /* @__PURE__ */ jsx(Box, { ref: (el) => setSectionRef(rowIndex, el), flexShrink: 0, children: /* @__PURE__ */ jsx(
|
|
251
|
+
SourceSection,
|
|
252
|
+
{
|
|
253
|
+
row,
|
|
254
|
+
isFocused: rowIndex === focusedRow,
|
|
255
|
+
focusedOptionIndex: focusedCol,
|
|
256
|
+
showSearchPill
|
|
257
|
+
}
|
|
258
|
+
) }, row.skillId));
|
|
259
|
+
const searchModalElement = searchModal.isOpen && /* @__PURE__ */ jsx(
|
|
260
|
+
SearchModal,
|
|
261
|
+
{
|
|
262
|
+
results: searchResults,
|
|
263
|
+
alias: searchAlias,
|
|
264
|
+
onBind: handleBind,
|
|
265
|
+
onClose: handleCloseSearch
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
if (!scrollEnabled) {
|
|
269
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
270
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: sectionElements }),
|
|
271
|
+
searchModalElement
|
|
272
|
+
] });
|
|
273
|
+
}
|
|
274
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", height: availableHeight, children: [
|
|
275
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", overflow: "hidden", flexGrow: 1, children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: scrollTopPx > 0 ? -scrollTopPx : 0, flexShrink: 0, children: sectionElements }) }),
|
|
276
|
+
searchModalElement
|
|
228
277
|
] });
|
|
229
278
|
};
|
|
230
279
|
|
|
231
280
|
export {
|
|
232
281
|
SourceGrid
|
|
233
282
|
};
|
|
234
|
-
//# sourceMappingURL=chunk-
|
|
283
|
+
//# sourceMappingURL=chunk-EISBUEBL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/source-grid.tsx","../src/cli/components/hooks/use-source-grid-search-modal.ts"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Box, type DOMElement, Text, measureElement, useInput } from \"ink\";\nimport type { BoundSkillCandidate, SkillAlias, SkillId } from \"../../types/index.js\";\nimport { CLI_COLORS, SCROLL_VIEWPORT } from \"../../consts.js\";\nimport { useFocusedListItem } from \"../hooks/use-focused-list-item.js\";\nimport { useSourceGridSearchModal } from \"../hooks/use-source-grid-search-modal.js\";\nimport { SearchModal } from \"./search-modal.js\";\n\nconst SEARCH_PILL_LABEL = \"\\u2315 Search\";\n\nexport type SourceOption = {\n id: string;\n label: string;\n selected: boolean;\n installed: boolean;\n};\n\nexport type SourceRow = {\n skillId: SkillId;\n displayName: string;\n alias: SkillAlias;\n options: SourceOption[];\n};\n\nexport type SourceGridProps = {\n rows: SourceRow[];\n /** Available height in terminal lines for the scrollable viewport. 0 = no constraint. */\n availableHeight?: number;\n onSelect: (skillId: SkillId, sourceId: string) => void;\n onSearch?: (alias: SkillAlias) => Promise<BoundSkillCandidate[]>;\n onBind?: (candidate: BoundSkillCandidate) => void;\n onSearchStateChange?: (active: boolean) => void;\n /** Optional initial focus row (default: 0). Use with React `key` to reset. */\n defaultFocusedRow?: number;\n /** Optional initial focus col (default: 0). Use with React `key` to reset. */\n defaultFocusedCol?: number;\n /** Optional callback fired whenever the focused position changes */\n onFocusChange?: (row: number, col: number) => void;\n};\n\ntype SearchPillProps = {\n isFocused: boolean;\n};\n\nconst SearchPill: React.FC<SearchPillProps> = ({ isFocused }) => {\n const borderColor = isFocused ? CLI_COLORS.UNFOCUSED : CLI_COLORS.NEUTRAL;\n\n return (\n <Box marginRight={1} borderColor={borderColor} borderStyle=\"single\" borderDimColor={!isFocused}>\n <Text dimColor={!isFocused} bold={isFocused}>\n {\" \"}\n {SEARCH_PILL_LABEL}{\" \"}\n </Text>\n </Box>\n );\n};\n\ntype SourceSectionProps = {\n row: SourceRow;\n isFocused: boolean;\n focusedOptionIndex: number;\n showSearchPill: boolean;\n};\n\nconst SourceTag: React.FC<{ option: SourceOption; isFocused: boolean }> = ({\n option,\n isFocused,\n}) => {\n const getBorderColor = (): string => {\n if (isFocused) {\n return option.selected ? CLI_COLORS.PRIMARY : CLI_COLORS.UNFOCUSED;\n }\n return CLI_COLORS.NEUTRAL;\n };\n\n const textColor = option.selected ? CLI_COLORS.PRIMARY : CLI_COLORS.NEUTRAL;\n const isBold = isFocused || option.selected;\n\n return (\n <Box\n marginRight={1}\n borderColor={getBorderColor()}\n borderStyle=\"single\"\n borderDimColor={!isFocused}\n >\n <Text color={textColor} bold={isBold} dimColor={false}>\n {\" \"}\n {option.label}{\" \"}\n </Text>\n </Box>\n );\n};\n\nconst SourceSection: React.FC<SourceSectionProps> = ({\n row,\n isFocused,\n focusedOptionIndex,\n showSearchPill,\n}) => {\n const searchPillIndex = row.options.length;\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box flexDirection=\"row\">\n <Text>{row.displayName}</Text>\n </Box>\n\n <Box flexDirection=\"row\" flexWrap=\"wrap\" marginTop={0}>\n {row.options.map((option, index) => (\n <SourceTag\n key={option.id}\n option={option}\n isFocused={isFocused && index === focusedOptionIndex}\n />\n ))}\n {showSearchPill && (\n <SearchPill isFocused={isFocused && focusedOptionIndex === searchPillIndex} />\n )}\n </Box>\n </Box>\n );\n};\n\n/** Total navigable columns for a row (options + search pill if applicable) */\nconst getNavigableCount = (row: SourceRow, showSearchPill: boolean): number => {\n return row.options.length + (showSearchPill ? 1 : 0);\n};\n\nexport const SourceGrid: React.FC<SourceGridProps> = ({\n rows,\n availableHeight = 0,\n onSelect,\n onSearch,\n onBind,\n onSearchStateChange,\n defaultFocusedRow = 0,\n defaultFocusedCol = 0,\n onFocusChange,\n}) => {\n const {\n searchModal,\n searchResults,\n searchAlias,\n handleSearchTrigger,\n handleBind,\n handleCloseSearch,\n } = useSourceGridSearchModal({ rows, onSearch, onBind, onSearchStateChange });\n\n const showSearchPill = !!onSearch;\n\n const getColCount = useCallback(\n (row: number): number => {\n const rowData = rows[row];\n return rowData ? getNavigableCount(rowData, showSearchPill) : 0;\n },\n [rows, showSearchPill],\n );\n\n const { focusedRow, focusedCol, moveFocus } = useFocusedListItem(rows.length, getColCount, {\n wrap: true,\n onChange: onFocusChange,\n initialRow: defaultFocusedRow,\n initialCol: defaultFocusedCol,\n });\n\n const sectionRefs = useRef<(DOMElement | null)[]>([]);\n const [sectionHeights, setSectionHeights] = useState<number[]>([]);\n const [scrollTopPx, setScrollTopPx] = useState(0);\n\n const setSectionRef = useCallback((index: number, el: DOMElement | null) => {\n sectionRefs.current[index] = el;\n }, []);\n\n useEffect(() => {\n const heights = sectionRefs.current.map((el) => {\n if (el) {\n const { height } = measureElement(el);\n return height;\n }\n return 0;\n });\n setSectionHeights((prev) => {\n if (prev.length === heights.length && prev.every((h, i) => h === heights[i])) {\n return prev;\n }\n return heights;\n });\n });\n\n const scrollEnabled = availableHeight > 0 && availableHeight >= SCROLL_VIEWPORT.MIN_VIEWPORT_ROWS;\n\n useEffect(() => {\n if (!scrollEnabled || sectionHeights.length === 0) return;\n\n let topOfFocused = 0;\n for (let i = 0; i < focusedRow; i++) {\n topOfFocused += sectionHeights[i] ?? 0;\n }\n const focusedHeight = sectionHeights[focusedRow] ?? 0;\n const bottomOfFocused = topOfFocused + focusedHeight;\n\n setScrollTopPx((prev) => {\n if (topOfFocused < prev) {\n return topOfFocused;\n }\n if (bottomOfFocused > prev + availableHeight) {\n return bottomOfFocused - availableHeight;\n }\n return prev;\n });\n }, [focusedRow, sectionHeights, scrollEnabled, availableHeight]);\n\n useInput(\n useCallback(\n (\n input: string,\n key: {\n leftArrow: boolean;\n rightArrow: boolean;\n upArrow: boolean;\n downArrow: boolean;\n return: boolean;\n },\n ) => {\n if (input === \" \") {\n const currentRow = rows[focusedRow];\n if (!currentRow) return;\n if (showSearchPill && focusedCol === currentRow.options.length) {\n void handleSearchTrigger(focusedRow);\n return;\n }\n if (focusedCol < currentRow.options.length) {\n const currentOption = currentRow.options[focusedCol];\n if (currentOption) {\n onSelect(currentRow.skillId, currentOption.id);\n }\n }\n return;\n }\n\n const isLeft = key.leftArrow;\n const isRight = key.rightArrow;\n const isUp = key.upArrow;\n const isDown = key.downArrow;\n\n if (isLeft) {\n moveFocus(\"left\");\n } else if (isRight) {\n moveFocus(\"right\");\n } else if (isUp) {\n moveFocus(\"up\");\n } else if (isDown) {\n moveFocus(\"down\");\n }\n },\n [rows, focusedRow, focusedCol, onSelect, showSearchPill, handleSearchTrigger, moveFocus],\n ),\n { isActive: !searchModal.isOpen },\n );\n\n if (rows.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>No skills to display.</Text>\n </Box>\n );\n }\n\n const sectionElements = rows.map((row, rowIndex) => (\n <Box key={row.skillId} ref={(el) => setSectionRef(rowIndex, el)} flexShrink={0}>\n <SourceSection\n row={row}\n isFocused={rowIndex === focusedRow}\n focusedOptionIndex={focusedCol}\n showSearchPill={showSearchPill}\n />\n </Box>\n ));\n\n const searchModalElement = searchModal.isOpen && (\n <SearchModal\n results={searchResults}\n alias={searchAlias}\n onBind={handleBind}\n onClose={handleCloseSearch}\n />\n );\n\n // When no height constraint, render flat (tests, or before first measurement)\n if (!scrollEnabled) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" flexGrow={1} overflow=\"hidden\">\n {sectionElements}\n </Box>\n {searchModalElement}\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" height={availableHeight}>\n <Box flexDirection=\"column\" overflow=\"hidden\" flexGrow={1}>\n <Box flexDirection=\"column\" marginTop={scrollTopPx > 0 ? -scrollTopPx : 0} flexShrink={0}>\n {sectionElements}\n </Box>\n </Box>\n {searchModalElement}\n </Box>\n );\n};\n","import { useCallback, useState } from \"react\";\nimport type { BoundSkillCandidate, SkillAlias } from \"../../types/index.js\";\nimport { useModalState } from \"./use-modal-state.js\";\nimport type { SourceRow } from \"../wizard/source-grid.js\";\n\ntype UseSourceGridSearchModalOptions = {\n rows: SourceRow[];\n onSearch?: (alias: SkillAlias) => Promise<BoundSkillCandidate[]>;\n onBind?: (candidate: BoundSkillCandidate) => void;\n onSearchStateChange?: (active: boolean) => void;\n};\n\ntype UseSourceGridSearchModalResult = {\n searchModal: { isOpen: boolean };\n searchResults: BoundSkillCandidate[];\n searchAlias: string;\n handleSearchTrigger: (rowIndex: number) => Promise<void>;\n handleBind: (candidate: BoundSkillCandidate) => void;\n handleCloseSearch: () => void;\n};\n\nexport function useSourceGridSearchModal({\n rows,\n onSearch,\n onBind,\n onSearchStateChange,\n}: UseSourceGridSearchModalOptions): UseSourceGridSearchModalResult {\n const searchModal = useModalState<number>();\n const [searchResults, setSearchResults] = useState<BoundSkillCandidate[]>([]);\n const [searchAlias, setSearchAlias] = useState(\"\");\n\n const resetSearch = useCallback(() => {\n searchModal.close();\n setSearchResults([]);\n setSearchAlias(\"\");\n onSearchStateChange?.(false);\n }, [onSearchStateChange, searchModal]);\n\n const handleSearchTrigger = useCallback(\n async (rowIndex: number) => {\n const row = rows[rowIndex];\n if (!row || !onSearch) return;\n\n const alias = row.alias;\n setSearchAlias(alias);\n searchModal.open(rowIndex);\n onSearchStateChange?.(true);\n\n const results = await onSearch(alias);\n setSearchResults(results);\n },\n [rows, onSearch, onSearchStateChange, searchModal],\n );\n\n const handleBind = useCallback(\n (candidate: BoundSkillCandidate) => {\n onBind?.(candidate);\n resetSearch();\n },\n [onBind, resetSearch],\n );\n\n const handleCloseSearch = useCallback(() => {\n resetSearch();\n }, [resetSearch]);\n\n return {\n searchModal: { isOpen: searchModal.isOpen },\n searchResults,\n searchAlias,\n handleSearchTrigger,\n handleBind,\n handleCloseSearch,\n };\n}\n"],"mappings":"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","names":["useCallback","useState","useCallback","useState"]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
CheckboxGrid
|
|
4
|
+
} from "./chunk-IWNPFIGY.js";
|
|
5
|
+
import {
|
|
6
|
+
useWizardStore
|
|
7
|
+
} from "./chunk-HRMQ2RGY.js";
|
|
8
|
+
import {
|
|
9
|
+
init_esm_shims
|
|
10
|
+
} from "./chunk-DHET7RCE.js";
|
|
11
|
+
|
|
12
|
+
// src/cli/components/wizard/step-agents.tsx
|
|
13
|
+
init_esm_shims();
|
|
14
|
+
import { jsx } from "react/jsx-runtime";
|
|
15
|
+
var AVAILABLE_AGENTS = [
|
|
16
|
+
{
|
|
17
|
+
id: "web-developer",
|
|
18
|
+
label: "Web Developer",
|
|
19
|
+
description: "Frontend features, components, TypeScript"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "api-developer",
|
|
23
|
+
label: "API Developer",
|
|
24
|
+
description: "Backend routes, database, middleware"
|
|
25
|
+
},
|
|
26
|
+
{ id: "cli-developer", label: "CLI Developer", description: "CLI commands, interactive prompts" },
|
|
27
|
+
{
|
|
28
|
+
id: "web-architecture",
|
|
29
|
+
label: "Web Architecture",
|
|
30
|
+
description: "App scaffolding, foundational patterns"
|
|
31
|
+
},
|
|
32
|
+
{ id: "web-reviewer", label: "Web Reviewer", description: "UI component code review" },
|
|
33
|
+
{ id: "api-reviewer", label: "API Reviewer", description: "Backend and config code review" },
|
|
34
|
+
{ id: "cli-reviewer", label: "CLI Reviewer", description: "CLI code review" },
|
|
35
|
+
{ id: "web-researcher", label: "Web Researcher", description: "Frontend pattern discovery" },
|
|
36
|
+
{ id: "api-researcher", label: "API Researcher", description: "Backend pattern discovery" },
|
|
37
|
+
{ id: "web-tester", label: "Web Tester", description: "Frontend tests, E2E, component tests" },
|
|
38
|
+
{ id: "cli-tester", label: "CLI Tester", description: "CLI application tests" },
|
|
39
|
+
{ id: "web-pm", label: "Web PM", description: "Implementation specs and planning" },
|
|
40
|
+
{
|
|
41
|
+
id: "pattern-scout",
|
|
42
|
+
label: "Pattern Scout",
|
|
43
|
+
description: "Extract codebase patterns and standards"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "web-pattern-critique",
|
|
47
|
+
label: "Pattern Critique",
|
|
48
|
+
description: "Critique patterns against industry standards"
|
|
49
|
+
},
|
|
50
|
+
{ id: "agent-summoner", label: "Agent Summoner", description: "Create and improve agents" },
|
|
51
|
+
{
|
|
52
|
+
id: "skill-summoner",
|
|
53
|
+
label: "Skill Summoner",
|
|
54
|
+
description: "Create technology-specific skills"
|
|
55
|
+
},
|
|
56
|
+
{ id: "documentor", label: "Documentor", description: "AI-focused documentation" },
|
|
57
|
+
{ id: "cli-migrator", label: "CLI Migrator", description: "Commander.js to oclif migration" }
|
|
58
|
+
];
|
|
59
|
+
var StepAgents = () => {
|
|
60
|
+
const store = useWizardStore();
|
|
61
|
+
return /* @__PURE__ */ jsx(
|
|
62
|
+
CheckboxGrid,
|
|
63
|
+
{
|
|
64
|
+
title: "Select agents to compile:",
|
|
65
|
+
subtitle: "Toggle agents on/off, then continue",
|
|
66
|
+
items: AVAILABLE_AGENTS,
|
|
67
|
+
selectedIds: store.selectedAgents,
|
|
68
|
+
onToggle: store.toggleAgent,
|
|
69
|
+
onContinue: () => store.setStep("confirm"),
|
|
70
|
+
onBack: store.goBack,
|
|
71
|
+
continueLabel: (count) => `Continue with ${count} agent(s)`,
|
|
72
|
+
emptyMessage: "Please select at least one agent"
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
StepAgents
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=chunk-EXFVAEPY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/step-agents.tsx"],"sourcesContent":["import React from \"react\";\nimport type { AgentName } from \"../../types/index.js\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport { CheckboxGrid, type CheckboxItem } from \"./checkbox-grid.js\";\n\nconst AVAILABLE_AGENTS: CheckboxItem<AgentName>[] = [\n {\n id: \"web-developer\",\n label: \"Web Developer\",\n description: \"Frontend features, components, TypeScript\",\n },\n {\n id: \"api-developer\",\n label: \"API Developer\",\n description: \"Backend routes, database, middleware\",\n },\n { id: \"cli-developer\", label: \"CLI Developer\", description: \"CLI commands, interactive prompts\" },\n {\n id: \"web-architecture\",\n label: \"Web Architecture\",\n description: \"App scaffolding, foundational patterns\",\n },\n { id: \"web-reviewer\", label: \"Web Reviewer\", description: \"UI component code review\" },\n { id: \"api-reviewer\", label: \"API Reviewer\", description: \"Backend and config code review\" },\n { id: \"cli-reviewer\", label: \"CLI Reviewer\", description: \"CLI code review\" },\n { id: \"web-researcher\", label: \"Web Researcher\", description: \"Frontend pattern discovery\" },\n { id: \"api-researcher\", label: \"API Researcher\", description: \"Backend pattern discovery\" },\n { id: \"web-tester\", label: \"Web Tester\", description: \"Frontend tests, E2E, component tests\" },\n { id: \"cli-tester\", label: \"CLI Tester\", description: \"CLI application tests\" },\n { id: \"web-pm\", label: \"Web PM\", description: \"Implementation specs and planning\" },\n {\n id: \"pattern-scout\",\n label: \"Pattern Scout\",\n description: \"Extract codebase patterns and standards\",\n },\n {\n id: \"web-pattern-critique\",\n label: \"Pattern Critique\",\n description: \"Critique patterns against industry standards\",\n },\n { id: \"agent-summoner\", label: \"Agent Summoner\", description: \"Create and improve agents\" },\n {\n id: \"skill-summoner\",\n label: \"Skill Summoner\",\n description: \"Create technology-specific skills\",\n },\n { id: \"documentor\", label: \"Documentor\", description: \"AI-focused documentation\" },\n { id: \"cli-migrator\", label: \"CLI Migrator\", description: \"Commander.js to oclif migration\" },\n];\n\nexport const StepAgents: React.FC = () => {\n const store = useWizardStore();\n\n return (\n <CheckboxGrid\n title=\"Select agents to compile:\"\n subtitle=\"Toggle agents on/off, then continue\"\n items={AVAILABLE_AGENTS}\n selectedIds={store.selectedAgents}\n onToggle={store.toggleAgent}\n onContinue={() => store.setStep(\"confirm\")}\n onBack={store.goBack}\n continueLabel={(count) => `Continue with ${count} agent(s)`}\n emptyMessage=\"Please select at least one agent\"\n />\n );\n};\n"],"mappings":";;;;;;;;;;;;AAAA;AAsDI;AAjDJ,IAAM,mBAA8C;AAAA,EAClD;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,EAAE,IAAI,iBAAiB,OAAO,iBAAiB,aAAa,oCAAoC;AAAA,EAChG;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,EAAE,IAAI,gBAAgB,OAAO,gBAAgB,aAAa,2BAA2B;AAAA,EACrF,EAAE,IAAI,gBAAgB,OAAO,gBAAgB,aAAa,iCAAiC;AAAA,EAC3F,EAAE,IAAI,gBAAgB,OAAO,gBAAgB,aAAa,kBAAkB;AAAA,EAC5E,EAAE,IAAI,kBAAkB,OAAO,kBAAkB,aAAa,6BAA6B;AAAA,EAC3F,EAAE,IAAI,kBAAkB,OAAO,kBAAkB,aAAa,4BAA4B;AAAA,EAC1F,EAAE,IAAI,cAAc,OAAO,cAAc,aAAa,uCAAuC;AAAA,EAC7F,EAAE,IAAI,cAAc,OAAO,cAAc,aAAa,wBAAwB;AAAA,EAC9E,EAAE,IAAI,UAAU,OAAO,UAAU,aAAa,oCAAoC;AAAA,EAClF;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,EAAE,IAAI,kBAAkB,OAAO,kBAAkB,aAAa,4BAA4B;AAAA,EAC1F;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,EAAE,IAAI,cAAc,OAAO,cAAc,aAAa,2BAA2B;AAAA,EACjF,EAAE,IAAI,gBAAgB,OAAO,gBAAgB,aAAa,kCAAkC;AAC9F;AAEO,IAAM,aAAuB,MAAM;AACxC,QAAM,QAAQ,eAAe;AAE7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,UAAS;AAAA,MACT,OAAO;AAAA,MACP,aAAa,MAAM;AAAA,MACnB,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM,MAAM,QAAQ,SAAS;AAAA,MACzC,QAAQ,MAAM;AAAA,MACd,eAAe,CAAC,UAAU,iBAAiB,KAAK;AAAA,MAChD,cAAa;AAAA;AAAA,EACf;AAEJ;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_BRANDING
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZBJQXDQN.js";
|
|
5
5
|
import {
|
|
6
6
|
init_esm_shims
|
|
7
7
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -13,7 +13,7 @@ init_esm_shims();
|
|
|
13
13
|
init_esm_shims();
|
|
14
14
|
import path from "path";
|
|
15
15
|
import { fileURLToPath } from "url";
|
|
16
|
-
import { parse as parseYaml } from "yaml";
|
|
16
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
17
17
|
import { run } from "@oclif/core";
|
|
18
18
|
var __filename = fileURLToPath(import.meta.url);
|
|
19
19
|
var __dirname = path.dirname(__filename);
|
|
@@ -117,7 +117,7 @@ var SKILL_FIXTURES = {
|
|
|
117
117
|
},
|
|
118
118
|
zustand: {
|
|
119
119
|
id: "web-state-zustand",
|
|
120
|
-
category: "web/state",
|
|
120
|
+
category: "web/client-state",
|
|
121
121
|
displayName: "zustand",
|
|
122
122
|
description: "Bear necessities state management",
|
|
123
123
|
tags: ["state", "react", "zustand"]
|
|
@@ -183,4 +183,4 @@ export {
|
|
|
183
183
|
createMockCategory,
|
|
184
184
|
createMockResolvedStack
|
|
185
185
|
};
|
|
186
|
-
//# sourceMappingURL=chunk-
|
|
186
|
+
//# sourceMappingURL=chunk-FWQK3HWB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/lib/__tests__/test-fixtures.ts","../src/cli/lib/__tests__/helpers.ts"],"sourcesContent":["import type { CategoryPath, ResolvedSkill, SkillDisplayName, SkillId } from \"../../types\";\nimport { createMockSkill } from \"./helpers\";\n\ninterface SkillFixtureConfig {\n id: SkillId;\n category: CategoryPath;\n displayName?: SkillDisplayName;\n description: string;\n tags: string[];\n}\n\nconst SKILL_FIXTURES: Record<string, SkillFixtureConfig> = {\n react: {\n id: \"web-framework-react\",\n category: \"web/framework\",\n displayName: \"react\",\n description: \"React framework for building user interfaces\",\n tags: [\"react\", \"web\", \"ui\", \"component\"],\n },\n zustand: {\n id: \"web-state-zustand\",\n category: \"web/client-state\",\n displayName: \"zustand\",\n description: \"Bear necessities state management\",\n tags: [\"state\", \"react\", \"zustand\"],\n },\n hono: {\n id: \"api-framework-hono\",\n category: \"api/framework\",\n displayName: \"hono\",\n description: \"Lightweight web framework for the edge\",\n tags: [\"api\", \"api\", \"edge\", \"serverless\"],\n },\n vitest: {\n id: \"web-testing-vitest\",\n category: \"testing\",\n displayName: \"vitest\",\n description: \"Next generation testing framework\",\n tags: [\"testing\", \"vitest\", \"unit\"],\n },\n vue: {\n id: \"web-framework-vue\",\n category: \"web/framework\",\n displayName: \"vue\",\n description: \"Progressive JavaScript framework\",\n tags: [\"vue\", \"web\", \"reactive\"],\n },\n \"auth-patterns\": {\n id: \"api-security-auth-patterns\",\n category: \"api/security\",\n description: \"Authentication and authorization patterns\",\n tags: [\"auth\", \"security\", \"jwt\", \"oauth\"],\n },\n drizzle: {\n id: \"api-database-drizzle\",\n category: \"api/database\",\n displayName: \"drizzle\",\n description: \"TypeScript ORM for SQL databases\",\n tags: [\"database\", \"orm\", \"sql\"],\n },\n methodology: {\n id: \"meta-methodology-anti-over-engineering\",\n category: \"meta/methodology\",\n description: \"Surgical implementation, not architectural innovation\",\n tags: [\"methodology\", \"foundational\"],\n },\n \"scss-modules\": {\n id: \"web-styling-scss-modules\",\n category: \"web/styling\",\n displayName: \"scss-modules\",\n description: \"CSS Modules with SCSS\",\n tags: [\"css\", \"scss\", \"modules\"],\n },\n} as const;\n\nexport type TestSkillName = keyof typeof SKILL_FIXTURES;\n\nexport function getTestSkill(\n name: TestSkillName,\n overrides?: Partial<ResolvedSkill>,\n): ResolvedSkill {\n const config = SKILL_FIXTURES[name];\n const { id, category, ...defaults } = config;\n return createMockSkill(id, category, { ...defaults, ...overrides });\n}\n","import path from \"path\";\nimport os from \"os\";\nimport { fileURLToPath } from \"url\";\nimport { mkdtemp, rm, mkdir, writeFile, readFile, stat } from \"fs/promises\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { run, Errors } from \"@oclif/core\";\nimport ansis from \"ansis\";\nimport { DEFAULT_BRANDING, DEFAULT_PLUGIN_NAME, STANDARD_FILES } from \"../../consts\";\nimport { typedEntries } from \"../../utils/typed-object\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport const CLI_ROOT = path.resolve(__dirname, \"../../../..\");\n\nexport const OUTPUT_STRINGS = {\n CONFIG_HEADER: `${DEFAULT_BRANDING.NAME} Configuration`,\n CONFIG_PATHS_HEADER: \"Configuration File Paths\",\n CONFIG_LAYERS_HEADER: \"Configuration Layers:\",\n CONFIG_PRECEDENCE: \"Precedence: flag > env > project > global > default\",\n SOURCE_LABEL: \"Source:\",\n MARKETPLACE_LABEL: \"Marketplace:\",\n AGENTS_SOURCE_LABEL: \"Agents Source:\",\n GLOBAL_LABEL: \"Global:\",\n PROJECT_LABEL: \"Project:\",\n\n // Setup/Init outputs\n INIT_HEADER: `${DEFAULT_BRANDING.NAME} Setup`,\n INIT_SUCCESS: `${DEFAULT_BRANDING.NAME} initialized successfully!`,\n LOADING_MATRIX: \"Loading skills matrix...\",\n LOADING_SKILLS: \"Loading skills...\",\n LOADING_AGENTS: \"Loading agent partials...\",\n\n // Plugin/installation outputs\n NO_PLUGIN_FOUND: \"No plugin found\",\n NO_INSTALLATION_FOUND: \"No installation found\",\n NO_PLUGIN_INSTALLATION: \"No plugin installation found\",\n NOT_INSTALLED: `${DEFAULT_BRANDING.NAME} is not installed`,\n UNINSTALL_HEADER: `${DEFAULT_BRANDING.NAME} Uninstall`,\n UNINSTALL_COMPLETE: `${DEFAULT_BRANDING.NAME} has been uninstalled`,\n EJECT_HEADER: `${DEFAULT_BRANDING.NAME} Eject`,\n\n // Doctor command outputs\n DOCTOR_HEADER: `${DEFAULT_BRANDING.NAME} Doctor`,\n\n // Error message patterns (lowercase for case-insensitive matching)\n ERROR_MISSING_ARG: \"missing required arg\",\n ERROR_UNEXPECTED_ARG: \"unexpected argument\",\n ERROR_UNKNOWN_FLAG: \"unknown flag\",\n ERROR_PARSE: \"parse\",\n} as const;\n\n/**\n * Run a CLI command and capture its output.\n *\n * Bun's `console.log` does not go through `process.stdout.write`, so\n * `@oclif/test`'s `runCommand` (which only intercepts `process.stdout.write`)\n * returns empty stdout/stderr in bun. This helper intercepts both layers\n * to work correctly in both Node.js and bun environments.\n */\nexport async function runCliCommand(args: string[]) {\n const origStdoutWrite = process.stdout.write;\n const origStderrWrite = process.stderr.write;\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n const stdoutBuf: string[] = [];\n const stderrBuf: string[] = [];\n\n // Intercept process.stdout/stderr.write (Node.js path)\n process.stdout.write = function (str: unknown, encoding?: unknown, cb?: unknown): boolean {\n stdoutBuf.push(String(str));\n if (typeof encoding === \"function\") {\n (encoding as () => void)();\n } else if (typeof cb === \"function\") {\n (cb as () => void)();\n }\n return true;\n } as typeof process.stdout.write;\n\n process.stderr.write = function (str: unknown, encoding?: unknown, cb?: unknown): boolean {\n stderrBuf.push(String(str));\n if (typeof encoding === \"function\") {\n (encoding as () => void)();\n } else if (typeof cb === \"function\") {\n (cb as () => void)();\n }\n return true;\n } as typeof process.stderr.write;\n\n // Intercept console methods (bun path — console.log bypasses process.stdout.write)\n console.log = (...logArgs: unknown[]) => {\n stdoutBuf.push(logArgs.map(String).join(\" \") + \"\\n\");\n };\n console.warn = (...warnArgs: unknown[]) => {\n stderrBuf.push(warnArgs.map(String).join(\" \") + \"\\n\");\n };\n console.error = (...errArgs: unknown[]) => {\n stderrBuf.push(errArgs.map(String).join(\" \") + \"\\n\");\n };\n\n let error: (Error & Partial<Errors.CLIError>) | undefined;\n try {\n await run(args, { root: CLI_ROOT });\n } catch (e) {\n if (e instanceof Error) {\n error = Object.assign(e, { message: ansis.strip(e.message) }) as Error &\n Partial<Errors.CLIError>;\n }\n } finally {\n process.stdout.write = origStdoutWrite;\n process.stderr.write = origStderrWrite;\n console.log = origLog;\n console.warn = origWarn;\n console.error = origError;\n }\n\n return {\n stdout: stdoutBuf.map((s) => ansis.strip(s)).join(\"\"),\n stderr: stderrBuf.map((s) => ansis.strip(s)).join(\"\"),\n error,\n };\n}\nimport type {\n AgentConfig,\n AgentDefinition,\n CategoryDefinition,\n CategoryPath,\n CompileContext,\n Domain,\n DomainSelections,\n ExtractedSkillMetadata,\n MergedSkillsMatrix,\n ResolvedSkill,\n ResolvedStack,\n Skill,\n SkillDisplayName,\n SkillId,\n Subcategory,\n} from \"../../types\";\nimport type { WizardResultV2 } from \"../../components/wizard/wizard\";\nimport type { SourceLoadResult } from \"../loading/source-loader\";\nimport type { ResolvedConfig } from \"../configuration/config\";\nimport { getTestSkill } from \"./test-fixtures\";\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const s = await stat(filePath);\n return s.isFile();\n } catch {\n return false;\n }\n}\n\nexport async function directoryExists(dirPath: string): Promise<boolean> {\n try {\n const s = await stat(dirPath);\n return s.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function readTestYaml<T>(filePath: string): Promise<T> {\n const content = await readFile(filePath, \"utf-8\");\n // Boundary cast: YAML parse returns `unknown`, caller provides expected type\n return parseYaml(content) as T;\n}\n\nexport function buildWizardResult(\n selectedSkills: SkillId[],\n overrides?: Partial<WizardResultV2>,\n): WizardResultV2 {\n return {\n selectedSkills,\n selectedAgents: [],\n selectedStackId: null,\n domainSelections: {} as DomainSelections,\n sourceSelections: {},\n expertMode: false,\n installMode: \"local\",\n cancelled: false,\n validation: { valid: true, errors: [], warnings: [] },\n ...overrides,\n };\n}\n\nexport function buildSourceResult(\n matrix: MergedSkillsMatrix,\n sourcePath: string,\n overrides?: Partial<SourceLoadResult>,\n): SourceLoadResult {\n const sourceConfig: ResolvedConfig = {\n source: sourcePath,\n sourceOrigin: \"flag\",\n };\n return {\n matrix,\n sourceConfig,\n sourcePath,\n isLocal: true,\n ...overrides,\n };\n}\n\n/**\n * Lightweight frontmatter parser for test assertions.\n * Returns raw key-value pairs (unlike the production parseFrontmatter which\n * returns typed SkillFrontmatter with Zod validation).\n */\nexport function parseTestFrontmatter(content: string): Record<string, unknown> | null {\n if (!content.startsWith(\"---\")) {\n return null;\n }\n\n const endIndex = content.indexOf(\"---\", 3);\n if (endIndex === -1) {\n return null;\n }\n\n const yamlContent = content.slice(3, endIndex).trim();\n try {\n // Boundary cast: YAML parse returns `unknown`\n return parseYaml(yamlContent) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport async function createTempDir(prefix = \"cc-test-\"): Promise<string> {\n return mkdtemp(path.join(os.tmpdir(), prefix));\n}\n\nconst CLEANUP_MAX_RETRIES = 3;\nconst CLEANUP_RETRY_DELAY_MS = 100;\n\nexport async function cleanupTempDir(dirPath: string): Promise<void> {\n for (let attempt = 0; attempt < CLEANUP_MAX_RETRIES; attempt++) {\n try {\n await rm(dirPath, { recursive: true, force: true });\n return;\n } catch (error: unknown) {\n const isRetryable =\n error instanceof Error &&\n \"code\" in error &&\n (error as NodeJS.ErrnoException).code === \"ENOTEMPTY\";\n if (!isRetryable || attempt === CLEANUP_MAX_RETRIES - 1) {\n throw error;\n }\n // Transient ENOTEMPTY on macOS: kernel hasn't released directory entries yet\n await new Promise((resolve) => setTimeout(resolve, CLEANUP_RETRY_DELAY_MS));\n }\n }\n}\n\nexport interface TestDirs {\n tempDir: string;\n projectDir: string;\n pluginDir: string;\n skillsDir: string;\n agentsDir: string;\n}\n\nexport async function createTestDirs(prefix = \"cc-test-\"): Promise<TestDirs> {\n const tempDir = await createTempDir(prefix);\n const projectDir = path.join(tempDir, \"project\");\n const pluginDir = path.join(projectDir, \".claude\", \"plugins\", DEFAULT_PLUGIN_NAME);\n const skillsDir = path.join(pluginDir, \"skills\");\n const agentsDir = path.join(pluginDir, \"agents\");\n\n await mkdir(skillsDir, { recursive: true });\n await mkdir(agentsDir, { recursive: true });\n\n return { tempDir, projectDir, pluginDir, skillsDir, agentsDir };\n}\n\nexport async function cleanupTestDirs(dirs: TestDirs): Promise<void> {\n await cleanupTempDir(dirs.tempDir);\n}\n\nexport function createMockSkill(\n id: SkillId,\n category: CategoryPath,\n overrides?: Partial<ResolvedSkill>,\n): ResolvedSkill {\n return {\n id,\n description: `${id} skill`,\n category,\n categoryExclusive: false,\n tags: [],\n author: \"@test\",\n conflictsWith: [],\n recommends: [],\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n requiresSetup: [],\n providesSetupFor: [],\n path: `skills/${category}/${id}/`,\n ...overrides,\n };\n}\n\n/**\n * Creates a mock ExtractedSkillMetadata for testing.\n * Used when mocking extractAllSkills() return values.\n */\nexport function createMockExtractedSkill(\n id: SkillId,\n overrides?: Partial<ExtractedSkillMetadata>,\n): ExtractedSkillMetadata {\n // Derive directory path and category from the skill ID convention: \"domain-subcategory-name\"\n const segments = id.split(\"-\");\n const domain = segments[0] ?? \"web\";\n const subcategory = segments[1] ?? \"framework\";\n const name = segments.slice(2).join(\"-\") || \"skill\";\n const directoryPath = `${domain}/${subcategory}/${name}`;\n\n return {\n id,\n directoryPath,\n description: `${id} skill`,\n category: `${subcategory}` as CategoryPath,\n categoryExclusive: true,\n author: \"@test\",\n tags: [],\n compatibleWith: [],\n conflictsWith: [],\n requires: [],\n requiresSetup: [],\n providesSetupFor: [],\n path: `skills/${directoryPath}/`,\n ...overrides,\n };\n}\n\nexport function createMockMatrix(\n skills: Record<string, ResolvedSkill>,\n overrides?: Partial<MergedSkillsMatrix>,\n): MergedSkillsMatrix {\n return {\n version: \"1.0.0\",\n categories: {} as Record<Subcategory, import(\"../../types\").CategoryDefinition>,\n skills,\n suggestedStacks: [],\n displayNameToId: {} as Record<SkillDisplayName, SkillId>,\n displayNames: {} as Record<SkillId, SkillDisplayName>,\n generatedAt: new Date().toISOString(),\n ...overrides,\n };\n}\n\nexport function createMockAgent(\n name: string,\n overrides?: Partial<AgentDefinition>,\n): AgentDefinition {\n return {\n title: name,\n description: `${name} agent`,\n tools: [\"Read\", \"Write\", \"Edit\", \"Grep\", \"Glob\", \"Bash\"],\n model: \"opus\",\n permissionMode: \"default\",\n ...overrides,\n };\n}\n\nexport function createMockAgentConfig(\n name: string,\n skills: Skill[] = [],\n overrides?: Partial<AgentConfig>,\n): AgentConfig {\n return {\n name,\n title: `${name} agent`,\n description: `Test ${name}`,\n tools: [\"Read\", \"Write\"],\n skills,\n path: name,\n ...overrides,\n };\n}\n\nexport function createMockSkillEntry(\n id: SkillId,\n preloaded = false,\n overrides?: Partial<Skill>,\n): Skill {\n return {\n id,\n path: `skills/${id}/`,\n description: `${id} skill`,\n usage: `when working with ${id}`,\n preloaded,\n ...overrides,\n };\n}\n\nexport function createCompileContext(overrides?: Partial<CompileContext>): CompileContext {\n return {\n stackId: \"test-stack\",\n verbose: false,\n projectRoot: \"/project\",\n outputDir: `/project/.claude/plugins/${DEFAULT_PLUGIN_NAME}`,\n ...overrides,\n };\n}\n\nexport function createSkillContent(name: string, description = \"A test skill\"): string {\n return `---\nname: ${name}\ndescription: ${description}\ncategory: test\n---\n\n# ${name}\n\nThis is a test skill.\n`;\n}\n\nfunction createMetadataContent(author = \"@test\"): string {\n return `version: 1\nauthor: ${author}\n`;\n}\n\nexport function createAgentYamlContent(name: string, description = `Test ${name} agent`): string {\n return `id: ${name}\ntitle: ${name} Agent\ndescription: ${description}\ntools:\n - Read\n - Write`;\n}\n\nexport async function writeTestSkill(\n skillsDir: string,\n skillName: string,\n options?: {\n author?: string;\n description?: string;\n /** Extra fields to merge into metadata.yaml (e.g., forkedFrom, cliName) */\n extraMetadata?: Record<string, unknown>;\n /** Skip metadata.yaml creation entirely */\n skipMetadata?: boolean;\n /** Custom SKILL.md content (overrides default generated content) */\n skillContent?: string;\n },\n): Promise<string> {\n const skillDir = path.join(skillsDir, skillName);\n await mkdir(skillDir, { recursive: true });\n\n await writeFile(\n path.join(skillDir, STANDARD_FILES.SKILL_MD),\n options?.skillContent ?? createSkillContent(skillName, options?.description),\n );\n\n if (!options?.skipMetadata) {\n if (options?.extraMetadata) {\n const metadata = {\n version: 1,\n author: options?.author ?? \"@test\",\n ...options.extraMetadata,\n };\n await writeFile(path.join(skillDir, STANDARD_FILES.METADATA_YAML), stringifyYaml(metadata));\n } else {\n await writeFile(\n path.join(skillDir, STANDARD_FILES.METADATA_YAML),\n createMetadataContent(options?.author),\n );\n }\n }\n\n return skillDir;\n}\n\n/**\n * Creates a source-level skill directory with SKILL.md and rich metadata.yaml.\n * Use this when testing `extractAllSkills()` and `mergeMatrixWithSkills()`.\n *\n * Unlike `writeTestSkill()` which creates installed skills, this writes skills\n * in the source directory layout (under `src/skills/<domain>/<subcategory>/<name>/`).\n */\nexport async function writeSourceSkill(\n skillsDir: string,\n directoryPath: string,\n config: {\n id: string;\n description: string;\n category: string;\n author?: string;\n tags?: string[];\n categoryExclusive?: boolean;\n content?: string;\n },\n): Promise<string> {\n const skillDir = path.join(skillsDir, directoryPath);\n await mkdir(skillDir, { recursive: true });\n\n await writeFile(\n path.join(skillDir, STANDARD_FILES.SKILL_MD),\n createSkillContent(config.id, config.description),\n );\n\n const metadata: Record<string, unknown> = {\n cliName: config.id,\n category: config.category,\n author: config.author ?? \"@test\",\n version: \"1\",\n };\n if (config.tags) {\n metadata.tags = config.tags;\n }\n if (config.categoryExclusive !== undefined) {\n metadata.categoryExclusive = config.categoryExclusive;\n }\n\n await writeFile(path.join(skillDir, STANDARD_FILES.METADATA_YAML), stringifyYaml(metadata));\n\n return skillDir;\n}\n\nexport async function writeTestAgent(\n agentsDir: string,\n agentName: string,\n options?: { description?: string },\n): Promise<string> {\n const agentDir = path.join(agentsDir, agentName);\n await mkdir(agentDir, { recursive: true });\n\n await writeFile(\n path.join(agentDir, STANDARD_FILES.AGENT_YAML),\n createAgentYamlContent(agentName, options?.description),\n );\n\n return agentDir;\n}\n\nexport function createMockCategory(\n id: Subcategory,\n displayName: string,\n overrides?: Partial<CategoryDefinition>,\n): CategoryDefinition {\n return {\n id,\n displayName,\n description: `${displayName} category`,\n exclusive: true,\n required: false,\n order: 0,\n ...overrides,\n };\n}\n\nexport function createMockResolvedStack(\n id: string,\n name: string,\n overrides?: Partial<ResolvedStack>,\n): ResolvedStack {\n return {\n id,\n name,\n description: `${name} stack`,\n audience: [],\n skills: {},\n allSkillIds: [],\n philosophy: \"\",\n ...overrides,\n };\n}\n\n/**\n * Builds a comprehensive test matrix with 7 skills across 6 categories,\n * 2 suggested stacks, display name mappings, and relationship data\n * (conflicts, recommends). Suitable for full wizard and compilation tests.\n * @returns A fully populated MergedSkillsMatrix with realistic test data\n */\nexport function createComprehensiveMatrix(\n overrides?: Partial<MergedSkillsMatrix>,\n): MergedSkillsMatrix {\n // Skill categories use bare Subcategory IDs (matching production metadata.yaml\n // and the categories map keys). The test fixture factories default to \"web/framework\"\n // CategoryPath format, but the wizard's populateFromStack needs bare IDs to match\n // the categories map lookup (e.g., \"framework\" not \"web/framework\").\n const skills = {\n \"web-framework-react\": getTestSkill(\"react\", { category: \"framework\" }),\n \"web-framework-vue\": getTestSkill(\"vue\", {\n category: \"framework\",\n conflictsWith: [{ skillId: \"web-framework-react\", reason: \"Choose one framework\" }],\n }),\n \"web-state-zustand\": getTestSkill(\"zustand\", {\n category: \"client-state\",\n recommends: [{ skillId: \"web-framework-react\", reason: \"Works great with React\" }],\n }),\n \"web-styling-scss-modules\": getTestSkill(\"scss-modules\", { category: \"styling\" }),\n \"api-framework-hono\": getTestSkill(\"hono\", { category: \"api\" }),\n \"api-database-drizzle\": getTestSkill(\"drizzle\", { category: \"database\" }),\n \"web-testing-vitest\": getTestSkill(\"vitest\", { category: \"testing\" }),\n };\n\n const categories = {\n framework: createMockCategory(\"framework\" as Subcategory, \"Framework\", {\n domain: \"web\" as Domain,\n exclusive: true,\n required: true,\n }),\n \"client-state\": createMockCategory(\"client-state\" as Subcategory, \"State\", {\n domain: \"web\" as Domain,\n order: 1,\n }),\n styling: createMockCategory(\"styling\" as Subcategory, \"Styling\", {\n domain: \"web\" as Domain,\n order: 2,\n }),\n api: createMockCategory(\"api\" as Subcategory, \"Backend Framework\", {\n domain: \"api\" as Domain,\n exclusive: true,\n required: true,\n }),\n database: createMockCategory(\"database\" as Subcategory, \"Database\", {\n domain: \"api\" as Domain,\n order: 1,\n }),\n testing: createMockCategory(\"testing\" as Subcategory, \"Testing\", {\n domain: \"shared\" as Domain,\n exclusive: false,\n order: 10,\n }),\n } as Record<Subcategory, CategoryDefinition>;\n\n const suggestedStacks: ResolvedStack[] = [\n createMockResolvedStack(\"nextjs-fullstack\", \"Next.js Fullstack\", {\n description: \"Complete Next.js stack with React and Hono\",\n audience: [\"startups\", \"enterprise\"],\n skills: {\n \"web-developer\": {\n framework: \"web-framework-react\",\n \"client-state\": \"web-state-zustand\",\n styling: \"web-styling-scss-modules\",\n },\n \"api-developer\": {\n api: \"api-framework-hono\",\n database: \"api-database-drizzle\",\n },\n } as ResolvedStack[\"skills\"],\n allSkillIds: [\n \"web-framework-react\",\n \"web-state-zustand\",\n \"web-styling-scss-modules\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n ],\n philosophy: \"Modern, type-safe fullstack development\",\n }),\n createMockResolvedStack(\"vue-stack\", \"Vue Stack\", {\n description: \"Vue.js frontend stack\",\n audience: [\"startups\"],\n skills: {\n \"web-developer\": {\n framework: \"web-framework-vue\",\n },\n } as ResolvedStack[\"skills\"],\n allSkillIds: [\"web-framework-vue\"],\n philosophy: \"Progressive framework approach\",\n }),\n ];\n\n const displayNameToId = {\n react: \"web-framework-react\",\n vue: \"web-framework-vue\",\n zustand: \"web-state-zustand\",\n \"scss-modules\": \"web-styling-scss-modules\",\n hono: \"api-framework-hono\",\n drizzle: \"api-database-drizzle\",\n vitest: \"web-testing-vitest\",\n // Double cast needed: object literal's string keys are not assignable to branded\n // SkillDisplayName/SkillId types without going through `unknown` first (boundary cast)\n } as unknown as Record<SkillDisplayName, SkillId>;\n\n const displayNames = {} as Record<SkillId, SkillDisplayName>;\n for (const [displayName, fullId] of typedEntries(displayNameToId)) {\n (displayNames as Record<string, string>)[fullId] = displayName;\n }\n\n return createMockMatrix(skills, {\n categories,\n suggestedStacks,\n displayNameToId,\n displayNames,\n ...overrides,\n });\n}\n\n/**\n * Builds a lightweight test matrix with 4 skills, 4 categories, and 2 stacks.\n * Use instead of createComprehensiveMatrix when relationship data is not needed.\n * @returns A minimal MergedSkillsMatrix for basic integration tests\n */\nexport function createBasicMatrix(overrides?: Partial<MergedSkillsMatrix>): MergedSkillsMatrix {\n // Bare Subcategory IDs — see createComprehensiveMatrix comment\n const skills = {\n \"web-framework-react\": getTestSkill(\"react\", { category: \"framework\" }),\n \"web-state-zustand\": getTestSkill(\"zustand\", { category: \"client-state\" }),\n \"api-framework-hono\": getTestSkill(\"hono\", { category: \"api\" }),\n \"web-testing-vitest\": getTestSkill(\"vitest\", { category: \"testing\" }),\n };\n\n const suggestedStacks: ResolvedStack[] = [\n createMockResolvedStack(\"react-fullstack\", \"React Fullstack\", {\n allSkillIds: [\"web-framework-react\", \"web-state-zustand\", \"api-framework-hono\"],\n }),\n createMockResolvedStack(\"testing-stack\", \"Testing Stack\", {\n allSkillIds: [\"web-testing-vitest\"],\n }),\n ];\n\n return createMockMatrix(skills, {\n suggestedStacks,\n categories: {\n framework: createMockCategory(\"framework\" as Subcategory, \"Framework\", {\n domain: \"web\" as Domain,\n exclusive: true,\n required: true,\n }),\n \"client-state\": createMockCategory(\"client-state\" as Subcategory, \"State\", {\n domain: \"web\" as Domain,\n order: 1,\n }),\n api: createMockCategory(\"api\" as Subcategory, \"Backend Framework\", {\n domain: \"api\" as Domain,\n exclusive: true,\n required: true,\n }),\n testing: createMockCategory(\"testing\" as Subcategory, \"Testing Framework\", {\n domain: \"shared\" as Domain,\n exclusive: false,\n }),\n } as Record<Subcategory, CategoryDefinition>,\n ...overrides,\n });\n}\n\nexport { getTestSkill } from \"./test-fixtures\";\nexport type { TestSkillName } from \"./test-fixtures\";\n"],"mappings":"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","names":[]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
|
|
6
6
|
// src/cli/components/hooks/use-focused-list-item.ts
|
|
7
7
|
init_esm_shims();
|
|
8
|
-
import { useState, useCallback,
|
|
8
|
+
import { useState, useCallback, useRef } from "react";
|
|
9
9
|
function useFocusedListItem(rowCount, getColCount, options = {}) {
|
|
10
10
|
const {
|
|
11
11
|
wrap = true,
|
|
@@ -19,17 +19,11 @@ function useFocusedListItem(rowCount, getColCount, options = {}) {
|
|
|
19
19
|
const [focusedRow, setFocusedRow] = useState(initialRow);
|
|
20
20
|
const [focusedCol, setFocusedCol] = useState(initialCol);
|
|
21
21
|
const focusedRowRef = useRef(focusedRow);
|
|
22
|
+
focusedRowRef.current = focusedRow;
|
|
22
23
|
const focusedColRef = useRef(focusedCol);
|
|
24
|
+
focusedColRef.current = focusedCol;
|
|
23
25
|
const onChangeRef = useRef(onChange);
|
|
24
|
-
|
|
25
|
-
focusedRowRef.current = focusedRow;
|
|
26
|
-
}, [focusedRow]);
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
focusedColRef.current = focusedCol;
|
|
29
|
-
}, [focusedCol]);
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
onChangeRef.current = onChange;
|
|
32
|
-
}, [onChange]);
|
|
26
|
+
onChangeRef.current = onChange;
|
|
33
27
|
const applyFocus = useCallback((row, col) => {
|
|
34
28
|
setFocusedRow(row);
|
|
35
29
|
setFocusedCol(col);
|
|
@@ -102,4 +96,4 @@ function useFocusedListItem(rowCount, getColCount, options = {}) {
|
|
|
102
96
|
export {
|
|
103
97
|
useFocusedListItem
|
|
104
98
|
};
|
|
105
|
-
//# sourceMappingURL=chunk-
|
|
99
|
+
//# sourceMappingURL=chunk-GG4BSB6S.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/hooks/use-focused-list-item.ts"],"sourcesContent":["import { useState, useCallback, useRef } from \"react\";\n\ntype Direction = \"up\" | \"down\" | \"left\" | \"right\";\n\ntype UseFocusedListItemOptions = {\n /** Wrap around when reaching boundaries (default: true) */\n wrap?: boolean;\n /** Returns true if a row should be skipped during vertical navigation */\n isRowLocked?: (row: number) => boolean;\n /** Custom column finder for skipping disabled items on horizontal nav.\n * Receives the row, current column, and direction (+1 right, -1 left).\n * Should return the next valid column index. */\n findValidCol?: (row: number, currentCol: number, direction: 1 | -1) => number;\n /** Called after vertical navigation to adjust the clamped column\n * (e.g. to skip disabled items). Returns the adjusted column index. */\n adjustCol?: (row: number, clampedCol: number) => number;\n /** Called whenever focused position changes */\n onChange?: (row: number, col: number) => void;\n /** Initial row index (default: 0) */\n initialRow?: number;\n /** Initial col index (default: 0) */\n initialCol?: number;\n};\n\ntype UseFocusedListItemResult = {\n focusedRow: number;\n focusedCol: number;\n setFocused: (row: number, col: number) => void;\n moveFocus: (direction: Direction) => void;\n};\n\n/**\n * 2D grid focus management: tracks (row, col) position and handles\n * directional movement with wrapping, column clamping, row locking,\n * and optional disabled-column skipping.\n */\nexport function useFocusedListItem(\n rowCount: number,\n getColCount: (row: number) => number,\n options: UseFocusedListItemOptions = {},\n): UseFocusedListItemResult {\n const {\n wrap = true,\n isRowLocked,\n findValidCol,\n adjustCol,\n onChange,\n initialRow = 0,\n initialCol = 0,\n } = options;\n\n const [focusedRow, setFocusedRow] = useState(initialRow);\n const [focusedCol, setFocusedCol] = useState(initialCol);\n\n // Refs for stable callback access without stale closures.\n // Synced during render (not via useEffect) to prevent a timing gap where\n // the ref holds stale values when an input event arrives between render\n // and effect execution (e.g. after a domain-switch remount).\n const focusedRowRef = useRef(focusedRow);\n focusedRowRef.current = focusedRow;\n\n const focusedColRef = useRef(focusedCol);\n focusedColRef.current = focusedCol;\n\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const applyFocus = useCallback((row: number, col: number) => {\n setFocusedRow(row);\n setFocusedCol(col);\n onChangeRef.current?.(row, col);\n }, []);\n\n const setFocused = applyFocus;\n\n const findNextUnlockedRow = useCallback(\n (fromRow: number, direction: 1 | -1): number => {\n if (!isRowLocked || rowCount === 0) {\n if (wrap) {\n return (fromRow + direction + rowCount) % rowCount;\n }\n const next = fromRow + direction;\n return Math.max(0, Math.min(rowCount - 1, next));\n }\n\n let index = fromRow;\n let attempts = 0;\n\n while (attempts < rowCount) {\n index += direction;\n\n if (wrap) {\n if (index < 0) index = rowCount - 1;\n if (index >= rowCount) index = 0;\n } else {\n if (index < 0) index = 0;\n if (index >= rowCount) index = rowCount - 1;\n }\n\n if (!isRowLocked(index)) {\n return index;\n }\n\n attempts++;\n }\n\n return fromRow;\n },\n [rowCount, wrap, isRowLocked],\n );\n\n const moveFocus = useCallback(\n (direction: Direction) => {\n const currentRow = focusedRowRef.current;\n const currentCol = focusedColRef.current;\n\n if (direction === \"left\" || direction === \"right\") {\n const colCount = getColCount(currentRow);\n if (colCount === 0) return;\n\n const step = direction === \"right\" ? 1 : -1;\n\n if (findValidCol) {\n const newCol = findValidCol(currentRow, currentCol, step);\n applyFocus(currentRow, newCol);\n } else if (wrap) {\n const newCol = (currentCol + step + colCount) % colCount;\n applyFocus(currentRow, newCol);\n } else {\n const newCol = Math.max(0, Math.min(colCount - 1, currentCol + step));\n applyFocus(currentRow, newCol);\n }\n } else {\n const step = direction === \"down\" ? 1 : -1;\n const newRow = findNextUnlockedRow(currentRow, step);\n const newRowColCount = getColCount(newRow);\n let finalCol = Math.min(currentCol, Math.max(0, newRowColCount - 1));\n\n if (adjustCol) {\n finalCol = adjustCol(newRow, finalCol);\n }\n\n applyFocus(newRow, finalCol);\n }\n },\n [getColCount, wrap, findValidCol, adjustCol, findNextUnlockedRow, applyFocus],\n );\n\n return { focusedRow, focusedCol, setFocused, moveFocus };\n}\n"],"mappings":";;;;;;AAAA;AAAA,SAAS,UAAU,aAAa,cAAc;AAoCvC,SAAS,mBACd,UACA,aACA,UAAqC,CAAC,GACZ;AAC1B,QAAM;AAAA,IACJ,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,EACf,IAAI;AAEJ,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,UAAU;AACvD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,UAAU;AAMvD,QAAM,gBAAgB,OAAO,UAAU;AACvC,gBAAc,UAAU;AAExB,QAAM,gBAAgB,OAAO,UAAU;AACvC,gBAAc,UAAU;AAExB,QAAM,cAAc,OAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,QAAM,aAAa,YAAY,CAAC,KAAa,QAAgB;AAC3D,kBAAc,GAAG;AACjB,kBAAc,GAAG;AACjB,gBAAY,UAAU,KAAK,GAAG;AAAA,EAChC,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa;AAEnB,QAAM,sBAAsB;AAAA,IAC1B,CAAC,SAAiB,cAA8B;AAC9C,UAAI,CAAC,eAAe,aAAa,GAAG;AAClC,YAAI,MAAM;AACR,kBAAQ,UAAU,YAAY,YAAY;AAAA,QAC5C;AACA,cAAM,OAAO,UAAU;AACvB,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,GAAG,IAAI,CAAC;AAAA,MACjD;AAEA,UAAI,QAAQ;AACZ,UAAI,WAAW;AAEf,aAAO,WAAW,UAAU;AAC1B,iBAAS;AAET,YAAI,MAAM;AACR,cAAI,QAAQ,EAAG,SAAQ,WAAW;AAClC,cAAI,SAAS,SAAU,SAAQ;AAAA,QACjC,OAAO;AACL,cAAI,QAAQ,EAAG,SAAQ;AACvB,cAAI,SAAS,SAAU,SAAQ,WAAW;AAAA,QAC5C;AAEA,YAAI,CAAC,YAAY,KAAK,GAAG;AACvB,iBAAO;AAAA,QACT;AAEA;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,UAAU,MAAM,WAAW;AAAA,EAC9B;AAEA,QAAM,YAAY;AAAA,IAChB,CAAC,cAAyB;AACxB,YAAM,aAAa,cAAc;AACjC,YAAM,aAAa,cAAc;AAEjC,UAAI,cAAc,UAAU,cAAc,SAAS;AACjD,cAAM,WAAW,YAAY,UAAU;AACvC,YAAI,aAAa,EAAG;AAEpB,cAAM,OAAO,cAAc,UAAU,IAAI;AAEzC,YAAI,cAAc;AAChB,gBAAM,SAAS,aAAa,YAAY,YAAY,IAAI;AACxD,qBAAW,YAAY,MAAM;AAAA,QAC/B,WAAW,MAAM;AACf,gBAAM,UAAU,aAAa,OAAO,YAAY;AAChD,qBAAW,YAAY,MAAM;AAAA,QAC/B,OAAO;AACL,gBAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,GAAG,aAAa,IAAI,CAAC;AACpE,qBAAW,YAAY,MAAM;AAAA,QAC/B;AAAA,MACF,OAAO;AACL,cAAM,OAAO,cAAc,SAAS,IAAI;AACxC,cAAM,SAAS,oBAAoB,YAAY,IAAI;AACnD,cAAM,iBAAiB,YAAY,MAAM;AACzC,YAAI,WAAW,KAAK,IAAI,YAAY,KAAK,IAAI,GAAG,iBAAiB,CAAC,CAAC;AAEnE,YAAI,WAAW;AACb,qBAAW,UAAU,QAAQ,QAAQ;AAAA,QACvC;AAEA,mBAAW,QAAQ,QAAQ;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,CAAC,aAAa,MAAM,cAAc,WAAW,qBAAqB,UAAU;AAAA,EAC9E;AAEA,SAAO,EAAE,YAAY,YAAY,YAAY,UAAU;AACzD;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_BRANDING
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZBJQXDQN.js";
|
|
5
5
|
import {
|
|
6
6
|
init_esm_shims
|
|
7
7
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -66,4 +66,4 @@ export {
|
|
|
66
66
|
INFO_MESSAGES,
|
|
67
67
|
DRY_RUN_MESSAGES
|
|
68
68
|
};
|
|
69
|
-
//# sourceMappingURL=chunk-
|
|
69
|
+
//# sourceMappingURL=chunk-HKDE4LJW.js.map
|