agents-inc 0.156.0 → 0.157.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 +31 -0
- package/dist/{chunk-PMUABBPG.js → chunk-24IGOJ7E.js} +9 -13
- package/dist/chunk-24IGOJ7E.js.map +1 -0
- package/dist/{chunk-H6UTKTLK.js → chunk-3E52LCYC.js} +98 -34
- package/dist/chunk-3E52LCYC.js.map +1 -0
- package/dist/{chunk-UMH2YZKG.js → chunk-4CIAZOTD.js} +4 -6
- package/dist/{chunk-UMH2YZKG.js.map → chunk-4CIAZOTD.js.map} +1 -1
- package/dist/{chunk-D2CAV7MG.js → chunk-4DMFK67G.js} +2 -2
- package/dist/{chunk-PNMM5HNX.js → chunk-4EPJWN7C.js} +9 -10
- package/dist/chunk-4EPJWN7C.js.map +1 -0
- package/dist/{chunk-MHRC3KRX.js → chunk-4KHUHPX4.js} +3 -3
- package/dist/chunk-4KHUHPX4.js.map +1 -0
- package/dist/{chunk-2H7UWE2G.js → chunk-CEGHC7L5.js} +13 -12
- package/dist/chunk-CEGHC7L5.js.map +1 -0
- package/dist/{chunk-MO5FGLVS.js → chunk-DCIC35R7.js} +11 -12
- package/dist/chunk-DCIC35R7.js.map +1 -0
- package/dist/{chunk-ILUVL7WM.js → chunk-DZD25NHW.js} +2 -2
- package/dist/{chunk-IO5YBKHV.js → chunk-G6G2FT2G.js} +10 -8
- package/dist/chunk-G6G2FT2G.js.map +1 -0
- package/dist/{chunk-RWOYPOMR.js → chunk-IGOFZG3S.js} +19 -5
- package/dist/chunk-IGOFZG3S.js.map +1 -0
- package/dist/{chunk-CLFHC2DK.js → chunk-K2VTGT45.js} +17 -18
- package/dist/chunk-K2VTGT45.js.map +1 -0
- package/dist/{chunk-YO2LTXB4.js → chunk-KTXVQ7OM.js} +115 -10
- package/dist/chunk-KTXVQ7OM.js.map +1 -0
- package/dist/{chunk-SY4X2LND.js → chunk-KUZBMEWR.js} +3 -3
- package/dist/{chunk-ZUAZHDKP.js → chunk-LDBVIPTP.js} +277 -40
- package/dist/chunk-LDBVIPTP.js.map +1 -0
- package/dist/{chunk-PCC4LBKB.js → chunk-MU2TQ5KK.js} +2 -2
- package/dist/{chunk-4G2YHZIM.js → chunk-O4K42CJB.js} +4 -6
- package/dist/{chunk-4G2YHZIM.js.map → chunk-O4K42CJB.js.map} +1 -1
- package/dist/{chunk-HXKOIWLU.js → chunk-P6OKOH62.js} +2 -6
- package/dist/chunk-P6OKOH62.js.map +1 -0
- package/dist/{chunk-IXRZAHZF.js → chunk-PGZSNNDA.js} +4 -4
- package/dist/{chunk-LJCNUP6M.js → chunk-PVPNVK3W.js} +2 -2
- package/dist/{chunk-4A4L3YIW.js → chunk-PXGDA2SY.js} +6 -7
- package/dist/chunk-PXGDA2SY.js.map +1 -0
- package/dist/{chunk-G47TDUK3.js → chunk-QNAMXQKF.js} +2 -2
- package/dist/{chunk-5OKLCVM4.js → chunk-QO4XD5V5.js} +3 -3
- package/dist/{chunk-5F2YR5XV.js → chunk-QXPMQBEI.js} +15 -5
- package/dist/chunk-QXPMQBEI.js.map +1 -0
- package/dist/{chunk-F5T6TV4Z.js → chunk-RLU2IXD3.js} +40 -14
- package/dist/chunk-RLU2IXD3.js.map +1 -0
- package/dist/{chunk-WCAUUBHO.js → chunk-RVXI5VQU.js} +14758 -14501
- package/dist/chunk-RVXI5VQU.js.map +1 -0
- package/dist/{chunk-WFRTHH3A.js → chunk-TZRXWFF5.js} +3 -3
- package/dist/{chunk-HG4JPXJT.js → chunk-V7PMQDDU.js} +23 -10
- package/dist/chunk-V7PMQDDU.js.map +1 -0
- package/dist/{chunk-Y5Y7XHVU.js → chunk-VI6U2PJG.js} +4 -4
- package/dist/{chunk-TBOVYLQJ.js → chunk-VTIDLRNA.js} +2 -2
- package/dist/{chunk-OKH64JZE.js → chunk-WCZNQECQ.js} +2 -2
- package/dist/{chunk-QWVXOCXO.js → chunk-WENBESZO.js} +7 -9
- package/dist/{chunk-QWVXOCXO.js.map → chunk-WENBESZO.js.map} +1 -1
- package/dist/{chunk-TNGMF4UX.js → chunk-XOZAKFTS.js} +12 -12
- package/dist/chunk-XOZAKFTS.js.map +1 -0
- package/dist/{chunk-6RLV45HN.js → chunk-YG5YPVTJ.js} +6 -6
- package/dist/chunk-YG5YPVTJ.js.map +1 -0
- package/dist/{chunk-HTYH7CKN.js → chunk-YKFCUVHG.js} +3 -3
- package/dist/{chunk-VPASBA7P.js → chunk-YXI3BTQQ.js} +2 -2
- package/dist/chunk-Z3H2K5PK.js +1352 -0
- package/dist/chunk-Z3H2K5PK.js.map +1 -0
- package/dist/{chunk-5QZAK6J7.js → chunk-ZAQ6WMJV.js} +50 -18
- package/dist/chunk-ZAQ6WMJV.js.map +1 -0
- package/dist/{chunk-GS2NZ3GD.js → chunk-ZBYVDXZG.js} +5 -5
- package/dist/chunk-ZBYVDXZG.js.map +1 -0
- package/dist/commands/build/marketplace.js +9 -12
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +9 -12
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +15 -19
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +75 -54
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +154 -109
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +68 -38
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +36 -39
- package/dist/commands/list.js +8 -10
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +8 -11
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +10 -13
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +8 -10
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +39 -28
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +7 -10
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/removal-plan-confirm.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/wizard/category-grid.js +4 -5
- package/dist/components/wizard/checkbox-grid.js +4 -4
- package/dist/components/wizard/domain-selection.js +9 -11
- package/dist/components/wizard/run-wizard-session.js +26 -28
- package/dist/components/wizard/scroll-affordance.js +2 -2
- package/dist/components/wizard/skill-agent-summary.js +5 -7
- package/dist/components/wizard/source-grid.js +5 -6
- package/dist/components/wizard/stack-selection.js +7 -9
- package/dist/components/wizard/step-agents.js +8 -10
- package/dist/components/wizard/step-build.js +7 -9
- package/dist/components/wizard/step-confirm.js +9 -11
- package/dist/components/wizard/step-sources.js +8 -10
- package/dist/components/wizard/step-stack.js +8 -10
- package/dist/components/wizard/summary-panel.js +8 -10
- package/dist/components/wizard/toast.js +2 -2
- package/dist/components/wizard/wizard-layout.js +12 -14
- package/dist/components/wizard/wizard-tabs.js +2 -4
- package/dist/components/wizard/wizard.js +25 -27
- package/dist/hooks/init.js +36 -39
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-M6LRVISN.js +13 -0
- package/dist/recompile-project-agents-G7ZM25PC.js +17 -0
- package/dist/{source-loader-3DL3NYUX.js → source-loader-BIAEDR5R.js} +4 -8
- package/dist/src/agents/_templates/agent.liquid +2 -2
- package/dist/stores/wizard-store.js +6 -6
- package/package.json +1 -1
- package/src/agents/_templates/agent.liquid +2 -2
- package/src/schemas/custom-metadata.schema.json +1 -1
- package/src/schemas/marketplace.schema.json +2 -1
- package/dist/chunk-2H7UWE2G.js.map +0 -1
- package/dist/chunk-4A4L3YIW.js.map +0 -1
- package/dist/chunk-5F2YR5XV.js.map +0 -1
- package/dist/chunk-5QZAK6J7.js.map +0 -1
- package/dist/chunk-6RLV45HN.js.map +0 -1
- package/dist/chunk-CLFHC2DK.js.map +0 -1
- package/dist/chunk-F2AMBBIA.js +0 -64
- package/dist/chunk-F2AMBBIA.js.map +0 -1
- package/dist/chunk-F5T6TV4Z.js.map +0 -1
- package/dist/chunk-GS2NZ3GD.js.map +0 -1
- package/dist/chunk-H6UTKTLK.js.map +0 -1
- package/dist/chunk-HG4JPXJT.js.map +0 -1
- package/dist/chunk-HXKOIWLU.js.map +0 -1
- package/dist/chunk-IO5YBKHV.js.map +0 -1
- package/dist/chunk-MHRC3KRX.js.map +0 -1
- package/dist/chunk-MO5FGLVS.js.map +0 -1
- package/dist/chunk-PMUABBPG.js.map +0 -1
- package/dist/chunk-PNMM5HNX.js.map +0 -1
- package/dist/chunk-RWOYPOMR.js.map +0 -1
- package/dist/chunk-TNGMF4UX.js.map +0 -1
- package/dist/chunk-VASLW636.js +0 -23
- package/dist/chunk-VASLW636.js.map +0 -1
- package/dist/chunk-WCAUUBHO.js.map +0 -1
- package/dist/chunk-WUQ3MTPF.js +0 -173
- package/dist/chunk-WUQ3MTPF.js.map +0 -1
- package/dist/chunk-XAXJWXI4.js +0 -1667
- package/dist/chunk-XAXJWXI4.js.map +0 -1
- package/dist/chunk-YO2LTXB4.js.map +0 -1
- package/dist/chunk-ZUAZHDKP.js.map +0 -1
- package/dist/copy-local-skills-NSUTBVLJ.js +0 -14
- package/dist/load-agent-defs-X4E57I2U.js +0 -15
- package/dist/loader-G6BFG2VA.js +0 -24
- package/dist/recompile-project-agents-JE4MM72I.js +0 -20
- package/dist/recompile-project-agents-JE4MM72I.js.map +0 -1
- package/dist/source-loader-3DL3NYUX.js.map +0 -1
- /package/dist/{chunk-D2CAV7MG.js.map → chunk-4DMFK67G.js.map} +0 -0
- /package/dist/{chunk-ILUVL7WM.js.map → chunk-DZD25NHW.js.map} +0 -0
- /package/dist/{chunk-SY4X2LND.js.map → chunk-KUZBMEWR.js.map} +0 -0
- /package/dist/{chunk-PCC4LBKB.js.map → chunk-MU2TQ5KK.js.map} +0 -0
- /package/dist/{chunk-IXRZAHZF.js.map → chunk-PGZSNNDA.js.map} +0 -0
- /package/dist/{chunk-LJCNUP6M.js.map → chunk-PVPNVK3W.js.map} +0 -0
- /package/dist/{chunk-G47TDUK3.js.map → chunk-QNAMXQKF.js.map} +0 -0
- /package/dist/{chunk-5OKLCVM4.js.map → chunk-QO4XD5V5.js.map} +0 -0
- /package/dist/{chunk-WFRTHH3A.js.map → chunk-TZRXWFF5.js.map} +0 -0
- /package/dist/{chunk-Y5Y7XHVU.js.map → chunk-VI6U2PJG.js.map} +0 -0
- /package/dist/{chunk-TBOVYLQJ.js.map → chunk-VTIDLRNA.js.map} +0 -0
- /package/dist/{chunk-OKH64JZE.js.map → chunk-WCZNQECQ.js.map} +0 -0
- /package/dist/{chunk-HTYH7CKN.js.map → chunk-YKFCUVHG.js.map} +0 -0
- /package/dist/{chunk-VPASBA7P.js.map → chunk-YXI3BTQQ.js.map} +0 -0
- /package/dist/{copy-local-skills-NSUTBVLJ.js.map → load-agent-defs-M6LRVISN.js.map} +0 -0
- /package/dist/{load-agent-defs-X4E57I2U.js.map → recompile-project-agents-G7ZM25PC.js.map} +0 -0
- /package/dist/{loader-G6BFG2VA.js.map → source-loader-BIAEDR5R.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CLI_COLORS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-G6G2FT2G.js";
|
|
5
5
|
|
|
6
6
|
// src/cli/components/wizard/wizard-tabs.tsx
|
|
7
7
|
import { Box, Text } from "ink";
|
|
@@ -18,9 +18,6 @@ var WIZARD_STEP_LABELS = {
|
|
|
18
18
|
function wizardTabsFor(flow) {
|
|
19
19
|
return flow.map((id) => ({ id, label: WIZARD_STEP_LABELS[id] }));
|
|
20
20
|
}
|
|
21
|
-
function formatStepLabel(stepId) {
|
|
22
|
-
return WIZARD_STEP_LABELS[stepId];
|
|
23
|
-
}
|
|
24
21
|
var getStepState = (stepId, currentStep, completedSteps, skippedSteps) => {
|
|
25
22
|
if (completedSteps.includes(stepId)) return "completed";
|
|
26
23
|
if (stepId === currentStep) return "current";
|
|
@@ -166,7 +163,6 @@ var WizardTabs = ({
|
|
|
166
163
|
|
|
167
164
|
export {
|
|
168
165
|
wizardTabsFor,
|
|
169
|
-
formatStepLabel,
|
|
170
166
|
WizardTabs
|
|
171
167
|
};
|
|
172
|
-
//# sourceMappingURL=chunk-
|
|
168
|
+
//# sourceMappingURL=chunk-P6OKOH62.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/wizard-tabs.tsx"],"sourcesContent":["import { Box, Text } from \"ink\";\nimport React from \"react\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport type { WizardStep } from \"../../stores/wizard-store.js\";\nimport type { Domain } from \"../../types/index.js\";\n\ntype WizardTabStep = {\n id: WizardStep;\n label: string;\n};\n\nexport type TabDropdownItem = {\n id: string;\n label: string;\n};\n\nexport type TabDropdownProps = {\n items: TabDropdownItem[];\n activeId?: string | undefined;\n isSubNav?: boolean | undefined;\n inline?: boolean | undefined;\n};\n\nexport type DomainNavProps = {\n domains: Domain[];\n activeDomain: Domain;\n getDomainLabel: (domain: Domain) => string;\n};\n\nexport type WizardTabsProps = {\n steps: WizardTabStep[];\n currentStep: WizardStep;\n completedSteps: WizardStep[];\n skippedSteps?: WizardStep[] | undefined;\n version?: string | undefined;\n domainNav?: DomainNavProps | undefined;\n dropdowns?: Partial<Record<WizardStep, TabDropdownProps>>;\n};\n\n/**\n * Display label per wizard step. Step ORDER has a single source: WIZARD_STEP_ORDER.\n *\n * The `sources` step is where a user picks where each skill comes from, so that is what\n * its tab is called. `e2e/pages/constants.ts` `WIZARD_TAB_LABELS` mirrors the whole set,\n * so a label moves in both places or in neither.\n */\nconst WIZARD_STEP_LABELS = {\n stack: \"Stack\",\n domains: \"Domains\",\n build: \"Skills\",\n sources: \"Sources\",\n agents: \"Agents\",\n confirm: \"Confirm\",\n} as const satisfies Record<WizardStep, string>;\n\n/**\n * The tabs for a step flow — one per step that flow runs, in its order.\n *\n * A function of the flow rather than a constant over `WIZARD_STEP_ORDER`: a\n * source that ships no stacks gives the wizard no stack step (see\n * `getActiveStepFlow`), and a bar drawn from every step the wizard HAS would\n * paint a Stack tab for a step this run never opens.\n */\nexport function wizardTabsFor(flow: WizardStep[]): WizardTabStep[] {\n return flow.map((id) => ({ id, label: WIZARD_STEP_LABELS[id] }));\n}\n\ntype StepState = \"completed\" | \"current\" | \"pending\" | \"skipped\";\n\nconst getStepState = (\n stepId: WizardStep,\n currentStep: WizardStep,\n completedSteps: WizardStep[],\n skippedSteps: WizardStep[],\n): StepState => {\n if (completedSteps.includes(stepId)) return \"completed\";\n if (stepId === currentStep) return \"current\";\n if (skippedSteps.includes(stepId)) return \"skipped\";\n return \"pending\";\n};\n\ntype TabProps = {\n step: WizardTabStep;\n state: StepState;\n};\n\nconst Tab: React.FC<TabProps> = ({ step, state }) => {\n const label = step.label;\n\n switch (state) {\n case \"current\":\n return (\n <Text color={CLI_COLORS.BLACK} backgroundColor={CLI_COLORS.WARNING} bold>\n {\" \"}\n {label}{\" \"}\n </Text>\n );\n case \"completed\":\n return <Text>{label}</Text>;\n case \"skipped\":\n return <Text dimColor>{label}</Text>;\n case \"pending\":\n return <Text color={CLI_COLORS.UNFOCUSED}>{label}</Text>;\n default: {\n const _exhaustive: never = state;\n return _exhaustive;\n }\n }\n};\n\nconst TabDropdown: React.FC<TabDropdownProps> = ({ items, activeId, isSubNav = false, inline }) => (\n <Box\n {...(inline ? {} : { position: \"absolute\" as const, marginTop: 2 })}\n flexDirection=\"row\"\n columnGap={0}\n paddingLeft={1}\n paddingRight={1}\n borderStyle=\"single\"\n borderColor=\"blackBright\"\n flexWrap=\"wrap\"\n >\n {items.map((item) => {\n const isActive = item.id === activeId;\n return (\n <Text\n key={item.id}\n dimColor={!isSubNav}\n bold={isSubNav && isActive}\n color={isActive ? CLI_COLORS.WARNING : CLI_COLORS.UNFOCUSED}\n >\n {\" \"}\n {item.label}{\" \"}\n </Text>\n );\n })}\n </Box>\n);\n\nconst DomainNav: React.FC<DomainNavProps & { inline?: boolean }> = ({\n domains,\n activeDomain,\n getDomainLabel,\n inline,\n}) => (\n <TabDropdown\n items={domains.map((d) => ({ id: d, label: getDomainLabel(d) }))}\n activeId={activeDomain}\n isSubNav\n inline={inline}\n />\n);\n\nconst DOMAIN_NAV_CHAR_THRESHOLD = 25;\n\nconst getStepJustifyContent = (stepId: WizardStep): \"flex-start\" | \"flex-end\" | \"center\" => {\n if (stepId === \"stack\") return \"flex-start\";\n if (stepId === \"confirm\") return \"flex-end\";\n return \"center\";\n};\n\nconst isDomainNavOverThreshold = (domainNav: DomainNavProps): boolean =>\n domainNav.domains.reduce((sum, d) => sum + domainNav.getDomainLabel(d).length, 0) >\n DOMAIN_NAV_CHAR_THRESHOLD;\n\nexport const WizardTabs: React.FC<WizardTabsProps> = ({\n steps,\n currentStep,\n completedSteps,\n skippedSteps = [],\n version,\n domainNav,\n dropdowns,\n}) => {\n const shouldHoistDomainNav = domainNav ? isDomainNavOverThreshold(domainNav) : false;\n\n return (\n <>\n <Box\n flexDirection=\"row\"\n columnGap={2}\n borderColor=\"blackBright\"\n borderStyle=\"single\"\n paddingX={1}\n alignItems=\"center\"\n marginBottom={shouldHoistDomainNav ? 0 : 3}\n >\n {steps.map((step) => {\n const state = getStepState(step.id, currentStep, completedSteps, skippedSteps);\n\n if (step.id === \"build\" && domainNav && !shouldHoistDomainNav) {\n return (\n <Box\n key={step.id}\n position=\"relative\"\n display=\"flex\"\n justifyContent={getStepJustifyContent(step.id)}\n >\n <Tab step={step} state={state} />\n <DomainNav {...domainNav} />\n </Box>\n );\n }\n\n // Generic dropdown for any step\n const dropdown = dropdowns?.[step.id];\n if (dropdown) {\n return (\n <Box\n key={step.id}\n position=\"relative\"\n display=\"flex\"\n justifyContent={getStepJustifyContent(step.id)}\n >\n <Tab step={step} state={state} />\n <TabDropdown {...dropdown} />\n </Box>\n );\n }\n\n return <Tab key={step.id} step={step} state={state} />;\n })}\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text dimColor>{`v${version}`}</Text>\n </Box>\n </Box>\n {domainNav && shouldHoistDomainNav && (\n <Box>\n <DomainNav {...domainNav} inline />\n </Box>\n )}\n </>\n );\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
Wizard
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XOZAKFTS.js";
|
|
5
5
|
import {
|
|
6
6
|
promptValue
|
|
7
7
|
} from "./chunk-JCPANDNR.js";
|
|
8
8
|
import {
|
|
9
9
|
hydrateWizardStore
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RLU2IXD3.js";
|
|
11
11
|
import {
|
|
12
12
|
disableBuffering,
|
|
13
13
|
drainBuffer,
|
|
14
14
|
enableBuffering
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-RVXI5VQU.js";
|
|
16
16
|
|
|
17
17
|
// src/cli/components/wizard/run-wizard-session.tsx
|
|
18
18
|
import "react";
|
|
@@ -50,4 +50,4 @@ async function runWizardSession(options) {
|
|
|
50
50
|
export {
|
|
51
51
|
runWizardSession
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-PGZSNNDA.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SummaryPanel
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YG5YPVTJ.js";
|
|
5
5
|
|
|
6
6
|
// src/cli/components/wizard/step-confirm.tsx
|
|
7
7
|
import { useInput } from "ink";
|
|
@@ -22,4 +22,4 @@ var StepConfirm = ({ onComplete, onBack }) => {
|
|
|
22
22
|
export {
|
|
23
23
|
StepConfirm
|
|
24
24
|
};
|
|
25
|
-
//# sourceMappingURL=chunk-
|
|
25
|
+
//# sourceMappingURL=chunk-PVPNVK3W.js.map
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
} from "./chunk-WTJ3AY33.js";
|
|
10
10
|
import {
|
|
11
11
|
useSectionScroll
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WCZNQECQ.js";
|
|
13
13
|
import {
|
|
14
14
|
getSkillById
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-IGOFZG3S.js";
|
|
16
16
|
import {
|
|
17
17
|
CLI_COLORS
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-G6G2FT2G.js";
|
|
19
19
|
|
|
20
20
|
// src/cli/components/wizard/category-grid.tsx
|
|
21
21
|
import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
|
|
@@ -99,15 +99,14 @@ var wrapOptionIndex = (length, currentIndex, direction) => {
|
|
|
99
99
|
if (length === 0) return currentIndex;
|
|
100
100
|
return (currentIndex + direction + length) % length;
|
|
101
101
|
};
|
|
102
|
+
var advisoryAnnotation = (state) => state.status === "normal" ? null : `(${state.status}: ${state.reason})`;
|
|
102
103
|
var getCompatibilityLabel = (option) => {
|
|
103
104
|
if (option.selected && option.hasUnmetRequirements && option.unmetRequirementsReason) {
|
|
104
105
|
return `(${option.unmetRequirementsReason})`;
|
|
105
106
|
}
|
|
106
107
|
if (option.selected) return null;
|
|
107
108
|
if (option.requiredBy) return `(required by ${option.requiredBy})`;
|
|
108
|
-
|
|
109
|
-
if (option.state.status === "discouraged") return "(discouraged)";
|
|
110
|
-
return null;
|
|
109
|
+
return advisoryAnnotation(option.state);
|
|
111
110
|
};
|
|
112
111
|
var STATUS_COLORS = {
|
|
113
112
|
incompatible: CLI_COLORS.ERROR,
|
|
@@ -266,4 +265,4 @@ var CategoryGrid = ({
|
|
|
266
265
|
export {
|
|
267
266
|
CategoryGrid
|
|
268
267
|
};
|
|
269
|
-
//# sourceMappingURL=chunk-
|
|
268
|
+
//# sourceMappingURL=chunk-PXGDA2SY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/category-grid.tsx","../src/cli/components/hooks/use-category-grid-input.ts"],"sourcesContent":["import React, { useCallback, useEffect } from \"react\";\n\nimport { Box, Text } from \"ink\";\n\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { getSkillById } from \"../../lib/matrix/matrix-provider.js\";\nimport type { Category, OptionState, SkillId, SkillScope } from \"../../types/index.js\";\nimport { useCategoryGridInput } from \"../hooks/use-category-grid-input.js\";\nimport { useFocusedListItem } from \"../hooks/use-focused-list-item.js\";\nimport { useSectionScroll } from \"../hooks/use-section-scroll.js\";\n\nexport type CategoryOption = {\n id: SkillId;\n state: OptionState;\n selected: boolean;\n local?: boolean;\n installed?: boolean;\n scope?: SkillScope;\n /** Secondary scope badge shown alongside primary (e.g. after G->P toggle, excluded tombstone) */\n secondaryScope?: SkillScope;\n source?: string;\n /** True when selected but has unmet dependency requirements (shown dimmed) */\n hasUnmetRequirements?: boolean;\n /** Explains unmet requirements (shown in label when D pressed) */\n unmetRequirementsReason?: string;\n /** Display name of the skill that requires this one (e.g. \"Next.js\") */\n requiredBy?: string;\n};\n\nexport type CategoryRow = {\n id: Category;\n displayName: string;\n required: boolean;\n exclusive: boolean;\n options: CategoryOption[];\n};\n\nexport type CategoryGridProps = {\n categories: CategoryRow[];\n /** Available height in terminal lines for the scrollable viewport. 0 = no constraint. */\n availableHeight?: number;\n showLabels: boolean;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => 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 /** Optional callback fired with the resolved SkillId of the focused cell */\n onFocusedSkillChange?: (skillId: SkillId | null) => void;\n};\n\nconst SYMBOL_REQUIRED = \"*\";\n\n/** Next option index stepping cyclically from `currentIndex`; empty rows stay put. */\nconst wrapOptionIndex = (length: number, currentIndex: number, direction: 1 | -1): number => {\n if (length === 0) return currentIndex;\n return (currentIndex + direction + length) % length;\n};\n\ntype SkillTagProps = {\n option: CategoryOption;\n isFocused: boolean;\n showLabels: boolean;\n};\n\n/**\n * The verdict word and the reason behind it — `(incompatible: conflicts with Vue\n * Composition Api)`. Every advisory state but `normal` carries a reason, so the\n * status discriminant narrows to the two that have one to state.\n *\n * The word leads rather than the reason: it is the only carrier of the verdict\n * once colour is off, a `discourages` rule's reason is free-form author prose\n * that need not identify itself as a discouragement, and `CELL_ANNOTATION` in\n * `e2e/pages/steps/build-step.ts` anchors cell-label parsing on that keyword.\n *\n * Nothing is elided. A long reason grows the tag and wraps inside its border,\n * which is what `unmetRequirementsReason` above already does.\n */\nconst advisoryAnnotation = (state: OptionState): string | null =>\n state.status === \"normal\" ? null : `(${state.status}: ${state.reason})`;\n\nconst getCompatibilityLabel = (option: CategoryOption): string | null => {\n if (option.selected && option.hasUnmetRequirements && option.unmetRequirementsReason) {\n return `(${option.unmetRequirementsReason})`;\n }\n if (option.selected) return null;\n if (option.requiredBy) return `(required by ${option.requiredBy})`;\n return advisoryAnnotation(option.state);\n};\n\nconst STATUS_COLORS: Partial<Record<OptionState[\"status\"], string>> = {\n incompatible: CLI_COLORS.ERROR,\n discouraged: CLI_COLORS.WARNING,\n};\n\n/** Selected wins, then advisory status; `fallback` covers the plain \"normal\" state. */\nfunction resolveTagColor(option: CategoryOption, fallback: string): string {\n if (option.selected) return CLI_COLORS.PRIMARY;\n return STATUS_COLORS[option.state.status] ?? fallback;\n}\n\nconst SkillTag: React.FC<SkillTagProps> = ({ option, isFocused, showLabels }) => {\n const textColor = resolveTagColor(option, CLI_COLORS.DIM);\n const hasRequiredBy = option.selected && !!option.requiredBy;\n const hasUnmetDeps = option.selected && !!option.hasUnmetRequirements;\n const isDimmed = hasUnmetDeps || hasRequiredBy;\n const showCompatibility = hasRequiredBy || hasUnmetDeps || (showLabels && isFocused);\n const compatibilityLabel = showCompatibility ? getCompatibilityLabel(option) : null;\n\n return (\n <Box\n marginRight={1}\n borderColor={isFocused ? resolveTagColor(option, CLI_COLORS.UNFOCUSED) : textColor}\n borderDimColor={!isFocused}\n borderStyle=\"single\"\n flexShrink={0}\n paddingLeft={1}\n flexDirection=\"row\"\n >\n <>\n {option.scope && (\n <>\n {[option.scope, option.secondaryScope].filter(Boolean).map((badgeScope, i) => (\n <Text key={i} color={CLI_COLORS.WARNING} backgroundColor={CLI_COLORS.LABEL_BG}>\n {badgeScope === \"global\" ? \" G \" : \" P \"}\n </Text>\n ))}\n <Text> </Text>\n </>\n )}\n <Text color={textColor} bold dimColor={isDimmed}>\n {getSkillById(option.id).displayName}{\" \"}\n </Text>\n {compatibilityLabel && (\n <Text color={textColor} dimColor>\n {compatibilityLabel}{\" \"}\n </Text>\n )}\n </>\n </Box>\n );\n};\n\ntype CategorySectionProps = {\n isFirst: boolean;\n category: CategoryRow;\n isFocused: boolean;\n focusedOptionIndex: number;\n showLabels: boolean;\n};\n\nconst CategorySection: React.FC<CategorySectionProps> = ({\n isFirst,\n category,\n isFocused,\n focusedOptionIndex,\n showLabels,\n}) => {\n const { options } = category;\n const selectedCount = options.filter((o) => o.selected).length;\n\n const selectionCounter = category.exclusive ? `(${selectedCount} of 1)` : null;\n\n return (\n <Box flexDirection=\"column\" marginTop={isFirst ? 0 : 1}>\n <Box flexDirection=\"row\">\n {isFocused ? (\n <Text color={CLI_COLORS.WHITE} backgroundColor={CLI_COLORS.LABEL_BG}>\n {` ${category.displayName}${category.required ? ` ${SYMBOL_REQUIRED}` : \"\"}${selectionCounter ? ` ${selectionCounter}` : \"\"} `}\n </Text>\n ) : (\n <>\n <Text color={CLI_COLORS.NEUTRAL}>{category.displayName}</Text>\n {category.required && <Text color={CLI_COLORS.NEUTRAL}> {SYMBOL_REQUIRED}</Text>}\n {selectionCounter && <Text dimColor> {selectionCounter}</Text>}\n </>\n )}\n </Box>\n\n <Box flexDirection=\"row\" flexWrap=\"wrap\" marginTop={0}>\n {options.map((option, index) => (\n <SkillTag\n key={option.id}\n option={option}\n isFocused={isFocused && index === focusedOptionIndex}\n showLabels={showLabels}\n />\n ))}\n </Box>\n </Box>\n );\n};\n\nexport const CategoryGrid: React.FC<CategoryGridProps> = ({\n categories,\n availableHeight = 0,\n showLabels,\n onToggle,\n onToggleLabels,\n defaultFocusedRow = 0,\n defaultFocusedCol = 0,\n onFocusChange,\n onFocusedSkillChange,\n}) => {\n const getColCount = useCallback(\n (row: number): number => categories[row]?.options.length ?? 0,\n [categories],\n );\n\n const findValidCol = useCallback(\n (row: number, currentCol: number, direction: 1 | -1): number =>\n wrapOptionIndex(categories[row]?.options.length ?? 0, currentCol, direction),\n [categories],\n );\n\n const handleFocusChange = useCallback(\n (row: number, col: number) => {\n if (showLabels) onToggleLabels();\n onFocusChange?.(row, col);\n },\n [showLabels, onToggleLabels, onFocusChange],\n );\n\n const { focusedRow, focusedCol, setFocused, moveFocus } = useFocusedListItem(\n categories.length,\n getColCount,\n {\n wrap: true,\n findValidCol,\n onChange: handleFocusChange,\n initialRow: defaultFocusedRow,\n initialCol: defaultFocusedCol,\n },\n );\n\n useCategoryGridInput({\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n });\n\n // Report the focused cell's skill on mount and whenever it changes — including\n // category reshapes that shift the cell without a navigation event. useFocusedListItem\n // only fires onChange during navigation, so the initially highlighted cell would\n // otherwise never reach the store, leaving focusedSkillId out of sync with the visual\n // focus and making the `s` scope hotkey no-op until the first arrow key.\n const focusedSkillId = categories[focusedRow]?.options[focusedCol]?.id ?? null;\n useEffect(() => {\n onFocusedSkillChange?.(focusedSkillId);\n }, [focusedSkillId, onFocusedSkillChange]);\n\n // `hiddenAbove` / `hiddenBelow` are discarded ON PURPOSE — the build grid has\n // no `ScrollAffordance` and is not getting one (owner decision). On a grid\n // this dense a half-cut card already says \"there is more\"; a counted hint\n // would be noise, and it would cost the viewport a row to say what the\n // clipped card says for free. Do not add one on the strength of the counts\n // merely being available here.\n const { setSectionRef, scrollEnabled, scrollTopPx } = useSectionScroll({\n sectionCount: categories.length,\n focusedIndex: focusedRow,\n availableHeight,\n });\n\n if (categories.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>No categories to display.</Text>\n </Box>\n );\n }\n\n const noShrink = scrollEnabled ? { flexShrink: 0 } : {};\n\n const sectionElements = categories.map((category, index) => (\n <Box key={category.id} ref={(el) => setSectionRef(index, el)} {...noShrink}>\n <CategorySection\n category={category}\n isFocused={index === focusedRow}\n focusedOptionIndex={focusedCol}\n showLabels={showLabels}\n isFirst={index === 0}\n />\n </Box>\n ));\n\n return (\n <Box\n flexDirection=\"column\"\n {...(scrollEnabled\n ? { height: availableHeight, overflow: \"hidden\" as const }\n : { flexGrow: 1 })}\n >\n <Box flexDirection=\"column\" marginTop={scrollTopPx > 0 ? -scrollTopPx : 0} {...noShrink}>\n {sectionElements}\n </Box>\n </Box>\n );\n};\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useInput, type Key } from \"ink\";\n\nimport type { Category, SkillId } from \"../../types/index.js\";\nimport type { CategoryRow } from \"../wizard/category-grid.js\";\nimport type { Direction } from \"./use-focused-list-item.js\";\nimport { HOTKEY_TOGGLE_LABELS, KEY_SPACE, isHotkey } from \"../wizard/hotkeys.js\";\n\n/** Find next section index (wrapping forward) */\nconst findNextIndex = (items: { length: number }, currentIndex: number): number => {\n const length = items.length;\n if (length === 0) return currentIndex;\n return (currentIndex + 1) % length;\n};\n\ntype UseCategoryGridInputOptions = {\n categories: CategoryRow[];\n focusedRow: number;\n focusedCol: number;\n setFocused: (row: number, col: number) => void;\n moveFocus: (direction: Direction) => void;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n};\n\nexport function useCategoryGridInput({\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n}: UseCategoryGridInputOptions): void {\n const currentRow = categories[focusedRow];\n // Memoised so the effect below keys on the row actually changing — the `[]`\n // fallback used to be a fresh array every render, re-running the effect for\n // nothing whenever no row was focused.\n const currentOptions = useMemo(() => currentRow?.options ?? [], [currentRow]);\n\n // Adjust column when current row's options change externally (e.g. option becomes disabled)\n useEffect(() => {\n if (!currentRow) return;\n\n const maxCol = currentOptions.length - 1;\n if (focusedCol > maxCol) {\n const newCol = Math.max(0, maxCol);\n setFocused(focusedRow, newCol);\n }\n }, [focusedRow, currentOptions, focusedCol, setFocused, currentRow]);\n\n // Store the latest handler in a ref so that the useInput effect never needs to\n // re-register on the event emitter. This avoids a stale-closure race condition\n // where, after a domain switch (CategoryGrid remount via key={activeDomain}),\n // the useInput effect may not yet have re-registered the updated handler when\n // the first keypress arrives — causing the first space press to be silently lost.\n const handlerRef = useRef<((input: string, key: Key) => void) | null>(null);\n handlerRef.current = (input: string, key: Key) => {\n if (key.tab && key.shift) {\n onToggleLabels();\n return;\n }\n\n if (key.tab && !key.shift) {\n const nextSection = findNextIndex(categories, focusedRow);\n if (nextSection !== focusedRow) {\n setFocused(nextSection, 0);\n }\n return;\n }\n\n if (isHotkey(input, HOTKEY_TOGGLE_LABELS)) {\n onToggleLabels();\n return;\n }\n\n if (input === KEY_SPACE) {\n const currentOption = currentOptions[focusedCol];\n if (currentRow && currentOption) {\n onToggle(currentRow.id, currentOption.id);\n }\n return;\n }\n\n const isLeft = key.leftArrow || input === \"h\";\n const isRight = key.rightArrow || input === \"l\";\n const isUp = key.upArrow || input === \"k\";\n const isDown = key.downArrow || input === \"j\";\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\n // Stable handler reference — never changes, so useInput's effect registers once\n const stableHandler = useCallback((input: string, key: Key) => {\n handlerRef.current?.(input, key);\n }, []);\n\n useInput(stableHandler);\n}\n"],"mappings":"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","names":["useCallback","useEffect","useCallback","useEffect"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
MIN_TERMINAL_SIZE
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-G6G2FT2G.js";
|
|
5
5
|
|
|
6
6
|
// src/cli/utils/terminal.ts
|
|
7
7
|
function clearTerminalScreen() {
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
isTerminalLargeEnough,
|
|
21
21
|
formatTerminalTooSmallMessage
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
23
|
+
//# sourceMappingURL=chunk-QNAMXQKF.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
isDomain
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RVXI5VQU.js";
|
|
5
5
|
import {
|
|
6
6
|
findStack
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IGOFZG3S.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/components/wizard/utils.ts
|
|
10
10
|
var DOMAIN_DISPLAY_NAMES = {
|
|
@@ -32,4 +32,4 @@ export {
|
|
|
32
32
|
getDomainDisplayName,
|
|
33
33
|
getStackName
|
|
34
34
|
};
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
35
|
+
//# sourceMappingURL=chunk-QO4XD5V5.js.map
|
|
@@ -4,11 +4,12 @@ import {
|
|
|
4
4
|
} from "./chunk-TSIU7DME.js";
|
|
5
5
|
import {
|
|
6
6
|
CategoryGrid
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PXGDA2SY.js";
|
|
8
8
|
import {
|
|
9
9
|
buildCategoriesForDomain,
|
|
10
|
-
useWizardStore
|
|
11
|
-
|
|
10
|
+
useWizardStore,
|
|
11
|
+
validateBuildStep
|
|
12
|
+
} from "./chunk-RLU2IXD3.js";
|
|
12
13
|
|
|
13
14
|
// src/cli/components/wizard/step-build.tsx
|
|
14
15
|
import { Box, useInput } from "ink";
|
|
@@ -42,6 +43,8 @@ var StepBuild = ({
|
|
|
42
43
|
}) => {
|
|
43
44
|
const { ref: gridRef, measuredHeight: gridHeight } = useMeasuredHeight();
|
|
44
45
|
const skillConfigs = useWizardStore((s) => s.skillConfigs);
|
|
46
|
+
const setToastMessage = useWizardStore((s) => s.setToastMessage);
|
|
47
|
+
const activeDomainSelections = useWizardStore((s) => s.domainSelections[activeDomain]);
|
|
45
48
|
const handleFocusedSkillChange = useCallback(
|
|
46
49
|
(id) => useWizardStore.getState().setFocusedSkillId(id),
|
|
47
50
|
[]
|
|
@@ -63,9 +66,16 @@ var StepBuild = ({
|
|
|
63
66
|
initialCol: focusedCategory.options.findIndex((o) => o.id === skillId)
|
|
64
67
|
};
|
|
65
68
|
}, [categories]);
|
|
69
|
+
const handleContinue = useCallback(() => {
|
|
70
|
+
const validation = validateBuildStep(categories, activeDomainSelections ?? {});
|
|
71
|
+
if (!validation.valid) {
|
|
72
|
+
setToastMessage(validation.message);
|
|
73
|
+
}
|
|
74
|
+
onContinue();
|
|
75
|
+
}, [categories, activeDomainSelections, setToastMessage, onContinue]);
|
|
66
76
|
useInput((_input, key) => {
|
|
67
77
|
if (key.return) {
|
|
68
|
-
|
|
78
|
+
handleContinue();
|
|
69
79
|
} else if (key.escape) {
|
|
70
80
|
onBack();
|
|
71
81
|
}
|
|
@@ -89,4 +99,4 @@ var StepBuild = ({
|
|
|
89
99
|
export {
|
|
90
100
|
StepBuild
|
|
91
101
|
};
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
102
|
+
//# sourceMappingURL=chunk-QXPMQBEI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/step-build.tsx","../src/cli/components/hooks/use-category-rows.ts"],"sourcesContent":["import { Box, useInput } from \"ink\";\nimport React, { useCallback, useMemo } from \"react\";\nimport type { Domain, SkillId, Category } from \"../../types/index.js\";\nimport { useCategoryRows } from \"../hooks/use-category-rows.js\";\nimport { useMeasuredHeight } from \"../hooks/use-measured-height.js\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport { validateBuildStep } from \"../../lib/wizard/index.js\";\nimport { CategoryGrid } from \"./category-grid.js\";\n\nexport type StepBuildProps = {\n domain: Domain;\n selectedDomains: Domain[];\n allSelections: SkillId[];\n showLabels: boolean;\n /** Skill IDs already installed on disk, shown with a dimmed checkmark */\n installedSkillIds?: SkillId[] | undefined;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n onContinue: () => void;\n onBack: () => void;\n};\n\nexport const StepBuild: React.FC<StepBuildProps> = ({\n domain: activeDomain,\n allSelections,\n showLabels,\n installedSkillIds,\n onToggle,\n onToggleLabels,\n onContinue,\n onBack,\n}) => {\n const { ref: gridRef, measuredHeight: gridHeight } = useMeasuredHeight();\n const skillConfigs = useWizardStore((s) => s.skillConfigs);\n const setToastMessage = useWizardStore((s) => s.setToastMessage);\n // A domain nobody has opened yet holds no entry at all, which is the same state as one\n // opened and left empty — both are \"nothing selected here\" and both are what the advisory\n // below is about.\n const activeDomainSelections = useWizardStore((s) => s.domainSelections[activeDomain]);\n\n const handleFocusedSkillChange = useCallback(\n (id: SkillId | null) => useWizardStore.getState().setFocusedSkillId(id),\n [],\n );\n\n const categories = useCategoryRows({\n domain: activeDomain,\n allSelections,\n ...(installedSkillIds !== undefined && { installedSkillIds }),\n skillConfigs,\n });\n\n const { initialRow, initialCol } = useMemo(() => {\n const skillId = useWizardStore.getState().focusedSkillId;\n if (!skillId) return { initialRow: 0, initialCol: 0 };\n const row = categories.findIndex((cat) => cat.options.some((o) => o.id === skillId));\n const focusedCategory = categories[row];\n if (!focusedCategory) return { initialRow: 0, initialCol: 0 };\n return {\n initialRow: row,\n initialCol: focusedCategory.options.findIndex((o) => o.id === skillId),\n };\n }, [categories]);\n\n /**\n * Leaves the domain, naming any required category it leaves empty on the way out.\n *\n * The toast is set BEFORE `onContinue`, and survives it: `WizardLayout` paints the toast\n * outside `renderStep`, so unmounting this grid to move to the next domain — or to the\n * sources step — does not take the message with it.\n */\n const handleContinue = useCallback(() => {\n const validation = validateBuildStep(categories, activeDomainSelections ?? {});\n if (!validation.valid) {\n setToastMessage(validation.message);\n }\n onContinue();\n }, [categories, activeDomainSelections, setToastMessage, onContinue]);\n\n useInput((_input, key) => {\n if (key.return) {\n handleContinue();\n } else if (key.escape) {\n onBack();\n }\n });\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" flexGrow={1} flexBasis={0}>\n <Box ref={gridRef} flexGrow={1} flexBasis={0}>\n <CategoryGrid\n key={activeDomain}\n categories={categories}\n availableHeight={gridHeight}\n showLabels={showLabels}\n defaultFocusedRow={initialRow}\n defaultFocusedCol={initialCol}\n onToggle={onToggle}\n onToggleLabels={onToggleLabels}\n onFocusedSkillChange={handleFocusedSkillChange}\n />\n </Box>\n </Box>\n );\n};\n","import { useMemo } from \"react\";\nimport type { Domain, SkillId } from \"../../types/index.js\";\nimport type { SkillConfig } from \"../../types/config.js\";\nimport { buildCategoriesForDomain } from \"../../lib/wizard/index.js\";\nimport type { CategoryRow } from \"../wizard/category-grid.js\";\n\ntype UseCategoryRowsOptions = {\n domain: Domain;\n allSelections: SkillId[];\n installedSkillIds?: SkillId[];\n skillConfigs?: SkillConfig[];\n};\n\n/** The build-step grid's rows for `domain`, rebuilt only when an input changes. */\nexport function useCategoryRows({\n domain,\n allSelections,\n installedSkillIds,\n skillConfigs,\n}: UseCategoryRowsOptions): CategoryRow[] {\n return useMemo(\n () => buildCategoriesForDomain(domain, allSelections, installedSkillIds, skillConfigs),\n [domain, allSelections, installedSkillIds, skillConfigs],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,KAAK,gBAAgB;AAC9B,SAAgB,aAAa,WAAAA,gBAAe;;;ACD5C,SAAS,eAAe;AAcjB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,SAAO;AAAA,IACL,MAAM,yBAAyB,QAAQ,eAAe,mBAAmB,YAAY;AAAA,IACrF,CAAC,QAAQ,eAAe,mBAAmB,YAAY;AAAA,EACzD;AACF;;;ADkEQ;AApED,IAAM,YAAsC,CAAC;AAAA,EAClD,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,KAAK,SAAS,gBAAgB,WAAW,IAAI,kBAAkB;AACvE,QAAM,eAAe,eAAe,CAAC,MAAM,EAAE,YAAY;AACzD,QAAM,kBAAkB,eAAe,CAAC,MAAM,EAAE,eAAe;AAI/D,QAAM,yBAAyB,eAAe,CAAC,MAAM,EAAE,iBAAiB,YAAY,CAAC;AAErF,QAAM,2BAA2B;AAAA,IAC/B,CAAC,OAAuB,eAAe,SAAS,EAAE,kBAAkB,EAAE;AAAA,IACtE,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,gBAAgB;AAAA,IACjC,QAAQ;AAAA,IACR;AAAA,IACA,GAAI,sBAAsB,UAAa,EAAE,kBAAkB;AAAA,IAC3D;AAAA,EACF,CAAC;AAED,QAAM,EAAE,YAAY,WAAW,IAAIC,SAAQ,MAAM;AAC/C,UAAM,UAAU,eAAe,SAAS,EAAE;AAC1C,QAAI,CAAC,QAAS,QAAO,EAAE,YAAY,GAAG,YAAY,EAAE;AACpD,UAAM,MAAM,WAAW,UAAU,CAAC,QAAQ,IAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,CAAC;AACnF,UAAM,kBAAkB,WAAW,GAAG;AACtC,QAAI,CAAC,gBAAiB,QAAO,EAAE,YAAY,GAAG,YAAY,EAAE;AAC5D,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,YAAY,gBAAgB,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,OAAO;AAAA,IACvE;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AASf,QAAM,iBAAiB,YAAY,MAAM;AACvC,UAAM,aAAa,kBAAkB,YAAY,0BAA0B,CAAC,CAAC;AAC7E,QAAI,CAAC,WAAW,OAAO;AACrB,sBAAgB,WAAW,OAAO;AAAA,IACpC;AACA,eAAW;AAAA,EACb,GAAG,CAAC,YAAY,wBAAwB,iBAAiB,UAAU,CAAC;AAEpE,WAAS,CAAC,QAAQ,QAAQ;AACxB,QAAI,IAAI,QAAQ;AACd,qBAAe;AAAA,IACjB,WAAW,IAAI,QAAQ;AACrB,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,SACE,oBAAC,OAAI,eAAc,UAAS,OAAM,QAAO,UAAU,GAAG,WAAW,GAC/D,8BAAC,OAAI,KAAK,SAAS,UAAU,GAAG,WAAW,GACzC;AAAA,IAAC;AAAA;AAAA,MAEC;AAAA,MACA,iBAAiB;AAAA,MACjB;AAAA,MACA,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB;AAAA,MACA;AAAA,MACA,sBAAsB;AAAA;AAAA,IARjB;AAAA,EASP,GACF,GACF;AAEJ;","names":["useMemo","useMemo"]}
|
|
@@ -2,28 +2,27 @@
|
|
|
2
2
|
import {
|
|
3
3
|
DOMAIN_ORDER,
|
|
4
4
|
deriveInstallMode,
|
|
5
|
+
disableBuffering,
|
|
6
|
+
drainBuffer,
|
|
7
|
+
enableBuffering,
|
|
5
8
|
getAvailableSkills,
|
|
6
9
|
getCellState,
|
|
7
10
|
getUnmetRequiredBy,
|
|
8
11
|
isActiveAt,
|
|
9
12
|
isGlobalTombstone,
|
|
10
13
|
isLocalOnlySkill,
|
|
11
|
-
isProjectOwned
|
|
12
|
-
} from "./chunk-WCAUUBHO.js";
|
|
13
|
-
import {
|
|
14
|
+
isProjectOwned,
|
|
14
15
|
warn
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RVXI5VQU.js";
|
|
16
17
|
import {
|
|
17
18
|
getCategoryDomain,
|
|
18
19
|
getSkillById,
|
|
19
|
-
matrix
|
|
20
|
-
} from "./chunk-RWOYPOMR.js";
|
|
21
|
-
import {
|
|
20
|
+
matrix,
|
|
22
21
|
typedEntries,
|
|
23
22
|
typedFromEntries,
|
|
24
23
|
typedKeys,
|
|
25
24
|
typedValues
|
|
26
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-IGOFZG3S.js";
|
|
27
26
|
import {
|
|
28
27
|
CLI_INVOKE_COMMAND,
|
|
29
28
|
DEFAULT_PUBLIC_SOURCE_NAME,
|
|
@@ -32,7 +31,7 @@ import {
|
|
|
32
31
|
FALLBACK_DOMAIN,
|
|
33
32
|
INSTALL_MODES,
|
|
34
33
|
SKILL_CATEGORIES_PATH
|
|
35
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-G6G2FT2G.js";
|
|
36
35
|
|
|
37
36
|
// src/cli/stores/wizard-store.ts
|
|
38
37
|
import { create } from "zustand";
|
|
@@ -144,6 +143,16 @@ function toRemovedAgentRow(agent) {
|
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
// src/cli/lib/wizard/build-step-logic.ts
|
|
146
|
+
function validateBuildStep(categories, selections) {
|
|
147
|
+
const emptyRequired = categories.find(
|
|
148
|
+
(category) => category.required && !selections[category.id]?.length
|
|
149
|
+
);
|
|
150
|
+
if (!emptyRequired) return { valid: true };
|
|
151
|
+
return {
|
|
152
|
+
valid: false,
|
|
153
|
+
message: `No skills selected in ${emptyRequired.displayName} (required category)`
|
|
154
|
+
};
|
|
155
|
+
}
|
|
147
156
|
function buildCategoriesForDomain(domain, allSelections, installedSkillIds, skillConfigs) {
|
|
148
157
|
const categories = sortBy(
|
|
149
158
|
typedValues(matrix.categories).filter((cat) => cat.domain === domain),
|
|
@@ -309,6 +318,9 @@ var TOAST_MESSAGES = {
|
|
|
309
318
|
ALREADY_EJECTED_AT_GLOBAL: "Already exists as ejected skill at global scope",
|
|
310
319
|
GLOBAL_AGENTS_LOCKED: "Global agents cannot be changed from project scope"
|
|
311
320
|
};
|
|
321
|
+
function skillsLeftOutToast(count) {
|
|
322
|
+
return count === 1 ? "1 skill was left out \u2014 this source cannot place it" : `${count} skills were left out \u2014 this source cannot place them`;
|
|
323
|
+
}
|
|
312
324
|
function resolveEffectiveSource(...candidates) {
|
|
313
325
|
return candidates.find((source) => source !== void 0) ?? DEFAULT_PUBLIC_SOURCE_NAME;
|
|
314
326
|
}
|
|
@@ -409,13 +421,13 @@ function reconcileSkillConfigs(configs, added, removed, installedSkillConfigs, i
|
|
|
409
421
|
return result;
|
|
410
422
|
}
|
|
411
423
|
function agentHasProjectActive(configs, name) {
|
|
412
|
-
return configs.some((ac) => ac.name === name && ac
|
|
424
|
+
return configs.some((ac) => ac.name === name && isActiveAt(ac, "project"));
|
|
413
425
|
}
|
|
414
426
|
function agentHasGlobalActive(configs, name) {
|
|
415
|
-
return configs.some((ac) => ac.name === name && ac
|
|
427
|
+
return configs.some((ac) => ac.name === name && isActiveAt(ac, "global"));
|
|
416
428
|
}
|
|
417
429
|
function agentHasGlobalTombstone(configs, name) {
|
|
418
|
-
return configs.some((ac) => ac.name === name && ac
|
|
430
|
+
return configs.some((ac) => ac.name === name && isGlobalTombstone(ac));
|
|
419
431
|
}
|
|
420
432
|
function isDualScopeAgentPair(configs, name) {
|
|
421
433
|
return agentHasProjectActive(configs, name) && agentHasGlobalTombstone(configs, name);
|
|
@@ -770,7 +782,7 @@ var useWizardStore = create((set, get) => ({
|
|
|
770
782
|
selectedDomains: state.selectedDomains.filter((d) => d !== domain),
|
|
771
783
|
domainSelections: remainingSelections,
|
|
772
784
|
// Global-scope edit: no overlay, so deselecting a domain uninstalls its skills cleanly
|
|
773
|
-
// rather than tombstoning them in the global config
|
|
785
|
+
// rather than tombstoning them in the global config.
|
|
774
786
|
skillConfigs: applySkillRemoval(
|
|
775
787
|
state.skillConfigs,
|
|
776
788
|
removedSkillIds,
|
|
@@ -1075,6 +1087,18 @@ var useWizardStore = create((set, get) => ({
|
|
|
1075
1087
|
return rows;
|
|
1076
1088
|
}
|
|
1077
1089
|
}));
|
|
1090
|
+
function showWarningsAsToast(change) {
|
|
1091
|
+
enableBuffering();
|
|
1092
|
+
try {
|
|
1093
|
+
change();
|
|
1094
|
+
const warnings = drainBuffer();
|
|
1095
|
+
if (warnings.length > 0) {
|
|
1096
|
+
useWizardStore.getState().setToastMessage(skillsLeftOutToast(warnings.length));
|
|
1097
|
+
}
|
|
1098
|
+
} finally {
|
|
1099
|
+
disableBuffering();
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1078
1102
|
function hydrateWizardStore(options) {
|
|
1079
1103
|
useWizardStore.setState(createInitialState());
|
|
1080
1104
|
const { initialStep } = options;
|
|
@@ -1156,6 +1180,7 @@ export {
|
|
|
1156
1180
|
computeScopeDiff,
|
|
1157
1181
|
formatScopeTag,
|
|
1158
1182
|
deriveScopeBadges,
|
|
1183
|
+
validateBuildStep,
|
|
1159
1184
|
buildCategoriesForDomain,
|
|
1160
1185
|
orderDomains,
|
|
1161
1186
|
BUILT_IN_AGENT_GROUPS,
|
|
@@ -1165,6 +1190,7 @@ export {
|
|
|
1165
1190
|
getActiveStepFlow,
|
|
1166
1191
|
createInitialState,
|
|
1167
1192
|
useWizardStore,
|
|
1193
|
+
showWarningsAsToast,
|
|
1168
1194
|
hydrateWizardStore
|
|
1169
1195
|
};
|
|
1170
|
-
//# sourceMappingURL=chunk-
|
|
1196
|
+
//# sourceMappingURL=chunk-RLU2IXD3.js.map
|