@agents-inc/cli 0.50.0 → 0.60.1
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 +155 -5
- package/dist/{chunk-YDYRAXSY.js → chunk-52M2XF3W.js} +6 -6
- package/dist/{chunk-2BWCR762.js → chunk-52XO4ULK.js} +6 -8
- package/dist/chunk-52XO4ULK.js.map +1 -0
- package/dist/{chunk-KQOU4POU.js → chunk-6G3KZSO4.js} +72 -51
- package/dist/chunk-6G3KZSO4.js.map +1 -0
- package/dist/{chunk-AWP5A6IM.js → chunk-6OWHQ7HM.js} +14 -12
- package/dist/chunk-6OWHQ7HM.js.map +1 -0
- package/dist/{chunk-D72AFYQR.js → chunk-7FMEMXJ4.js} +71 -71
- package/dist/chunk-7FMEMXJ4.js.map +1 -0
- package/dist/{chunk-RA2IPRO2.js → chunk-AJJJE7F7.js} +2 -2
- package/dist/{chunk-4R52TQ3K.js → chunk-AX3SZZWA.js} +2 -2
- package/dist/{chunk-U2W5SENM.js → chunk-BFD5NZQ4.js} +5 -4
- package/dist/chunk-BFD5NZQ4.js.map +1 -0
- package/dist/{chunk-HYEUETIC.js → chunk-BKJHAJQW.js} +2 -2
- package/dist/{chunk-HYEUETIC.js.map → chunk-BKJHAJQW.js.map} +1 -1
- package/dist/{chunk-DCE423KO.js → chunk-BMJZBLP7.js} +5 -5
- package/dist/{chunk-GBOW6FUW.js → chunk-BNQ5O6LE.js} +2 -2
- package/dist/{chunk-KAO3LKB5.js → chunk-C577AJE7.js} +3 -3
- package/dist/{chunk-C3Q43WLC.js → chunk-CIG7IKX3.js} +4 -4
- package/dist/chunk-EC3UJRKZ.js +1534 -0
- package/dist/chunk-EC3UJRKZ.js.map +1 -0
- package/dist/{chunk-I6IOGZSZ.js → chunk-EMIUPGPL.js} +11 -15
- package/dist/chunk-EMIUPGPL.js.map +1 -0
- package/dist/{chunk-4QWDB2MD.js → chunk-G6WHCALR.js} +127 -105
- package/dist/chunk-G6WHCALR.js.map +1 -0
- package/dist/{chunk-JFF7P4LC.js → chunk-H7WJK7NJ.js} +22 -6
- package/dist/chunk-H7WJK7NJ.js.map +1 -0
- package/dist/chunk-HGTC76BX.js +16 -0
- package/dist/chunk-HGTC76BX.js.map +1 -0
- package/dist/{chunk-RDWGYKDY.js → chunk-K6OLORQL.js} +6 -6
- package/dist/{chunk-XDSVV5GZ.js → chunk-KIWFEBKH.js} +41 -11
- package/dist/chunk-KIWFEBKH.js.map +1 -0
- package/dist/{chunk-WBHPCBVN.js → chunk-LWXRUR6B.js} +66 -94
- package/dist/chunk-LWXRUR6B.js.map +1 -0
- package/dist/{chunk-CMNKHDOX.js → chunk-MGNYPVOJ.js} +2 -2
- package/dist/{chunk-5FPIKTSA.js → chunk-MKCHLXMY.js} +7 -7
- package/dist/{chunk-U7X4V4HE.js → chunk-MMFQNJPE.js} +2 -2
- package/dist/{chunk-WLZHCM7O.js → chunk-MR6OBL3B.js} +3 -11
- package/dist/{chunk-WLZHCM7O.js.map → chunk-MR6OBL3B.js.map} +1 -1
- package/dist/{chunk-RFKDGJAJ.js → chunk-O6BA7Q2B.js} +6 -6
- package/dist/chunk-O6BA7Q2B.js.map +1 -0
- package/dist/chunk-OCEFD7V6.js +201 -0
- package/dist/chunk-OCEFD7V6.js.map +1 -0
- package/dist/{chunk-YZTWZVGX.js → chunk-PUT7X3GA.js} +1 -1
- package/dist/chunk-PUT7X3GA.js.map +1 -0
- package/dist/{chunk-WFFV254H.js → chunk-RO6LX3UV.js} +110 -82
- package/dist/chunk-RO6LX3UV.js.map +1 -0
- package/dist/{chunk-QYLCINGC.js → chunk-SDKCQXWE.js} +2 -2
- package/dist/{chunk-M3GQ2R3E.js → chunk-SEJF7CGJ.js} +19 -7
- package/dist/chunk-SEJF7CGJ.js.map +1 -0
- package/dist/{chunk-SPFHPHYL.js → chunk-SZRK3VOR.js} +24 -14
- package/dist/chunk-SZRK3VOR.js.map +1 -0
- package/dist/{chunk-QB5HHTAA.js → chunk-TC3NHO34.js} +28 -12
- package/dist/chunk-TC3NHO34.js.map +1 -0
- package/dist/{chunk-5L724R4C.js → chunk-TGLRDEEL.js} +8 -13
- package/dist/chunk-TGLRDEEL.js.map +1 -0
- package/dist/{chunk-HMSHB5EQ.js → chunk-TZXYBG3R.js} +3544 -3037
- package/dist/chunk-TZXYBG3R.js.map +1 -0
- package/dist/{chunk-PGY5XROM.js → chunk-VR3CDXDT.js} +2 -6
- package/dist/chunk-VR3CDXDT.js.map +1 -0
- package/dist/{chunk-5FCHJLM7.js → chunk-WF6RM73R.js} +252 -38
- package/dist/chunk-WF6RM73R.js.map +1 -0
- package/dist/{chunk-3VOL4WEG.js → chunk-WYVDNGJB.js} +3 -3
- package/dist/{chunk-WJHFV6RI.js → chunk-X5EG4EFP.js} +2 -2
- package/dist/{chunk-JWYRXE6C.js → chunk-XUDTFI4M.js} +2 -2
- package/dist/{chunk-7LV4V6A4.js → chunk-YHCYKUA3.js} +14 -10
- package/dist/chunk-YHCYKUA3.js.map +1 -0
- package/dist/commands/build/marketplace.js +4 -4
- package/dist/commands/build/plugins.js +9 -7
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +13 -10
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +42 -71
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/index.js +7 -5
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +8 -6
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/show.js +7 -5
- package/dist/commands/diff.js +9 -7
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +20 -16
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +175 -79
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +20 -41
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +10 -18
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +21 -20
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +32 -31
- package/dist/commands/list.js +8 -6
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +23 -11
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +63 -46
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +11 -9
- package/dist/commands/outdated.js +9 -7
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +45 -35
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +93 -123
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +11 -9
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +23 -27
- package/dist/commands/validate.js.map +1 -1
- package/dist/components/common/confirm.test.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 +4 -4
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +5 -5
- package/dist/components/wizard/checkbox-grid.test.js +6 -6
- package/dist/components/wizard/domain-selection.js +12 -11
- package/dist/components/wizard/help-modal.js +2 -2
- package/dist/components/wizard/menu-item.js +1 -1
- package/dist/components/wizard/search-modal.js +2 -2
- package/dist/components/wizard/search-modal.test.js +3 -3
- package/dist/components/wizard/search-modal.test.js.map +1 -1
- package/dist/components/wizard/section-progress.js +2 -2
- package/dist/components/wizard/section-progress.test.js +4 -4
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/selection-card.js +2 -2
- package/dist/components/wizard/source-grid.js +4 -4
- package/dist/components/wizard/source-grid.test.js +5 -5
- package/dist/components/wizard/source-grid.test.js.map +1 -1
- package/dist/components/wizard/stack-selection.js +9 -8
- package/dist/components/wizard/step-agents.js +11 -10
- package/dist/components/wizard/step-agents.test.js +13 -12
- package/dist/components/wizard/step-agents.test.js.map +1 -1
- package/dist/components/wizard/step-build.js +11 -9
- package/dist/components/wizard/step-build.test.js +18 -22
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +4 -4
- package/dist/components/wizard/step-confirm.test.js +83 -23
- 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 +3 -3
- package/dist/components/wizard/step-settings.js +9 -7
- package/dist/components/wizard/step-settings.test.js +13 -11
- package/dist/components/wizard/step-settings.test.js.map +1 -1
- package/dist/components/wizard/step-sources.js +13 -11
- package/dist/components/wizard/step-sources.test.js +19 -17
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +15 -14
- package/dist/components/wizard/step-stack.test.js +17 -16
- 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 +10 -8
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard-tabs.test.js +2 -2
- package/dist/components/wizard/wizard.js +29 -27
- package/dist/config-exports.js +20 -0
- package/dist/config-exports.js.map +1 -0
- package/dist/hooks/init.js +34 -33
- package/dist/hooks/init.js.map +1 -1
- package/dist/loader-2O32KKAQ.js +19 -0
- package/dist/source-loader-A6B3NDI4.js +16 -0
- package/dist/source-loader-A6B3NDI4.js.map +1 -0
- package/dist/source-manager-Q7IQSGIX.js +18 -0
- package/dist/source-manager-Q7IQSGIX.js.map +1 -0
- package/dist/src/agents/meta/agent-summoner/workflow.md +3 -3
- package/dist/src/agents/meta/skill-summoner/critical-reminders.md +2 -2
- package/dist/src/agents/meta/skill-summoner/critical-requirements.md +1 -1
- package/dist/src/agents/meta/skill-summoner/intro.md +1 -1
- package/dist/src/agents/meta/skill-summoner/output-format.md +3 -3
- package/dist/src/agents/meta/skill-summoner/workflow.md +8 -8
- package/dist/stores/wizard-store.js +6 -5
- package/dist/stores/wizard-store.test.js +299 -59
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +5 -1
- package/src/agents/meta/agent-summoner/workflow.md +3 -3
- package/src/agents/meta/skill-summoner/critical-reminders.md +2 -2
- package/src/agents/meta/skill-summoner/critical-requirements.md +1 -1
- package/src/agents/meta/skill-summoner/intro.md +1 -1
- package/src/agents/meta/skill-summoner/output-format.md +3 -3
- package/src/agents/meta/skill-summoner/workflow.md +8 -8
- package/src/schemas/metadata.schema.json +6 -0
- package/src/schemas/stacks.schema.json +1 -1
- package/config/skill-categories.yaml +0 -344
- package/config/skill-rules.yaml +0 -740
- package/config/stacks.yaml +0 -1864
- package/dist/chunk-26MXZUHU.js +0 -183
- package/dist/chunk-26MXZUHU.js.map +0 -1
- package/dist/chunk-2BWCR762.js.map +0 -1
- package/dist/chunk-4QWDB2MD.js.map +0 -1
- package/dist/chunk-5FCHJLM7.js.map +0 -1
- package/dist/chunk-5L724R4C.js.map +0 -1
- package/dist/chunk-7LV4V6A4.js.map +0 -1
- package/dist/chunk-AWP5A6IM.js.map +0 -1
- package/dist/chunk-D72AFYQR.js.map +0 -1
- package/dist/chunk-HMSHB5EQ.js.map +0 -1
- package/dist/chunk-I6IOGZSZ.js.map +0 -1
- package/dist/chunk-JFF7P4LC.js.map +0 -1
- package/dist/chunk-KQOU4POU.js.map +0 -1
- package/dist/chunk-M3GQ2R3E.js.map +0 -1
- package/dist/chunk-PGY5XROM.js.map +0 -1
- package/dist/chunk-QB5HHTAA.js.map +0 -1
- package/dist/chunk-RFKDGJAJ.js.map +0 -1
- package/dist/chunk-SPFHPHYL.js.map +0 -1
- package/dist/chunk-U2W5SENM.js.map +0 -1
- package/dist/chunk-UAD3SC27.js +0 -107
- package/dist/chunk-UAD3SC27.js.map +0 -1
- package/dist/chunk-WBHPCBVN.js.map +0 -1
- package/dist/chunk-WFFV254H.js.map +0 -1
- package/dist/chunk-XDSVV5GZ.js.map +0 -1
- package/dist/chunk-YZTWZVGX.js.map +0 -1
- package/dist/commands/config/get.js +0 -61
- package/dist/commands/config/get.js.map +0 -1
- package/dist/commands/config/set-project.js +0 -61
- package/dist/commands/config/set-project.js.map +0 -1
- package/dist/commands/config/unset-project.js +0 -57
- package/dist/commands/config/unset-project.js.map +0 -1
- package/dist/config/skill-categories.yaml +0 -344
- package/dist/config/skill-rules.yaml +0 -740
- package/dist/config/stacks.yaml +0 -1864
- package/dist/source-manager-BVB2SG73.js +0 -16
- /package/dist/{chunk-YDYRAXSY.js.map → chunk-52M2XF3W.js.map} +0 -0
- /package/dist/{chunk-RA2IPRO2.js.map → chunk-AJJJE7F7.js.map} +0 -0
- /package/dist/{chunk-4R52TQ3K.js.map → chunk-AX3SZZWA.js.map} +0 -0
- /package/dist/{chunk-DCE423KO.js.map → chunk-BMJZBLP7.js.map} +0 -0
- /package/dist/{chunk-GBOW6FUW.js.map → chunk-BNQ5O6LE.js.map} +0 -0
- /package/dist/{chunk-KAO3LKB5.js.map → chunk-C577AJE7.js.map} +0 -0
- /package/dist/{chunk-C3Q43WLC.js.map → chunk-CIG7IKX3.js.map} +0 -0
- /package/dist/{chunk-RDWGYKDY.js.map → chunk-K6OLORQL.js.map} +0 -0
- /package/dist/{chunk-CMNKHDOX.js.map → chunk-MGNYPVOJ.js.map} +0 -0
- /package/dist/{chunk-5FPIKTSA.js.map → chunk-MKCHLXMY.js.map} +0 -0
- /package/dist/{chunk-U7X4V4HE.js.map → chunk-MMFQNJPE.js.map} +0 -0
- /package/dist/{chunk-QYLCINGC.js.map → chunk-SDKCQXWE.js.map} +0 -0
- /package/dist/{chunk-3VOL4WEG.js.map → chunk-WYVDNGJB.js.map} +0 -0
- /package/dist/{chunk-WJHFV6RI.js.map → chunk-X5EG4EFP.js.map} +0 -0
- /package/dist/{chunk-JWYRXE6C.js.map → chunk-XUDTFI4M.js.map} +0 -0
- /package/dist/{source-manager-BVB2SG73.js.map → loader-2O32KKAQ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/consts.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport type { Domain, SkillId } from \"./types/index.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// After tsup build, dist/ is flat, so we go up one level from dist/ to get CLI root\n// In development (src/cli/consts.ts), we go up two levels\nconst isInDist = __dirname.includes(\"/dist\");\nconst CLI_ROOT = isInDist ? path.resolve(__dirname, \"..\") : path.resolve(__dirname, \"../..\");\nexport const PROJECT_ROOT = CLI_ROOT;\n\nexport const CLAUDE_DIR = \".claude\";\nexport const CLAUDE_SRC_DIR = \".claude-src\";\nexport const PLUGINS_SUBDIR = \"plugins\";\nexport const PLUGIN_MANIFEST_DIR = \".claude-plugin\";\nexport const PLUGIN_MANIFEST_FILE = \"plugin.json\";\nexport const DEFAULT_PLUGIN_NAME = \"agents-inc\";\n\n/** Home directory used as the root for global installations */\nexport const GLOBAL_INSTALL_ROOT = os.homedir();\n\nexport const CACHE_DIR = path.join(os.homedir(), \".cache\", DEFAULT_PLUGIN_NAME);\n\nexport const CLI_BIN_NAME = \"agentsinc\";\n\nexport const SKILL_CATEGORIES_PATH = \"config/skill-categories.ts\";\nexport const SKILL_RULES_PATH = \"config/skill-rules.ts\";\nexport const STACKS_FILE_PATH = \"config/stacks.ts\";\nexport const SKILLS_DIR_PATH = \"src/skills\";\nexport const LOCAL_SKILLS_PATH = \".claude/skills\";\n\nexport const DIRS = {\n agents: \"src/agents\",\n skills: \"src/skills\",\n stacks: \"src/stacks\",\n templates: \"src/agents/_templates\",\n commands: \"src/commands\",\n} as const;\n\nexport const STANDARD_FILES = {\n SKILL_MD: \"SKILL.md\",\n METADATA_YAML: \"metadata.yaml\",\n METADATA_JSON: \"metadata.json\",\n CONFIG_YAML: \"config.yaml\",\n SKILL_CATEGORIES_TS: \"skill-categories.ts\",\n SKILL_RULES_TS: \"skill-rules.ts\",\n AGENT_METADATA_YAML: \"metadata.yaml\",\n PLUGIN_JSON: \"plugin.json\",\n CONFIG_TS: \"config.ts\",\n CONFIG_TYPES_TS: \"config-types.ts\",\n CLAUDE_MD: \"CLAUDE.md\",\n REFERENCE_MD: \"reference.md\",\n INTRO_MD: \"intro.md\",\n WORKFLOW_MD: \"workflow.md\",\n EXAMPLES_MD: \"examples.md\",\n OUTPUT_FORMAT_MD: \"output-format.md\",\n CRITICAL_REQUIREMENTS_MD: \"critical-requirements.md\",\n CRITICAL_REMINDERS_MD: \"critical-reminders.md\",\n} as const;\n\nexport const STANDARD_DIRS = {\n EXAMPLES: \"examples\",\n SCRIPTS: \"scripts\",\n SKILLS: \"skills\",\n} as const;\n\nexport const DEFAULT_VERSION = \"1.0.0\";\n\n// \"0.0.0\" indicates no version was explicitly set\nexport const DEFAULT_DISPLAY_VERSION = \"0.0.0\";\n\n// JSON Schema URLs for yaml-language-server $schema comments.\n// Uses raw.githubusercontent.com so schemas resolve without requiring the CLI as a dependency.\nconst SCHEMA_PKG_PREFIX = \"https://raw.githubusercontent.com/agents-inc/cli/main/src/schemas\";\n\nexport const SCHEMA_PATHS = {\n agent: `${SCHEMA_PKG_PREFIX}/agent.schema.json`,\n metadata: `${SCHEMA_PKG_PREFIX}/metadata.schema.json`,\n marketplace: `${SCHEMA_PKG_PREFIX}/marketplace.schema.json`,\n projectConfig: `${SCHEMA_PKG_PREFIX}/project-config.schema.json`,\n projectSourceConfig: `${SCHEMA_PKG_PREFIX}/project-source-config.schema.json`,\n stacks: `${SCHEMA_PKG_PREFIX}/stacks.schema.json`,\n} as const;\n\n/** Generates a yaml-language-server schema comment for the top of YAML files. */\nexport function yamlSchemaComment(schemaPath: string): string {\n return `# yaml-language-server: $schema=${schemaPath}`;\n}\n\nexport const YAML_FORMATTING = {\n INDENT: 2,\n LINE_WIDTH: 120,\n /** lineWidth: 0 disables wrapping — used for metadata files */\n LINE_WIDTH_NONE: 0,\n} as const;\n\nexport const UI_SYMBOLS = {\n CHECKBOX_CHECKED: \"[x]\",\n CHECKBOX_UNCHECKED: \"[ ]\",\n CHEVRON: \"\\u276F\",\n CHEVRON_SPACER: \" \",\n SELECTED: \"\\u2713\",\n UNSELECTED: \"\\u25CB\",\n CURRENT: \"\\u25CF\",\n SKIPPED: \"\\u2013\",\n DISCOURAGED: \"!\",\n DISABLED: \"\\u2013\",\n SCROLL_UP: \"\\u25B2\",\n SCROLL_DOWN: \"\\u25BC\",\n} as const;\n\nexport const UI_LAYOUT = {\n MAX_VISIBLE_RESULTS: 10,\n DESCRIPTION_WIDTH: 30,\n COPIED_MESSAGE_TIMEOUT_MS: 2000,\n FALLBACK_MESSAGE_TIMEOUT_MS: 3000,\n} as const;\n\nexport const GITHUB_SOURCE = {\n HTTPS_PREFIX: \"https://github.com/\",\n GITHUB_PREFIX: \"github:\",\n GH_PREFIX: \"gh:\",\n} as const;\n\nexport const DEFAULT_SKILLS_SUBDIR = \"skills\";\n\n/** Strict kebab-case: starts with letter, segments separated by single hyphens, no trailing hyphens */\nexport const KEBAB_CASE_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;\n\nexport const HASH_PREFIX_LENGTH = 7;\n\n/** Hex chars from SHA-256 hash used in cache directory names (64 bits of collision resistance) */\nexport const CACHE_HASH_LENGTH = 16;\n\n/** Max chars of human-readable prefix in cache directory names (for debugging) */\nexport const CACHE_READABLE_PREFIX_LENGTH = 32;\n\n// File size limits for parsing boundaries (DoS prevention)\nconst ONE_MB = 1024 * 1024;\nexport const MAX_MARKETPLACE_FILE_SIZE = 10 * ONE_MB;\nexport const MAX_PLUGIN_FILE_SIZE = ONE_MB;\nexport const MAX_CONFIG_FILE_SIZE = ONE_MB;\n\nexport const MAX_JSON_NESTING_DEPTH = 10;\nexport const MAX_MARKETPLACE_PLUGINS = 10_000;\n\nexport const SCROLL_VIEWPORT = {\n /** Height of the \"N more above\" scroll indicator */\n SCROLL_INDICATOR_HEIGHT: 1,\n /** Estimated lines per category name row (including top margin) */\n CATEGORY_NAME_LINES: 2,\n /** Margin between category sections (marginTop on CategorySection) */\n CATEGORY_MARGIN_LINES: 1,\n /** Minimum rows to show at least 1 category before enabling scroll */\n MIN_VIEWPORT_ROWS: 5,\n /** Minimum terminal height to show the wizard at all */\n MIN_TERMINAL_HEIGHT: 15,\n} as const;\n\nexport const DEFAULT_BRANDING = {\n NAME: \"Agents Inc.\",\n TAGLINE: \"AI-powered development tools\",\n} as const;\n\n/** Fallback name for the default public marketplace when marketplace.json is unavailable */\nexport const DEFAULT_PUBLIC_SOURCE_NAME = \"agents-inc\";\n\n/** Human-readable labels for skill source types shown in the wizard and edit command */\nexport const SOURCE_DISPLAY_NAMES: Record<string, string> = {\n public: \"Public\",\n local: \"Local\",\n \"agents-inc\": \"Agents Inc\",\n};\n\nexport const CLI_COLORS = {\n PRIMARY: \"cyan\",\n SUCCESS: \"green\",\n ERROR: \"red\",\n WARNING: \"yellow\",\n INFO: \"blue\",\n NEUTRAL: \"gray\",\n FOCUS: \"cyan\",\n UNFOCUSED: \"white\",\n WHITE: \"white\",\n} as const;\n\n/** Canonical display order for built-in domains. Custom domains appear before these, alphabetically. */\nexport const BUILT_IN_DOMAIN_ORDER: readonly Domain[] = [\"web\", \"api\", \"mobile\", \"cli\", \"shared\"];\n\n/** Default domains pre-selected when \"Start from scratch\" is chosen (all except CLI) */\nexport const DEFAULT_SCRATCH_DOMAINS: readonly Domain[] = [\"web\", \"api\", \"mobile\"];\n\nexport const ASCII_LOGO = ` █████╗ ██████╗ ███████╗███╗ ██╗████████╗███████╗ ██╗███╗ ██╗ ██████╗\n██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝██╔════╝ ██║████╗ ██║██╔════╝\n███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ███████╗ ██║██╔██╗ ██║██║\n██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║ ██║██║╚██╗██║██║\n██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████║ ██║██║ ╚████║╚██████╗\n╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝`;\n\nexport const DEFAULT_PRESELECTED_SKILLS: readonly SkillId[] = [\n \"meta-methodology-anti-over-engineering\",\n \"meta-methodology-context-management\",\n \"meta-methodology-improvement-protocol\",\n \"meta-methodology-investigation-requirements\",\n \"meta-methodology-success-criteria\",\n \"meta-methodology-write-verification\",\n];\n"],"mappings":"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","names":[]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-T4EXUIBY.js";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_BRANDING
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
8
8
|
import {
|
|
9
9
|
init_esm_shims
|
|
10
10
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -18,9 +18,11 @@ import path from "path";
|
|
|
18
18
|
import { fileURLToPath } from "url";
|
|
19
19
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
20
20
|
import { run } from "@oclif/core";
|
|
21
|
+
import { createJiti } from "jiti";
|
|
21
22
|
var __filename = fileURLToPath(import.meta.url);
|
|
22
23
|
var __dirname = path.dirname(__filename);
|
|
23
24
|
var CLI_ROOT = path.resolve(__dirname, "../../../..");
|
|
25
|
+
var CONFIG_EXPORTS_PATH = path.resolve(__dirname, "../../config-exports.ts");
|
|
24
26
|
var OUTPUT_STRINGS = {
|
|
25
27
|
CONFIG_HEADER: `${DEFAULT_BRANDING.NAME} Configuration`,
|
|
26
28
|
CONFIG_PATHS_HEADER: "Configuration File Paths",
|
|
@@ -53,15 +55,27 @@ var OUTPUT_STRINGS = {
|
|
|
53
55
|
ERROR_UNKNOWN_FLAG: "unknown flag",
|
|
54
56
|
ERROR_PARSE: "parse"
|
|
55
57
|
};
|
|
58
|
+
function buildSkillConfigs(skillIds, overrides) {
|
|
59
|
+
return skillIds.map((id) => ({
|
|
60
|
+
id,
|
|
61
|
+
scope: overrides?.scope ?? "project",
|
|
62
|
+
source: overrides?.source ?? "local"
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
56
65
|
function createMockSkill(id, category, overrides) {
|
|
66
|
+
const segments = id.split("-");
|
|
67
|
+
const defaultSlug = segments.length >= 3 ? segments.slice(2).join("-") : id;
|
|
68
|
+
const defaultDisplayName = defaultSlug.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
57
69
|
return {
|
|
58
70
|
id,
|
|
71
|
+
slug: defaultSlug,
|
|
72
|
+
displayName: defaultDisplayName,
|
|
59
73
|
description: `${id} skill`,
|
|
60
74
|
category,
|
|
61
75
|
tags: [],
|
|
62
76
|
author: "@test",
|
|
63
77
|
conflictsWith: [],
|
|
64
|
-
|
|
78
|
+
isRecommended: false,
|
|
65
79
|
requires: [],
|
|
66
80
|
alternatives: [],
|
|
67
81
|
discourages: [],
|
|
@@ -73,12 +87,12 @@ function createMockSkill(id, category, overrides) {
|
|
|
73
87
|
};
|
|
74
88
|
}
|
|
75
89
|
function createMockMatrix(skills, overrides) {
|
|
76
|
-
const
|
|
77
|
-
const
|
|
90
|
+
const autoSlugToId = {};
|
|
91
|
+
const autoIdToSlug = {};
|
|
78
92
|
for (const [id, skill] of typedEntries(skills)) {
|
|
79
|
-
if (skill.
|
|
80
|
-
|
|
81
|
-
|
|
93
|
+
if (skill.slug) {
|
|
94
|
+
autoSlugToId[skill.slug] = id;
|
|
95
|
+
autoIdToSlug[id] = skill.slug;
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
return {
|
|
@@ -86,8 +100,7 @@ function createMockMatrix(skills, overrides) {
|
|
|
86
100
|
categories: {},
|
|
87
101
|
skills,
|
|
88
102
|
suggestedStacks: [],
|
|
89
|
-
|
|
90
|
-
displayNames: autoDisplayNames,
|
|
103
|
+
slugMap: { slugToId: autoSlugToId, idToSlug: autoIdToSlug },
|
|
91
104
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
92
105
|
...overrides
|
|
93
106
|
};
|
|
@@ -118,72 +131,49 @@ function createMockResolvedStack(id, name, overrides) {
|
|
|
118
131
|
|
|
119
132
|
// src/cli/lib/__tests__/test-fixtures.ts
|
|
120
133
|
var SKILL_FIXTURES = {
|
|
121
|
-
react: {
|
|
122
|
-
id: "web-framework-react",
|
|
123
|
-
category: "web-framework",
|
|
124
|
-
displayName: "react",
|
|
134
|
+
react: createMockSkill("web-framework-react", "web-framework", {
|
|
125
135
|
description: "React framework for building user interfaces",
|
|
126
136
|
tags: ["react", "web", "ui", "component"]
|
|
127
|
-
},
|
|
128
|
-
zustand: {
|
|
129
|
-
id: "web-state-zustand",
|
|
130
|
-
category: "web-client-state",
|
|
131
|
-
displayName: "zustand",
|
|
137
|
+
}),
|
|
138
|
+
zustand: createMockSkill("web-state-zustand", "web-client-state", {
|
|
132
139
|
description: "Bear necessities state management",
|
|
133
140
|
tags: ["state", "react", "zustand"]
|
|
134
|
-
},
|
|
135
|
-
hono: {
|
|
136
|
-
id: "api-framework-hono",
|
|
137
|
-
category: "api-api",
|
|
138
|
-
displayName: "hono",
|
|
141
|
+
}),
|
|
142
|
+
hono: createMockSkill("api-framework-hono", "api-api", {
|
|
139
143
|
description: "Lightweight web framework for the edge",
|
|
140
144
|
tags: ["api", "api", "edge", "serverless"]
|
|
141
|
-
},
|
|
142
|
-
vitest: {
|
|
143
|
-
id: "web-testing-vitest",
|
|
144
|
-
category: "web-testing",
|
|
145
|
-
displayName: "vitest",
|
|
145
|
+
}),
|
|
146
|
+
vitest: createMockSkill("web-testing-vitest", "web-testing", {
|
|
146
147
|
description: "Next generation testing framework",
|
|
147
148
|
tags: ["testing", "vitest", "unit"]
|
|
148
|
-
},
|
|
149
|
-
vue: {
|
|
150
|
-
id: "web-framework-vue",
|
|
151
|
-
category: "web-framework",
|
|
152
|
-
displayName: "vue",
|
|
149
|
+
}),
|
|
150
|
+
vue: createMockSkill("web-framework-vue", "web-framework", {
|
|
153
151
|
description: "Progressive JavaScript framework",
|
|
154
152
|
tags: ["vue", "web", "reactive"]
|
|
155
|
-
},
|
|
156
|
-
"auth-patterns": {
|
|
157
|
-
id: "api-security-auth-patterns",
|
|
158
|
-
category: "api-security",
|
|
153
|
+
}),
|
|
154
|
+
"auth-patterns": createMockSkill("api-security-auth-patterns", "api-security", {
|
|
159
155
|
description: "Authentication and authorization patterns",
|
|
160
156
|
tags: ["auth", "security", "jwt", "oauth"]
|
|
161
|
-
},
|
|
162
|
-
drizzle: {
|
|
163
|
-
id: "api-database-drizzle",
|
|
164
|
-
category: "api-database",
|
|
165
|
-
displayName: "drizzle",
|
|
157
|
+
}),
|
|
158
|
+
drizzle: createMockSkill("api-database-drizzle", "api-database", {
|
|
166
159
|
description: "TypeScript ORM for SQL databases",
|
|
167
160
|
tags: ["database", "orm", "sql"]
|
|
168
|
-
},
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
displayName: "scss-modules",
|
|
161
|
+
}),
|
|
162
|
+
"anti-over-engineering": createMockSkill(
|
|
163
|
+
"meta-methodology-anti-over-engineering",
|
|
164
|
+
"shared-methodology",
|
|
165
|
+
{
|
|
166
|
+
description: "Surgical implementation, not architectural innovation",
|
|
167
|
+
tags: ["methodology", "foundational"]
|
|
168
|
+
}
|
|
169
|
+
),
|
|
170
|
+
"scss-modules": createMockSkill("web-styling-scss-modules", "web-styling", {
|
|
179
171
|
description: "CSS Modules with SCSS",
|
|
180
172
|
tags: ["css", "scss", "modules"]
|
|
181
|
-
}
|
|
173
|
+
})
|
|
182
174
|
};
|
|
183
175
|
function getTestSkill(name, overrides) {
|
|
184
|
-
|
|
185
|
-
const { id, category, ...defaults } = config;
|
|
186
|
-
return createMockSkill(id, category, { ...defaults, ...overrides });
|
|
176
|
+
return { ...SKILL_FIXTURES[name], ...overrides };
|
|
187
177
|
}
|
|
188
178
|
var TEST_SKILLS = {
|
|
189
179
|
react: createMockSkill("web-framework-react", "web-framework"),
|
|
@@ -196,35 +186,43 @@ var TEST_SKILLS = {
|
|
|
196
186
|
}),
|
|
197
187
|
hono: createMockSkill("api-framework-hono", "api-api"),
|
|
198
188
|
vitest: createMockSkill("web-testing-vitest", "web-testing"),
|
|
199
|
-
|
|
189
|
+
"scss-modules": createMockSkill("web-styling-scss-modules", "web-styling"),
|
|
200
190
|
drizzle: createMockSkill("api-database-drizzle", "api-database"),
|
|
201
191
|
// Methodology skills (DEFAULT_PRESELECTED_SKILLS) — used by createComprehensiveMatrix
|
|
202
|
-
|
|
192
|
+
"investigation-requirements": createMockSkill(
|
|
203
193
|
"meta-methodology-investigation-requirements",
|
|
204
194
|
"shared-methodology",
|
|
205
195
|
{ description: "Never speculate - read actual code first" }
|
|
206
196
|
),
|
|
207
|
-
|
|
197
|
+
"anti-over-engineering": createMockSkill(
|
|
208
198
|
"meta-methodology-anti-over-engineering",
|
|
209
199
|
"shared-methodology",
|
|
210
200
|
{
|
|
211
201
|
description: "Surgical implementation, not architectural innovation"
|
|
212
202
|
}
|
|
213
203
|
),
|
|
214
|
-
|
|
204
|
+
"success-criteria": createMockSkill("meta-methodology-success-criteria", "shared-methodology", {
|
|
215
205
|
description: "Explicit, measurable criteria defining done"
|
|
216
206
|
}),
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
207
|
+
"write-verification": createMockSkill(
|
|
208
|
+
"meta-methodology-write-verification",
|
|
209
|
+
"shared-methodology",
|
|
210
|
+
{
|
|
211
|
+
description: "Verify work was actually saved"
|
|
212
|
+
}
|
|
213
|
+
),
|
|
214
|
+
"improvement-protocol": createMockSkill(
|
|
221
215
|
"meta-methodology-improvement-protocol",
|
|
222
216
|
"shared-methodology",
|
|
223
217
|
{ description: "Evidence-based self-improvement" }
|
|
224
218
|
),
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
219
|
+
"context-management": createMockSkill(
|
|
220
|
+
"meta-methodology-context-management",
|
|
221
|
+
"shared-methodology",
|
|
222
|
+
{
|
|
223
|
+
description: "Maintain project continuity across sessions"
|
|
224
|
+
}
|
|
225
|
+
)
|
|
228
226
|
};
|
|
229
227
|
var TEST_CATEGORIES = {
|
|
230
228
|
framework: createMockCategory("web-framework", "Framework"),
|
|
@@ -251,11 +249,11 @@ var TEST_MATRICES = {
|
|
|
251
249
|
}),
|
|
252
250
|
reactAndScss: createMockMatrix({
|
|
253
251
|
"web-framework-react": TEST_SKILLS.react,
|
|
254
|
-
"web-styling-scss-modules": TEST_SKILLS
|
|
252
|
+
"web-styling-scss-modules": TEST_SKILLS["scss-modules"]
|
|
255
253
|
}),
|
|
256
254
|
reactScssAndHono: createMockMatrix({
|
|
257
255
|
"web-framework-react": TEST_SKILLS.react,
|
|
258
|
-
"web-styling-scss-modules": TEST_SKILLS
|
|
256
|
+
"web-styling-scss-modules": TEST_SKILLS["scss-modules"],
|
|
259
257
|
"api-framework-hono": TEST_SKILLS.hono
|
|
260
258
|
}),
|
|
261
259
|
reactZustandAndHono: createMockMatrix({
|
|
@@ -268,10 +266,12 @@ var TEST_MATRICES = {
|
|
|
268
266
|
export {
|
|
269
267
|
getTestSkill,
|
|
270
268
|
TEST_SKILLS,
|
|
269
|
+
TEST_CATEGORIES,
|
|
271
270
|
TEST_MATRICES,
|
|
271
|
+
buildSkillConfigs,
|
|
272
272
|
createMockSkill,
|
|
273
273
|
createMockMatrix,
|
|
274
274
|
createMockCategory,
|
|
275
275
|
createMockResolvedStack
|
|
276
276
|
};
|
|
277
|
-
//# sourceMappingURL=chunk-
|
|
277
|
+
//# sourceMappingURL=chunk-7FMEMXJ4.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 { MergedSkillsMatrix, ResolvedSkill, SkillSlug } from \"../../types\";\nimport { createMockSkill, createMockCategory, createMockMatrix } from \"./helpers\";\n\nconst SKILL_FIXTURES = {\n react: createMockSkill(\"web-framework-react\", \"web-framework\", {\n description: \"React framework for building user interfaces\",\n tags: [\"react\", \"web\", \"ui\", \"component\"],\n }),\n zustand: createMockSkill(\"web-state-zustand\", \"web-client-state\", {\n description: \"Bear necessities state management\",\n tags: [\"state\", \"react\", \"zustand\"],\n }),\n hono: createMockSkill(\"api-framework-hono\", \"api-api\", {\n description: \"Lightweight web framework for the edge\",\n tags: [\"api\", \"api\", \"edge\", \"serverless\"],\n }),\n vitest: createMockSkill(\"web-testing-vitest\", \"web-testing\", {\n description: \"Next generation testing framework\",\n tags: [\"testing\", \"vitest\", \"unit\"],\n }),\n vue: createMockSkill(\"web-framework-vue\", \"web-framework\", {\n description: \"Progressive JavaScript framework\",\n tags: [\"vue\", \"web\", \"reactive\"],\n }),\n \"auth-patterns\": createMockSkill(\"api-security-auth-patterns\", \"api-security\", {\n description: \"Authentication and authorization patterns\",\n tags: [\"auth\", \"security\", \"jwt\", \"oauth\"],\n }),\n drizzle: createMockSkill(\"api-database-drizzle\", \"api-database\", {\n description: \"TypeScript ORM for SQL databases\",\n tags: [\"database\", \"orm\", \"sql\"],\n }),\n \"anti-over-engineering\": createMockSkill(\n \"meta-methodology-anti-over-engineering\",\n \"shared-methodology\",\n {\n description: \"Surgical implementation, not architectural innovation\",\n tags: [\"methodology\", \"foundational\"],\n },\n ),\n \"scss-modules\": createMockSkill(\"web-styling-scss-modules\", \"web-styling\", {\n description: \"CSS Modules with SCSS\",\n tags: [\"css\", \"scss\", \"modules\"],\n }),\n} satisfies Partial<Record<SkillSlug, ResolvedSkill>>;\n\nexport type TestSkillName = keyof typeof SKILL_FIXTURES;\n\nexport function getTestSkill(\n name: TestSkillName,\n overrides?: Partial<ResolvedSkill>,\n): ResolvedSkill {\n return { ...SKILL_FIXTURES[name], ...overrides };\n}\n\n// ---------------------------------------------------------------------------\n// Shared base skill fixtures — canonical defaults with no overrides.\n// Use spread for per-test customization: `{ ...TEST_SKILLS.react, slug: \"react\" }`\n// ---------------------------------------------------------------------------\n\nexport const TEST_SKILLS = {\n react: createMockSkill(\"web-framework-react\", \"web-framework\"),\n vue: createMockSkill(\"web-framework-vue\", \"web-framework\"),\n zustand: createMockSkill(\"web-state-zustand\", \"web-client-state\", {\n compatibleWith: [\"web-framework-react\"],\n }),\n pinia: createMockSkill(\"web-state-pinia\", \"web-client-state\", {\n compatibleWith: [\"web-framework-vue\"],\n }),\n hono: createMockSkill(\"api-framework-hono\", \"api-api\"),\n vitest: createMockSkill(\"web-testing-vitest\", \"web-testing\"),\n \"scss-modules\": createMockSkill(\"web-styling-scss-modules\", \"web-styling\"),\n drizzle: createMockSkill(\"api-database-drizzle\", \"api-database\"),\n // Methodology skills (DEFAULT_PRESELECTED_SKILLS) — used by createComprehensiveMatrix\n \"investigation-requirements\": createMockSkill(\n \"meta-methodology-investigation-requirements\",\n \"shared-methodology\",\n { description: \"Never speculate - read actual code first\" },\n ),\n \"anti-over-engineering\": createMockSkill(\n \"meta-methodology-anti-over-engineering\",\n \"shared-methodology\",\n {\n description: \"Surgical implementation, not architectural innovation\",\n },\n ),\n \"success-criteria\": createMockSkill(\"meta-methodology-success-criteria\", \"shared-methodology\", {\n description: \"Explicit, measurable criteria defining done\",\n }),\n \"write-verification\": createMockSkill(\n \"meta-methodology-write-verification\",\n \"shared-methodology\",\n {\n description: \"Verify work was actually saved\",\n },\n ),\n \"improvement-protocol\": createMockSkill(\n \"meta-methodology-improvement-protocol\",\n \"shared-methodology\",\n { description: \"Evidence-based self-improvement\" },\n ),\n \"context-management\": createMockSkill(\n \"meta-methodology-context-management\",\n \"shared-methodology\",\n {\n description: \"Maintain project continuity across sessions\",\n },\n ),\n} satisfies Partial<Record<SkillSlug, ResolvedSkill>>;\n\n// ---------------------------------------------------------------------------\n// Shared base category fixtures — canonical defaults with no overrides.\n// Use spread for per-test customization: `{ ...TEST_CATEGORIES.framework, required: true }`\n// ---------------------------------------------------------------------------\n\nexport const TEST_CATEGORIES = {\n framework: createMockCategory(\"web-framework\", \"Framework\"),\n clientState: createMockCategory(\"web-client-state\", \"Client State\"),\n styling: createMockCategory(\"web-styling\", \"Styling\"),\n testing: createMockCategory(\"web-testing\", \"Testing\"),\n api: createMockCategory(\"api-api\", \"Backend Framework\"),\n database: createMockCategory(\"api-database\", \"Database\"),\n methodology: createMockCategory(\"shared-methodology\", \"Methodology\"),\n tooling: createMockCategory(\"shared-tooling\", \"Tooling\"),\n};\n\n// ---------------------------------------------------------------------------\n// Shared matrix fixtures — common skill combinations used across test files.\n// Use createMockMatrix overrides for per-test customization:\n// `createMockMatrix(TEST_MATRICES.react.skills, { suggestedStacks: [...] })`\n// ---------------------------------------------------------------------------\n\nexport const TEST_MATRICES: Record<string, MergedSkillsMatrix> = {\n empty: createMockMatrix({}),\n react: createMockMatrix({\n \"web-framework-react\": TEST_SKILLS.react,\n }),\n reactAndZustand: createMockMatrix({\n \"web-framework-react\": TEST_SKILLS.react,\n \"web-state-zustand\": TEST_SKILLS.zustand,\n }),\n reactAndHono: createMockMatrix({\n \"web-framework-react\": TEST_SKILLS.react,\n \"api-framework-hono\": TEST_SKILLS.hono,\n }),\n reactAndScss: createMockMatrix({\n \"web-framework-react\": TEST_SKILLS.react,\n \"web-styling-scss-modules\": TEST_SKILLS[\"scss-modules\"],\n }),\n reactScssAndHono: createMockMatrix({\n \"web-framework-react\": TEST_SKILLS.react,\n \"web-styling-scss-modules\": TEST_SKILLS[\"scss-modules\"],\n \"api-framework-hono\": TEST_SKILLS.hono,\n }),\n reactZustandAndHono: createMockMatrix({\n \"web-framework-react\": TEST_SKILLS.react,\n \"web-state-zustand\": TEST_SKILLS.zustand,\n \"api-framework-hono\": TEST_SKILLS.hono,\n }),\n};\n","import path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { mkdir, writeFile, readFile } from \"fs/promises\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { run, Errors } from \"@oclif/core\";\nimport ansis from \"ansis\";\nimport { createJiti } from \"jiti\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DEFAULT_PLUGIN_NAME,\n STANDARD_FILES,\n} from \"../../consts\";\nimport { typedEntries } from \"../../utils/typed-object\";\nimport { computeSkillFolderHash } from \"../versioning\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport const CLI_ROOT = path.resolve(__dirname, \"../../../..\");\n\n/** Resolve @agents-inc/cli/config to the source config-exports.ts so jiti can load it in dev. */\nconst CONFIG_EXPORTS_PATH = path.resolve(__dirname, \"../../config-exports.ts\");\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 AgentName,\n AgentScopeConfig,\n CategoryDefinition,\n CategoryPath,\n CompiledAgentData,\n CompileAgentConfig,\n CompileConfig,\n CompileContext,\n Domain,\n DomainSelections,\n ExtractedSkillMetadata,\n Marketplace,\n MarketplacePlugin,\n MergedSkillsMatrix,\n ProjectConfig,\n ResolvedSkill,\n ResolvedStack,\n Skill,\n SkillAssignment,\n SkillConfig,\n SkillDefinition,\n SkillSlug,\n SkillSlugMap,\n SkillId,\n SkillSource,\n SkillSourceType,\n RelationshipDefinitions,\n RawStacksConfig,\n Stack,\n StackAgentConfig,\n Category,\n} from \"../../types\";\nimport type { CompiledStackPlugin } from \"../stacks/stack-plugin-compiler\";\nimport type { WizardResultV2 } from \"../../components/wizard/wizard\";\nimport type { SourceLoadResult } from \"../loading/source-loader\";\nimport type { ResolvedConfig } from \"../configuration/config\";\nimport { useWizardStore } from \"../../stores/wizard-store\";\nimport { resolveAlias, validateSelection } from \"../matrix\";\nimport type { TestProjectConfig, TestSkill } from \"./fixtures/create-test-source\";\nimport { getTestSkill, TEST_SKILLS, TEST_CATEGORIES } from \"./test-fixtures\";\n\nexport { fileExists, directoryExists } from \"./test-fs-utils\";\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\n/**\n * Load a config file using jiti. Handles defineConfig(), satisfies, and plain exports.\n */\nexport async function readTestTsConfig<T>(filePath: string): Promise<T> {\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n interopDefault: true,\n alias: { \"@agents-inc/cli/config\": CONFIG_EXPORTS_PATH },\n });\n // Boundary cast: jiti returns unknown, caller provides expected type\n const result = await jiti.import(filePath, { default: true });\n return result as T;\n}\n\n/** Writes a config file with the given object into the given subdirectory (defaults to CLAUDE_SRC_DIR) */\nexport async function writeTestTsConfig(\n projectDir: string,\n config: Record<string, unknown>,\n configSubdir: string = CLAUDE_SRC_DIR,\n): Promise<void> {\n const configDir = path.join(projectDir, configSubdir);\n await mkdir(configDir, { recursive: true });\n const content = `export default ${JSON.stringify(config, null, 2)};`;\n await writeFile(path.join(configDir, STANDARD_FILES.CONFIG_TS), content);\n}\n\nexport function buildProjectConfig(overrides?: Partial<ProjectConfig>): ProjectConfig {\n return {\n name: \"test-project\",\n agents: [{ name: \"web-developer\", scope: \"project\" }],\n skills: buildSkillConfigs([\"web-framework-react\"]),\n ...overrides,\n };\n}\n\nexport function buildWizardResult(\n skills: SkillConfig[],\n overrides?: Partial<WizardResultV2>,\n): WizardResultV2 {\n return {\n skills,\n selectedAgents: [],\n agentConfigs: [],\n selectedStackId: null,\n domainSelections: {} as DomainSelections,\n selectedDomains: [],\n cancelled: false,\n validation: { valid: true, errors: [], warnings: [] },\n ...overrides,\n };\n}\n\n/** Build a SkillConfig array from skill IDs with default scope and source */\nexport function buildSkillConfigs(\n skillIds: SkillId[],\n overrides?: Partial<Omit<SkillConfig, \"id\">>,\n): SkillConfig[] {\n return skillIds.map((id) => ({\n id,\n scope: overrides?.scope ?? \"project\",\n source: overrides?.source ?? \"local\",\n }));\n}\n\nexport function buildAgentConfigs(\n agentNames: AgentName[],\n overrides?: Partial<Omit<AgentScopeConfig, \"name\">>,\n): AgentScopeConfig[] {\n return agentNames.map((name) => ({\n name,\n scope: overrides?.scope ?? \"project\",\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\nimport { createTempDir, cleanupTempDir } from \"./test-fs-utils\";\nexport { createTempDir, cleanupTempDir };\n\nexport interface PluginTestDirs {\n tempDir: string;\n projectDir: string;\n pluginDir: string;\n skillsDir: string;\n agentsDir: string;\n}\n\nexport async function createTestDirs(prefix = \"ai-test-\"): Promise<PluginTestDirs> {\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: PluginTestDirs): 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 // Derive slug from skill ID: strip domain-category prefix to get the last segment(s)\n // e.g., \"web-framework-react\" -> \"react\", \"meta-methodology-anti-over-engineering\" -> \"anti-over-engineering\"\n const segments = id.split(\"-\");\n const defaultSlug = (segments.length >= 3 ? segments.slice(2).join(\"-\") : id) as SkillSlug;\n\n // Derive display name from slug: title-case each segment\n const defaultDisplayName = defaultSlug\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n\n return {\n id,\n slug: defaultSlug,\n displayName: defaultDisplayName,\n description: `${id} skill`,\n category,\n tags: [],\n author: \"@test\",\n conflictsWith: [],\n isRecommended: false,\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n requiresSetup: [],\n providesSetupFor: [],\n path: `skills/${category}/${id}/`,\n ...overrides,\n };\n}\n\nexport function createMockSkillSource(\n type: SkillSourceType,\n overrides?: Partial<SkillSource>,\n): SkillSource {\n const defaults: Record<SkillSourceType, SkillSource> = {\n public: { name: \"public\", type: \"public\", installed: false },\n private: {\n name: \"private-source\",\n type: \"private\",\n url: \"github:org/skills\",\n installed: false,\n },\n local: { name: \"local\", type: \"local\", installed: true, installMode: \"local\" },\n };\n return { ...defaults[type], ...overrides };\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-category-name\"\n const segments = id.split(\"-\");\n const domain = segments[0] ?? \"web\";\n const category = segments[1] ?? \"framework\";\n const name = segments.slice(2).join(\"-\") || \"skill\";\n const directoryPath = `${domain}/${category}/${name}`;\n\n return {\n id,\n directoryPath,\n description: `${id} skill`,\n category: `${domain}-${category}` as CategoryPath,\n author: \"@test\",\n tags: [],\n path: `skills/${directoryPath}/`,\n domain: domain as Domain,\n displayName: name,\n slug: name as SkillSlug,\n ...overrides,\n };\n}\n\nexport function createMockMatrix(\n skills: Record<string, ResolvedSkill>,\n overrides?: Partial<MergedSkillsMatrix>,\n): MergedSkillsMatrix {\n // Boundary cast: empty objects are populated in the loop below\n const autoSlugToId = {} as Record<SkillSlug, SkillId>;\n const autoIdToSlug = {} as Record<SkillId, SkillSlug>;\n for (const [id, skill] of typedEntries(skills)) {\n if (skill.slug) {\n autoSlugToId[skill.slug] = id as SkillId;\n autoIdToSlug[id as SkillId] = skill.slug;\n }\n }\n\n return {\n version: \"1.0.0\",\n categories: {} as Record<Category, import(\"../../types\").CategoryDefinition>,\n skills,\n suggestedStacks: [],\n slugMap: { slugToId: autoSlugToId, idToSlug: autoIdToSlug },\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\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\n/** Derive domain, category, and slug from a SkillId like \"web-framework-react\". */\nfunction parseSkillId(skillId: SkillId): {\n domain: string;\n category: CategoryPath;\n slug: SkillSlug;\n} {\n const parts = skillId.split(\"-\");\n const domain = parts[0];\n const category = parts.slice(0, 2).join(\"-\") as CategoryPath;\n const slug = parts.slice(2).join(\"-\") as SkillSlug;\n return { domain, category, slug };\n}\n\nexport async function writeTestSkill(\n skillsDir: string,\n skillId: SkillId,\n options?: {\n slug?: SkillSlug;\n category?: CategoryPath;\n author?: string;\n description?: string;\n /** Extra fields to merge into metadata.yaml (e.g., forkedFrom, displayName) */\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 parsed = parseSkillId(skillId);\n const slug = options?.slug ?? parsed.slug;\n const category = options?.category ?? parsed.category;\n const domain = options?.category?.split(\"-\")[0] ?? parsed.domain;\n\n const skillDir = path.join(skillsDir, skillId);\n await mkdir(skillDir, { recursive: true });\n\n await writeFile(\n path.join(skillDir, STANDARD_FILES.SKILL_MD),\n options?.skillContent ?? createSkillContent(skillId, options?.description),\n );\n\n if (!options?.skipMetadata) {\n const contentHash = await computeSkillFolderHash(skillDir);\n const baseMetadata = {\n author: options?.author ?? \"@test\",\n category,\n domain,\n slug,\n contentHash,\n };\n if (options?.extraMetadata) {\n const metadata = {\n ...baseMetadata,\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 stringifyYaml(baseMetadata),\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>/<category>/<name>/`).\n */\nexport async function writeSourceSkill(\n skillsDir: string,\n directoryPath: string,\n config: TestSkill,\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 domain = config.domain;\n const slug = config.slug;\n const metadata: Record<string, unknown> = {\n displayName: config.id,\n slug,\n category: config.category,\n domain,\n author: config.author ?? \"@test\",\n };\n if (config.tags) {\n metadata.tags = config.tags;\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_METADATA_YAML),\n createAgentYamlContent(agentName, options?.description),\n );\n\n return agentDir;\n}\n\nexport function createMockCategory(\n id: Category,\n displayName: string,\n overrides?: Partial<CategoryDefinition>,\n): CategoryDefinition {\n return {\n id,\n displayName,\n description: `${displayName} category`,\n domain: \"web\",\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 skills: {},\n allSkillIds: [],\n philosophy: \"\",\n ...overrides,\n };\n}\n\n/**\n * Builds a comprehensive test matrix with 13 skills across 7 categories,\n * 2 suggested stacks, display name mappings, and relationship data\n * (conflicts, recommends). Includes all 6 DEFAULT_PRESELECTED_SKILLS\n * (methodology) so wizard handleComplete can resolve them.\n * @returns A fully populated MergedSkillsMatrix with realistic test data\n */\nexport function createComprehensiveMatrix(\n overrides?: Partial<MergedSkillsMatrix>,\n): MergedSkillsMatrix {\n // Skill categories use domain-prefixed Category IDs (matching production\n // metadata.yaml and the categories map keys, e.g., \"web-framework\", \"api-api\").\n const skills = {\n \"web-framework-react\": getTestSkill(\"react\", { category: \"web-framework\" }),\n \"web-framework-vue\": getTestSkill(\"vue\", {\n category: \"web-framework\",\n conflictsWith: [{ skillId: \"web-framework-react\", reason: \"Choose one framework\" }],\n }),\n \"web-state-zustand\": getTestSkill(\"zustand\", {\n category: \"web-client-state\",\n }),\n \"web-styling-scss-modules\": getTestSkill(\"scss-modules\", { category: \"web-styling\" }),\n \"api-framework-hono\": getTestSkill(\"hono\", { category: \"api-api\" }),\n \"api-database-drizzle\": getTestSkill(\"drizzle\", { category: \"api-database\" }),\n \"web-testing-vitest\": getTestSkill(\"vitest\", { category: \"web-testing\" }),\n // Methodology skills (DEFAULT_PRESELECTED_SKILLS) — auto-injected by wizard\n \"meta-methodology-investigation-requirements\": TEST_SKILLS[\"investigation-requirements\"],\n \"meta-methodology-anti-over-engineering\": TEST_SKILLS[\"anti-over-engineering\"],\n \"meta-methodology-success-criteria\": TEST_SKILLS[\"success-criteria\"],\n \"meta-methodology-write-verification\": TEST_SKILLS[\"write-verification\"],\n \"meta-methodology-improvement-protocol\": TEST_SKILLS[\"improvement-protocol\"],\n \"meta-methodology-context-management\": TEST_SKILLS[\"context-management\"],\n };\n\n const categories = {\n \"web-framework\": {\n ...TEST_CATEGORIES.framework,\n domain: \"web\",\n exclusive: true,\n required: true,\n },\n \"web-client-state\": { ...TEST_CATEGORIES.clientState, domain: \"web\", order: 1 },\n \"web-styling\": { ...TEST_CATEGORIES.styling, domain: \"web\", order: 2 },\n \"api-api\": { ...TEST_CATEGORIES.api, domain: \"api\", exclusive: true, required: true },\n \"api-database\": { ...TEST_CATEGORIES.database, domain: \"api\", order: 1 },\n \"web-testing\": {\n ...TEST_CATEGORIES.testing,\n domain: \"shared\",\n exclusive: false,\n order: 10,\n },\n \"shared-methodology\": {\n ...TEST_CATEGORIES.methodology,\n domain: \"shared\",\n exclusive: false,\n required: false,\n order: 11,\n },\n } as Record<Category, CategoryDefinition>;\n\n const suggestedStacks: ResolvedStack[] = [\n createMockResolvedStack(\"nextjs-fullstack\", \"Next.js Fullstack\", {\n description: \"Complete Next.js stack with React and Hono\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-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 skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-vue\"],\n },\n } as ResolvedStack[\"skills\"],\n allSkillIds: [\"web-framework-vue\"],\n philosophy: \"Progressive framework approach\",\n }),\n ];\n\n // Boundary cast: test matrix only contains a subset of all possible slugs\n const slugToId = {\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 \"investigation-requirements\": \"meta-methodology-investigation-requirements\",\n \"anti-over-engineering\": \"meta-methodology-anti-over-engineering\",\n \"success-criteria\": \"meta-methodology-success-criteria\",\n \"write-verification\": \"meta-methodology-write-verification\",\n \"improvement-protocol\": \"meta-methodology-improvement-protocol\",\n \"context-management\": \"meta-methodology-context-management\",\n } as unknown as Record<SkillSlug, SkillId>;\n\n // Boundary cast: Object.fromEntries returns { [k: string]: string }\n const idToSlug = Object.fromEntries(\n typedEntries(slugToId).map(([slug, fullId]) => [fullId, slug]),\n ) as SkillSlugMap[\"idToSlug\"];\n\n return createMockMatrix(skills, {\n categories,\n suggestedStacks,\n slugMap: { slugToId, idToSlug },\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 // Domain-prefixed Category IDs — see createComprehensiveMatrix comment\n const skills = {\n \"web-framework-react\": getTestSkill(\"react\", { category: \"web-framework\" }),\n \"web-state-zustand\": getTestSkill(\"zustand\", { category: \"web-client-state\" }),\n \"api-framework-hono\": getTestSkill(\"hono\", { category: \"api-api\" }),\n \"web-testing-vitest\": getTestSkill(\"vitest\", { category: \"web-testing\" }),\n // Methodology skills (DEFAULT_PRESELECTED_SKILLS) — auto-injected by wizard\n \"meta-methodology-anti-over-engineering\": TEST_SKILLS[\"anti-over-engineering\"],\n \"meta-methodology-context-management\": TEST_SKILLS[\"context-management\"],\n \"meta-methodology-improvement-protocol\": TEST_SKILLS[\"improvement-protocol\"],\n \"meta-methodology-investigation-requirements\": TEST_SKILLS[\"investigation-requirements\"],\n \"meta-methodology-success-criteria\": TEST_SKILLS[\"success-criteria\"],\n \"meta-methodology-write-verification\": TEST_SKILLS[\"write-verification\"],\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 \"web-framework\": {\n ...TEST_CATEGORIES.framework,\n domain: \"web\",\n exclusive: true,\n required: true,\n },\n \"web-client-state\": { ...TEST_CATEGORIES.clientState, domain: \"web\", order: 1 },\n \"api-api\": {\n ...TEST_CATEGORIES.api,\n domain: \"api\",\n exclusive: true,\n required: true,\n },\n \"web-testing\": {\n ...TEST_CATEGORIES.testing,\n displayName: \"Testing Framework\",\n domain: \"shared\",\n exclusive: false,\n },\n \"shared-methodology\": {\n ...TEST_CATEGORIES.methodology,\n domain: \"shared\",\n exclusive: false,\n required: false,\n },\n } as Record<Category, CategoryDefinition>,\n ...overrides,\n });\n}\n\n/**\n * Replicates `handleComplete` from wizard.tsx for the \"customize\" path.\n *\n * Given the wizard store state (after simulated user selections), this\n * builds the same WizardResultV2 that the real wizard produces:\n * 1. Collects all selected technologies from domainSelections\n * 2. Resolves aliases to canonical skill IDs\n * 3. Adds methodology skills (DEFAULT_PRESELECTED_SKILLS)\n * 4. Runs validation\n */\nexport function buildWizardResultFromStore(\n matrix: MergedSkillsMatrix,\n overrides?: Partial<WizardResultV2>,\n): WizardResultV2 {\n const store = useWizardStore.getState();\n\n let allSkills: SkillId[];\n\n if (store.selectedStackId && store.stackAction === \"defaults\") {\n const stack = matrix.suggestedStacks.find((s) => s.id === store.selectedStackId);\n allSkills = [...(stack?.allSkillIds || [])];\n } else {\n const techNames = store.getAllSelectedTechnologies();\n allSkills = techNames.map((tech) => resolveAlias(tech, matrix));\n }\n\n const methodologySkills = store.getDefaultMethodologySkills();\n allSkills = [...allSkills, ...methodologySkills.filter((s) => !allSkills.includes(s))];\n\n const validation = validateSelection(allSkills, matrix);\n\n return {\n skills: store.skillConfigs.length > 0 ? store.skillConfigs : buildSkillConfigs(allSkills),\n selectedAgents: store.selectedAgents,\n agentConfigs: store.agentConfigs,\n selectedStackId: store.selectedStackId,\n domainSelections: store.domainSelections,\n selectedDomains: store.selectedDomains,\n cancelled: false,\n validation,\n ...overrides,\n };\n}\n\n/**\n * Simulates a user selecting specific skills via the wizard store.\n *\n * Sets up domainSelections as if the user toggled each skill in the build step,\n * using the matrix to look up the correct domain and category per skill.\n */\nexport function simulateSkillSelections(\n skillIds: SkillId[],\n matrix: MergedSkillsMatrix,\n selectedDomains: string[],\n): void {\n const domainSelections = skillIds.reduce<DomainSelections>((acc, skillId) => {\n const skill = matrix.skills[skillId];\n if (!skill) return acc;\n // Boundary cast: skill.category is a Category at runtime\n const category = skill.category as Category;\n const domain = matrix.categories[category]?.domain;\n if (!domain) return acc;\n const domainObj = acc[domain] ?? {};\n const subcatList = domainObj[category] ?? [];\n if (subcatList.includes(skillId)) return acc;\n return {\n ...acc,\n [domain]: { ...domainObj, [category]: [...subcatList, skillId] },\n };\n }, {});\n\n useWizardStore.setState({\n domainSelections,\n selectedDomains: selectedDomains as Domain[],\n approach: \"scratch\",\n step: \"confirm\",\n });\n}\n\n/**\n * Extracts skill IDs from a stack assignment value, which may be:\n * - A bare string (e.g., \"web-framework-react\")\n * - An object with .id (e.g., { id: \"web-framework-react\", preloaded: true })\n * - An array of strings or objects\n */\nexport function extractSkillIdsFromAssignment(assignment: unknown): string[] {\n if (typeof assignment === \"string\") {\n return [assignment];\n }\n if (Array.isArray(assignment)) {\n return assignment.flatMap((item) => extractSkillIdsFromAssignment(item));\n }\n if (typeof assignment === \"object\" && assignment !== null && \"id\" in assignment) {\n return [String((assignment as { id: string }).id)];\n }\n return [];\n}\n\nexport function buildTestProjectConfig(\n agents: string[],\n skills: Array<string | { id: string }>,\n overrides?: Partial<TestProjectConfig>,\n): TestProjectConfig {\n return {\n name: \"test-project\",\n description: \"Test project\",\n agents,\n skills,\n ...overrides,\n };\n}\n\nexport function createMockSkillDefinition(\n id: SkillId,\n overrides?: Partial<SkillDefinition>,\n): SkillDefinition {\n return {\n id,\n path: `skills/${id}/`,\n description: `${id} skill`,\n ...overrides,\n };\n}\n\n/** Decomposed matrix config returned by createMockMatrixConfig (replaces SkillsMatrixConfig) */\nexport type MockMatrixConfig = {\n categories: Record<string, CategoryDefinition>;\n relationships: RelationshipDefinitions;\n};\n\nexport function createMockMatrixConfig(\n categories: Record<string, CategoryDefinition>,\n overrides?: {\n relationships?: RelationshipDefinitions;\n },\n): MockMatrixConfig {\n return {\n categories,\n relationships: overrides?.relationships ?? {\n conflicts: [],\n discourages: [],\n recommends: [],\n requires: [],\n alternatives: [],\n },\n };\n}\n\nexport function createMockStack(\n id: string,\n config: {\n name: string;\n description?: string;\n agents: Record<string, StackAgentConfig>;\n philosophy?: string;\n },\n): Stack {\n return {\n id,\n name: config.name,\n description: config.description ?? \"\",\n // Boundary cast: test callers may pass arbitrary agent names (e.g., \"nonexistent-agent\")\n agents: config.agents as Stack[\"agents\"],\n philosophy: config.philosophy,\n };\n}\n\nexport function createMockCompileConfig(\n agents: Record<string, CompileAgentConfig>,\n overrides?: Partial<CompileConfig>,\n): CompileConfig {\n return {\n name: \"Test Plugin\",\n description: \"Test description\",\n agents,\n ...overrides,\n };\n}\n\nexport function createMockCompiledStackPlugin(\n overrides?: Partial<CompiledStackPlugin>,\n): CompiledStackPlugin {\n return {\n pluginPath: \"/tmp/cc-stack-123456/test-stack\",\n manifest: { name: \"test-stack\", version: \"1.0.0\" },\n stackName: \"Test Stack\",\n agents: [\"web-developer\"],\n skillPlugins: [\"web-framework-react\"],\n hasHooks: false,\n ...overrides,\n };\n}\n\nexport function createMockSkillAssignment(id: SkillId, preloaded = false): SkillAssignment {\n return { id, preloaded };\n}\n\nexport function createMockRawStacksConfig(): RawStacksConfig {\n return {\n stacks: [\n {\n id: \"nextjs-fullstack\",\n name: \"Next.js Fullstack\",\n description: \"Full-stack Next.js with Hono API\",\n agents: {\n \"web-developer\": {\n \"web-framework\": \"web-framework-react\",\n \"web-styling\": \"web-styling-scss-modules\",\n },\n \"api-developer\": {\n \"api-api\": \"api-framework-hono\",\n \"api-database\": \"api-database-drizzle\",\n },\n },\n },\n {\n id: \"vue-spa\",\n name: \"Vue SPA\",\n description: \"Vue single-page application\",\n agents: {\n \"web-developer\": {\n \"web-framework\": \"web-framework-vue-composition-api\",\n \"web-styling\": \"web-styling-tailwind\",\n },\n },\n },\n ],\n };\n}\n\nexport function createMockRawStacksConfigWithArrays(): RawStacksConfig {\n return {\n stacks: [\n {\n id: \"multi-select-stack\",\n name: \"Multi-Select Stack\",\n description: \"Stack with array-valued categories\",\n agents: {\n \"web-developer\": {\n \"web-framework\": \"web-framework-react\",\n \"shared-methodology\": [\n \"meta-methodology-investigation-requirements\",\n \"meta-methodology-anti-over-engineering\",\n \"meta-methodology-success-criteria\",\n ],\n },\n \"pattern-scout\": {\n \"shared-methodology\": [\n \"meta-methodology-investigation-requirements\",\n \"meta-methodology-anti-over-engineering\",\n ],\n \"shared-research\": \"meta-research-research-methodology\",\n },\n },\n },\n ],\n };\n}\n\nexport function createMockRawStacksConfigWithObjects(): RawStacksConfig {\n return {\n stacks: [\n {\n id: \"object-stack\",\n name: \"Object Stack\",\n description: \"Stack with object-form skill assignments\",\n agents: {\n \"web-developer\": {\n \"web-framework\": [{ id: \"web-framework-react\", preloaded: true }],\n \"web-styling\": \"web-styling-scss-modules\",\n \"shared-methodology\": [\n { id: \"meta-methodology-investigation-requirements\", preloaded: true },\n \"meta-methodology-anti-over-engineering\",\n ],\n },\n },\n },\n ],\n };\n}\n\nexport function createMockMarketplace(plugins: MarketplacePlugin[] = []): Marketplace {\n return {\n name: \"test-marketplace\",\n version: \"1.0.0\",\n owner: { name: \"Test Owner\" },\n plugins,\n };\n}\n\nexport function createMockMarketplacePlugin(\n name: string,\n source: MarketplacePlugin[\"source\"] = \"local\",\n): MarketplacePlugin {\n return {\n name,\n source,\n };\n}\n\n/**\n * Creates a ResolvedSkill with availableSources annotation for multi-source testing.\n * Simulates what multi-source-loader.ts does after tagging.\n */\nexport function createMockMultiSourceSkill(\n id: SkillId,\n category: CategoryPath,\n sources: SkillSource[],\n overrides?: Partial<ResolvedSkill>,\n): ResolvedSkill {\n const activeSource = sources.find((s) => s.installed) ?? sources[0];\n return createMockSkill(id, category, {\n availableSources: sources,\n activeSource,\n ...overrides,\n });\n}\n\nexport function createMockCompiledAgentData(overrides?: Partial<AgentConfig>): CompiledAgentData {\n const agent = createMockAgentConfig(\"test-agent\", [], {\n title: \"Test Agent\",\n description: \"A test agent\",\n ...overrides,\n });\n\n return {\n agent,\n intro: \"Test intro\",\n workflow: \"Test workflow\",\n examples: \"Test examples\",\n criticalRequirementsTop: \"\",\n criticalReminders: \"\",\n outputFormat: \"\",\n skills: agent.skills,\n preloadedSkills: [],\n dynamicSkills: [],\n preloadedSkillIds: [],\n };\n}\n\nexport { getTestSkill, TEST_SKILLS, TEST_CATEGORIES, TEST_MATRICES } from \"./test-fixtures\";\nexport type { TestSkillName } from \"./test-fixtures\";\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CLI_COLORS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
5
5
|
import {
|
|
6
6
|
init_esm_shims
|
|
7
7
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -45,4 +45,4 @@ var SectionProgress = ({
|
|
|
45
45
|
export {
|
|
46
46
|
SectionProgress
|
|
47
47
|
};
|
|
48
|
-
//# sourceMappingURL=chunk-
|
|
48
|
+
//# sourceMappingURL=chunk-AJJJE7F7.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CLI_COLORS,
|
|
4
4
|
DEFAULT_BRANDING
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
6
6
|
import {
|
|
7
7
|
init_esm_shims
|
|
8
8
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -108,4 +108,4 @@ var StepRefine = ({
|
|
|
108
108
|
export {
|
|
109
109
|
StepRefine
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-AX3SZZWA.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
cliTheme
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XUDTFI4M.js";
|
|
5
5
|
import {
|
|
6
6
|
useTextInput
|
|
7
7
|
} from "./chunk-U3IGFMCY.js";
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
CLI_COLORS,
|
|
10
10
|
UI_LAYOUT,
|
|
11
11
|
UI_SYMBOLS
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
13
13
|
import {
|
|
14
14
|
init_esm_shims
|
|
15
15
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -93,7 +93,8 @@ function matchesQuery(skill, query) {
|
|
|
93
93
|
if (!query.trim()) return true;
|
|
94
94
|
const lowerQuery = query.toLowerCase();
|
|
95
95
|
if (skill.id.toLowerCase().includes(lowerQuery)) return true;
|
|
96
|
-
if (skill.displayName
|
|
96
|
+
if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;
|
|
97
|
+
if (skill.slug?.toLowerCase().includes(lowerQuery)) return true;
|
|
97
98
|
if (skill.description.toLowerCase().includes(lowerQuery)) return true;
|
|
98
99
|
if (skill.category.toLowerCase().includes(lowerQuery)) return true;
|
|
99
100
|
if (skill.tags.some((tag) => tag.toLowerCase().includes(lowerQuery))) return true;
|
|
@@ -343,4 +344,4 @@ var SkillSearch = ({
|
|
|
343
344
|
export {
|
|
344
345
|
SkillSearch
|
|
345
346
|
};
|
|
346
|
-
//# sourceMappingURL=chunk-
|
|
347
|
+
//# sourceMappingURL=chunk-BFD5NZQ4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/skill-search/skill-search.tsx","../src/cli/components/hooks/use-filtered-results.ts"],"sourcesContent":["import React, { useState, useCallback } from \"react\";\nimport { Box, Text, useApp, useInput } from \"ink\";\nimport { ThemeProvider } from \"@inkjs/ui\";\nimport { cliTheme } from \"../themes/default.js\";\nimport type { ResolvedSkill, SkillId } from \"../../types/index.js\";\nimport { CLI_COLORS, UI_SYMBOLS, UI_LAYOUT } from \"../../consts.js\";\nimport { useTextInput } from \"../hooks/use-text-input.js\";\nimport { useFilteredResults } from \"../hooks/use-filtered-results.js\";\n\nexport type SourcedSkill = ResolvedSkill & {\n sourceName: string;\n sourceUrl?: string;\n};\n\nexport type SkillSearchResult = {\n selectedSkills: SourcedSkill[];\n cancelled: boolean;\n};\n\nexport type SkillSearchProps = {\n skills: SourcedSkill[];\n sourceCount: number;\n initialQuery?: string;\n onComplete: (result: SkillSearchResult) => void;\n onCancel: () => void;\n};\n\nconst {\n MAX_VISIBLE_RESULTS,\n DESCRIPTION_WIDTH,\n COPIED_MESSAGE_TIMEOUT_MS,\n FALLBACK_MESSAGE_TIMEOUT_MS,\n} = UI_LAYOUT;\nconst { CHECKBOX_CHECKED, CHECKBOX_UNCHECKED } = UI_SYMBOLS;\n\nfunction matchesQuery(skill: SourcedSkill, query: string): boolean {\n if (!query.trim()) return true;\n\n const lowerQuery = query.toLowerCase();\n\n if (skill.id.toLowerCase().includes(lowerQuery)) return true;\n if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;\n if (skill.slug?.toLowerCase().includes(lowerQuery)) return true;\n if (skill.description.toLowerCase().includes(lowerQuery)) return true;\n if (skill.category.toLowerCase().includes(lowerQuery)) return true;\n if (skill.tags.some((tag) => tag.toLowerCase().includes(lowerQuery))) return true;\n\n return skill.sourceName.toLowerCase().includes(lowerQuery);\n}\n\nfunction truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return `${text.slice(0, maxLength - 3)}...`;\n}\n\ntype HeaderProps = {\n sourceCount: number;\n};\n\nconst Header: React.FC<HeaderProps> = ({ sourceCount }) => {\n return (\n <Box\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n borderStyle=\"single\"\n borderBottom={false}\n borderLeft={false}\n borderRight={false}\n paddingX={1}\n >\n <Text bold color={CLI_COLORS.PRIMARY}>\n Search Skills\n </Text>\n <Text dimColor>\n {sourceCount} source{sourceCount !== 1 ? \"s\" : \"\"}\n </Text>\n </Box>\n );\n};\n\ntype SearchInputProps = {\n value: string;\n};\n\nconst SearchInput: React.FC<SearchInputProps> = ({ value }) => {\n return (\n <Box paddingX={1} paddingY={1}>\n <Text color={CLI_COLORS.FOCUS}>{\">\"} </Text>\n <Text>{value}</Text>\n <Text color={CLI_COLORS.FOCUS}>_</Text>\n </Box>\n );\n};\n\ntype ResultItemProps = {\n skill: SourcedSkill;\n isSelected: boolean;\n isFocused: boolean;\n};\n\nconst ResultItem: React.FC<ResultItemProps> = ({ skill, isSelected, isFocused }) => {\n const checkbox = isSelected ? CHECKBOX_CHECKED : CHECKBOX_UNCHECKED;\n const displayName = skill.displayName || skill.id;\n return (\n <Box flexDirection=\"row\" gap={1}>\n <Text\n color={isFocused ? CLI_COLORS.FOCUS : isSelected ? CLI_COLORS.SUCCESS : undefined}\n bold={isFocused}\n backgroundColor={isFocused ? \"#333333\" : undefined}\n >\n {\" \"}\n {checkbox}{\" \"}\n </Text>\n <Box width={14}>\n <Text dimColor>{truncate(skill.sourceName, 12)}</Text>\n </Box>\n <Box width={24}>\n <Text color={isFocused ? CLI_COLORS.FOCUS : undefined} bold={isFocused || isSelected}>\n {truncate(displayName, 22)}\n </Text>\n </Box>\n <Text dimColor>{truncate(skill.description, DESCRIPTION_WIDTH)}</Text>\n </Box>\n );\n};\n\ntype ResultsListProps = {\n results: SourcedSkill[];\n selectedIds: Set<SkillId>;\n focusedIndex: number;\n scrollOffset: number;\n};\n\nconst ResultsList: React.FC<ResultsListProps> = ({\n results,\n selectedIds,\n focusedIndex,\n scrollOffset,\n}) => {\n const visibleResults = results.slice(scrollOffset, scrollOffset + MAX_VISIBLE_RESULTS);\n\n if (results.length === 0) {\n return (\n <Box paddingX={1} paddingY={1}>\n <Text dimColor>No skills found matching your search.</Text>\n </Box>\n );\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderTop={false}\n borderBottom={false}\n paddingX={1}\n >\n {visibleResults.map((skill, index) => {\n const actualIndex = scrollOffset + index;\n return (\n <ResultItem\n key={skill.id}\n skill={skill}\n isSelected={selectedIds.has(skill.id)}\n isFocused={actualIndex === focusedIndex}\n />\n );\n })}\n </Box>\n );\n};\n\ntype StatusBarProps = {\n resultCount: number;\n selectedCount: number;\n};\n\nconst StatusBar: React.FC<StatusBarProps> = ({ resultCount, selectedCount }) => {\n return (\n <Box paddingX={1}>\n <Text dimColor>\n {resultCount} result{resultCount !== 1 ? \"s\" : \"\"}\n {selectedCount > 0 && <Text color={CLI_COLORS.SUCCESS}> | {selectedCount} selected</Text>}\n </Text>\n </Box>\n );\n};\n\ntype FooterProps = {\n hasSelection: boolean;\n};\n\nconst Footer: React.FC<FooterProps> = ({ hasSelection }) => {\n return (\n <Box\n flexDirection=\"row\"\n justifyContent=\"center\"\n gap={2}\n borderStyle=\"single\"\n borderTop={false}\n borderLeft={false}\n borderRight={false}\n paddingX={1}\n marginTop={1}\n >\n <Text dimColor>\n <Text color={CLI_COLORS.UNFOCUSED}>j/k</Text> navigate\n </Text>\n <Text dimColor>\n <Text color={CLI_COLORS.UNFOCUSED}>SPACE</Text> select\n </Text>\n {hasSelection && (\n <Text dimColor>\n <Text color={CLI_COLORS.SUCCESS}>ENTER</Text> import\n </Text>\n )}\n <Text dimColor>\n <Text color={CLI_COLORS.UNFOCUSED}>c</Text> copy link\n </Text>\n <Text dimColor>\n <Text color={CLI_COLORS.WARNING}>ESC</Text> cancel\n </Text>\n </Box>\n );\n};\n\nexport const SkillSearch: React.FC<SkillSearchProps> = ({\n skills,\n sourceCount,\n initialQuery = \"\",\n onComplete,\n onCancel,\n}) => {\n const { exit } = useApp();\n\n const { value: query, handleInput: handleTextInput } = useTextInput(initialQuery);\n const [selectedIds, setSelectedIds] = useState<Set<SkillId>>(new Set());\n const [copiedMessage, setCopiedMessage] = useState<string | null>(null);\n\n const {\n filteredResults,\n safeFocusedIndex,\n focusedItem: focusedSkill,\n scrollOffset,\n moveUp,\n moveDown,\n } = useFilteredResults({\n items: skills,\n query,\n filterFn: matchesQuery,\n maxVisible: MAX_VISIBLE_RESULTS,\n });\n\n const toggleSelection = useCallback((skillId: SkillId) => {\n setSelectedIds((prev) => {\n const next = new Set(prev);\n if (next.has(skillId)) {\n next.delete(skillId);\n } else {\n next.add(skillId);\n }\n return next;\n });\n }, []);\n\n const copySkillLink = useCallback(async (skill: SourcedSkill) => {\n const link = skill.sourceUrl ? `${skill.sourceUrl}/${skill.id}` : skill.id;\n\n try {\n // OSC 52 terminal clipboard escape sequence\n const encoded = Buffer.from(link).toString(\"base64\");\n process.stdout.write(`\\x1b]52;c;${encoded}\\x07`);\n setCopiedMessage(`Copied: ${link}`);\n setTimeout(() => setCopiedMessage(null), COPIED_MESSAGE_TIMEOUT_MS);\n } catch {\n setCopiedMessage(`Link: ${link}`);\n setTimeout(() => setCopiedMessage(null), FALLBACK_MESSAGE_TIMEOUT_MS);\n }\n }, []);\n\n useInput((input, key) => {\n if (key.escape) {\n onCancel();\n exit();\n return;\n }\n\n if (key.return) {\n if (selectedIds.size > 0) {\n const selectedSkills = filteredResults.filter((s) => selectedIds.has(s.id));\n onComplete({\n selectedSkills,\n cancelled: false,\n });\n exit();\n }\n return;\n }\n\n if (input === \" \" && focusedSkill) {\n toggleSelection(focusedSkill.id);\n return;\n }\n\n if ((input === \"c\" || input === \"C\") && focusedSkill) {\n void copySkillLink(focusedSkill);\n return;\n }\n\n const isUp = key.upArrow || input === \"k\";\n const isDown = key.downArrow || input === \"j\";\n\n if (isUp) {\n moveUp();\n }\n\n if (isDown) {\n moveDown();\n }\n\n handleTextInput(input, key);\n });\n\n return (\n <ThemeProvider theme={cliTheme}>\n <Box flexDirection=\"column\">\n <Header sourceCount={sourceCount} />\n <SearchInput value={query} />\n <ResultsList\n results={filteredResults}\n selectedIds={selectedIds}\n focusedIndex={safeFocusedIndex}\n scrollOffset={scrollOffset}\n />\n <StatusBar resultCount={filteredResults.length} selectedCount={selectedIds.size} />\n {copiedMessage && (\n <Box paddingX={1}>\n <Text color={CLI_COLORS.SUCCESS}>{copiedMessage}</Text>\n </Box>\n )}\n <Footer hasSelection={selectedIds.size > 0} />\n </Box>\n </ThemeProvider>\n );\n};\n","import { useState, useMemo, useEffect, useCallback, useRef } from \"react\";\n\ntype UseFilteredResultsOptions<T> = {\n /** Items to filter */\n items: T[];\n /** Current search query */\n query: string;\n /** Filter predicate — returns true if item matches the query */\n filterFn: (item: T, query: string) => boolean;\n /** Number of visible rows in the scrollable viewport */\n maxVisible: number;\n};\n\ntype UseFilteredResultsResult<T> = {\n /** Items that pass the filter */\n filteredResults: T[];\n /** Index clamped to valid range */\n safeFocusedIndex: number;\n /** The item at safeFocusedIndex, or undefined when empty */\n focusedItem: T | undefined;\n /** First visible row offset for windowed rendering */\n scrollOffset: number;\n /** Move focus up one row (clamped, adjusts scroll) */\n moveUp: () => void;\n /** Move focus down one row (clamped, adjusts scroll) */\n moveDown: () => void;\n};\n\n/**\n * Manages filtered list state: query-based filtering, focus tracking,\n * and scroll-offset synchronisation for windowed rendering.\n * Focus and scroll reset automatically when the query changes.\n */\nexport function useFilteredResults<T>({\n items,\n query,\n filterFn,\n maxVisible,\n}: UseFilteredResultsOptions<T>): UseFilteredResultsResult<T> {\n const [focusedIndex, setFocusedIndex] = useState(0);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n useEffect(() => {\n setFocusedIndex(0);\n setScrollOffset(0);\n }, [query]);\n\n const filteredResults = useMemo(() => {\n return items.filter((item) => filterFn(item, query));\n }, [items, query, filterFn]);\n\n const safeFocusedIndex = Math.min(focusedIndex, Math.max(0, filteredResults.length - 1));\n const focusedItem = filteredResults[safeFocusedIndex] as T | undefined;\n\n // Refs for stable callback access (matches use-keyboard-navigation pattern)\n const safeFocusedIndexRef = useRef(safeFocusedIndex);\n const scrollOffsetRef = useRef(scrollOffset);\n const resultCountRef = useRef(filteredResults.length);\n\n useEffect(() => {\n safeFocusedIndexRef.current = safeFocusedIndex;\n }, [safeFocusedIndex]);\n\n useEffect(() => {\n scrollOffsetRef.current = scrollOffset;\n }, [scrollOffset]);\n\n useEffect(() => {\n resultCountRef.current = filteredResults.length;\n }, [filteredResults.length]);\n\n const moveUp = useCallback(() => {\n const current = safeFocusedIndexRef.current;\n if (current <= 0) return;\n const newIndex = current - 1;\n setFocusedIndex(newIndex);\n if (newIndex < scrollOffsetRef.current) {\n setScrollOffset(newIndex);\n }\n }, []);\n\n const moveDown = useCallback(() => {\n const current = safeFocusedIndexRef.current;\n if (current >= resultCountRef.current - 1) return;\n const newIndex = current + 1;\n setFocusedIndex(newIndex);\n if (newIndex >= scrollOffsetRef.current + maxVisible) {\n setScrollOffset(newIndex - maxVisible + 1);\n }\n }, [maxVisible]);\n\n return {\n filteredResults,\n safeFocusedIndex,\n focusedItem,\n scrollOffset,\n moveUp,\n moveDown,\n };\n}\n"],"mappings":"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","names":["useState","useCallback","useState","useCallback"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
BUILT_IN_DOMAIN_ORDER
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
5
5
|
import {
|
|
6
6
|
init_esm_shims
|
|
7
7
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -35,4 +35,4 @@ export {
|
|
|
35
35
|
getStackName,
|
|
36
36
|
orderDomains
|
|
37
37
|
};
|
|
38
|
-
//# sourceMappingURL=chunk-
|
|
38
|
+
//# sourceMappingURL=chunk-BKJHAJQW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/components/wizard/utils.ts"],"sourcesContent":["import { unique } from \"remeda\";\nimport { BUILT_IN_DOMAIN_ORDER } from \"../../consts.js\";\nimport type { CategoryMap, Domain, MergedSkillsMatrix, ResolvedStack } from \"../../types/index.js\";\nimport { typedKeys } from \"../../utils/typed-object.js\";\n\nexport function getDomainDisplayName(domain: string): string {\n const displayNames: Record<Domain, string> = {\n web: \"Web\",\n api: \"API\",\n cli: \"CLI\",\n mobile: \"Mobile\",\n shared: \"Shared\",\n };\n return (\n (domain in displayNames ? displayNames[domain as Domain] : null) ??\n domain.charAt(0).toUpperCase() + domain.slice(1)\n );\n}\n\nexport function getStackName(\n stackId: string | null,\n matrix: MergedSkillsMatrix,\n): string | undefined {\n if (!stackId) return undefined;\n const stack = matrix.suggestedStacks.find((s) => s.id === stackId);\n return stack?.name;\n}\n\n/** Sort domains into canonical display order: custom domains first (alphabetically), then built-in domains (per BUILT_IN_DOMAIN_ORDER). */\nexport function orderDomains(domains: Domain[]): Domain[] {\n const builtIn = BUILT_IN_DOMAIN_ORDER.filter((d) => domains.includes(d));\n const custom = domains.filter((d) => !BUILT_IN_DOMAIN_ORDER.includes(d)).sort();\n return [...custom, ...builtIn];\n}\n\n/** Extract unique domains from a stack's agent-to-skill mappings. */\nexport function getDomainsFromStack(stack: ResolvedStack, categories: CategoryMap): Domain[] {\n const
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/utils.ts"],"sourcesContent":["import { unique } from \"remeda\";\nimport { BUILT_IN_DOMAIN_ORDER } from \"../../consts.js\";\nimport type { CategoryMap, Domain, MergedSkillsMatrix, ResolvedStack } from \"../../types/index.js\";\nimport { typedKeys } from \"../../utils/typed-object.js\";\n\nexport function getDomainDisplayName(domain: string): string {\n const displayNames: Record<Domain, string> = {\n web: \"Web\",\n api: \"API\",\n cli: \"CLI\",\n mobile: \"Mobile\",\n shared: \"Shared\",\n };\n return (\n (domain in displayNames ? displayNames[domain as Domain] : null) ??\n domain.charAt(0).toUpperCase() + domain.slice(1)\n );\n}\n\nexport function getStackName(\n stackId: string | null,\n matrix: MergedSkillsMatrix,\n): string | undefined {\n if (!stackId) return undefined;\n const stack = matrix.suggestedStacks.find((s) => s.id === stackId);\n return stack?.name;\n}\n\n/** Sort domains into canonical display order: custom domains first (alphabetically), then built-in domains (per BUILT_IN_DOMAIN_ORDER). */\nexport function orderDomains(domains: Domain[]): Domain[] {\n const builtIn = BUILT_IN_DOMAIN_ORDER.filter((d) => domains.includes(d));\n const custom = domains.filter((d) => !BUILT_IN_DOMAIN_ORDER.includes(d)).sort();\n return [...custom, ...builtIn];\n}\n\n/** Extract unique domains from a stack's agent-to-skill mappings. */\nexport function getDomainsFromStack(stack: ResolvedStack, categories: CategoryMap): Domain[] {\n const categoryKeys = Object.values(stack.skills).flatMap((config) =>\n config ? typedKeys(config) : [],\n );\n return unique(\n categoryKeys.flatMap((sub) => {\n const d = categories[sub]?.domain;\n return d ? [d] : [];\n }),\n ).sort();\n}\n"],"mappings":";;;;;;;;;AAAA;AAAA,SAAS,cAAc;AAKhB,SAAS,qBAAqB,QAAwB;AAC3D,QAAM,eAAuC;AAAA,IAC3C,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,UACG,UAAU,eAAe,aAAa,MAAgB,IAAI,SAC3D,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAEnD;AAEO,SAAS,aACd,SACA,QACoB;AACpB,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,QAAQ,OAAO,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AACjE,SAAO,OAAO;AAChB;AAGO,SAAS,aAAa,SAA6B;AACxD,QAAM,UAAU,sBAAsB,OAAO,CAAC,MAAM,QAAQ,SAAS,CAAC,CAAC;AACvE,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,CAAC,sBAAsB,SAAS,CAAC,CAAC,EAAE,KAAK;AAC9E,SAAO,CAAC,GAAG,QAAQ,GAAG,OAAO;AAC/B;","names":[]}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SelectionCard
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-X5EG4EFP.js";
|
|
5
5
|
import {
|
|
6
6
|
useSectionScroll
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BNQ5O6LE.js";
|
|
8
8
|
import {
|
|
9
9
|
useWizardStore
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WF6RM73R.js";
|
|
11
11
|
import {
|
|
12
12
|
DEFAULT_SCRATCH_DOMAINS
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
14
14
|
import {
|
|
15
15
|
init_esm_shims
|
|
16
16
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -108,4 +108,4 @@ var StackSelection = ({
|
|
|
108
108
|
export {
|
|
109
109
|
StackSelection
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-BMJZBLP7.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SCROLL_VIEWPORT
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
5
5
|
import {
|
|
6
6
|
init_esm_shims
|
|
7
7
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -71,4 +71,4 @@ export {
|
|
|
71
71
|
useSectionScroll,
|
|
72
72
|
computeRowScrollTop
|
|
73
73
|
};
|
|
74
|
-
//# sourceMappingURL=chunk-
|
|
74
|
+
//# sourceMappingURL=chunk-BNQ5O6LE.js.map
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
verbose,
|
|
9
9
|
warn,
|
|
10
10
|
writeFile
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-LWXRUR6B.js";
|
|
12
12
|
import {
|
|
13
13
|
MAX_PLUGIN_FILE_SIZE
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6OWHQ7HM.js";
|
|
15
15
|
import {
|
|
16
16
|
init_esm_shims
|
|
17
17
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -129,4 +129,4 @@ export {
|
|
|
129
129
|
writeMarketplace,
|
|
130
130
|
getMarketplaceStats
|
|
131
131
|
};
|
|
132
|
-
//# sourceMappingURL=chunk-
|
|
132
|
+
//# sourceMappingURL=chunk-C577AJE7.js.map
|