@agents-inc/cli 0.74.13 → 0.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/{chunk-SXGBPQY6.js → chunk-2I5SXGXR.js} +2 -2
- package/dist/{chunk-MYSIW4HY.js → chunk-36YW5E7G.js} +5 -5
- package/dist/{chunk-T5DJCIUP.js → chunk-3REKTRAN.js} +2 -2
- package/dist/{chunk-ICJV3JJF.js → chunk-6F3CZLD6.js} +32 -73
- package/dist/chunk-6F3CZLD6.js.map +1 -0
- package/dist/{chunk-GHBZ7NUI.js → chunk-7NACNRFG.js} +21 -9
- package/dist/chunk-7NACNRFG.js.map +1 -0
- package/dist/{chunk-RKZFLLER.js → chunk-7PMFIL5L.js} +3 -3
- package/dist/{chunk-TKNPMYKJ.js → chunk-7PZFDI46.js} +4 -4
- package/dist/{chunk-NKKYTCBH.js → chunk-7XUKTYVD.js} +706 -327
- package/dist/chunk-7XUKTYVD.js.map +1 -0
- package/dist/{chunk-4EPFKZB5.js → chunk-AE2QHAFO.js} +23 -17
- package/dist/chunk-AE2QHAFO.js.map +1 -0
- package/dist/{chunk-OZ4DXMRF.js → chunk-CBJTSEI2.js} +5 -5
- package/dist/{chunk-HT5KOOUQ.js → chunk-CCSU4R65.js} +3 -4
- package/dist/chunk-CCSU4R65.js.map +1 -0
- package/dist/{chunk-W6NWOYMS.js → chunk-CKU7FJNV.js} +4 -4
- package/dist/{chunk-SASGCSBZ.js → chunk-EEZSCHS2.js} +9 -9
- package/dist/{chunk-CBXMOWQY.js → chunk-ERHTXNIF.js} +3 -3
- package/dist/{chunk-2YFC7IJ6.js → chunk-EWBNSS5Y.js} +6 -6
- package/dist/{chunk-TQLDQ3XZ.js → chunk-EYFBODHL.js} +2 -2
- package/dist/{chunk-AUNBGZS4.js → chunk-FFMWFEUH.js} +2 -2
- package/dist/{chunk-EGMQ3SXN.js → chunk-FMYAYX6W.js} +1 -1
- package/dist/chunk-FMYAYX6W.js.map +1 -0
- package/dist/{chunk-7Q6RMYR3.js → chunk-I2SUTL7S.js} +5 -5
- package/dist/{chunk-RRBWNEG3.js → chunk-I534EWJQ.js} +3 -3
- package/dist/{chunk-2PZ7LBFT.js → chunk-IDN2OZJY.js} +2 -2
- package/dist/{chunk-NG2GGK6P.js → chunk-JWMYAJHD.js} +2974 -3454
- package/dist/chunk-JWMYAJHD.js.map +1 -0
- package/dist/{chunk-MWGDG4QN.js → chunk-K63OEZW7.js} +2 -2
- package/dist/{chunk-BM5Y6LIC.js → chunk-KPRCP3MZ.js} +3 -3
- package/dist/{chunk-746DCNGM.js → chunk-LO5QGAP2.js} +5 -5
- package/dist/{chunk-IJNNVCS4.js → chunk-M4ZDKHJV.js} +3 -3
- package/dist/{chunk-IJNNVCS4.js.map → chunk-M4ZDKHJV.js.map} +1 -1
- package/dist/{chunk-CXRVM7BA.js → chunk-M76LNKMY.js} +2 -2
- package/dist/{chunk-WF5PMBIR.js → chunk-MLXAZODL.js} +2 -2
- package/dist/{chunk-UFKDY45I.js → chunk-NWW3OJH5.js} +3 -3
- package/dist/{chunk-ARGCINJC.js → chunk-O5CPXIC4.js} +7 -9
- package/dist/chunk-O5CPXIC4.js.map +1 -0
- package/dist/{chunk-A5TTDOP4.js → chunk-ODVQXXEO.js} +45 -16
- package/dist/{chunk-A5TTDOP4.js.map → chunk-ODVQXXEO.js.map} +1 -1
- package/dist/{chunk-EWGFIBBU.js → chunk-PRG7PKZM.js} +5 -5
- package/dist/{chunk-SRIH4U5Y.js → chunk-Q4PJSAMP.js} +33 -13
- package/dist/chunk-Q4PJSAMP.js.map +1 -0
- package/dist/{chunk-Q3F36QZZ.js → chunk-R7F5YQMI.js} +2 -2
- package/dist/{chunk-JQSJH72Q.js → chunk-S6DKM6MJ.js} +6 -6
- package/dist/{chunk-XMLCXRTS.js → chunk-SQ7WINEU.js} +3 -3
- package/dist/{chunk-LVNNP7T4.js → chunk-UBNHVBSV.js} +4 -4
- package/dist/{chunk-NPMGVQM4.js → chunk-VQV3DSHD.js} +6 -6
- package/dist/{chunk-ZU7AOE3X.js → chunk-WMMU5FOO.js} +15 -16
- package/dist/chunk-WMMU5FOO.js.map +1 -0
- package/dist/{chunk-4CRWKTNQ.js → chunk-WN2TUP4M.js} +4 -10
- package/dist/chunk-WN2TUP4M.js.map +1 -0
- package/dist/{chunk-6W4H2K3Z.js → chunk-WS3TL2AO.js} +35 -21
- package/dist/chunk-WS3TL2AO.js.map +1 -0
- package/dist/{chunk-7X4F4HCO.js → chunk-WZ5S4LGX.js} +6 -6
- package/dist/{chunk-IJLAVOKZ.js → chunk-XYZ7B5BY.js} +2 -2
- package/dist/commands/build/marketplace.js +5 -5
- package/dist/commands/build/plugins.js +9 -9
- package/dist/commands/build/stack.js +9 -9
- package/dist/commands/compile.js +10 -10
- package/dist/commands/config/index.js +9 -9
- package/dist/commands/config/path.js +8 -8
- package/dist/commands/config/show.js +9 -9
- package/dist/commands/diff.js +8 -8
- package/dist/commands/doctor.js +8 -8
- package/dist/commands/edit.js +33 -33
- package/dist/commands/eject.js +8 -8
- package/dist/commands/import/skill.js +9 -9
- package/dist/commands/info.js +9 -17
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +33 -33
- package/dist/commands/list.js +8 -8
- package/dist/commands/new/agent.js +9 -9
- package/dist/commands/new/marketplace.js +10 -10
- package/dist/commands/new/skill.js +9 -9
- package/dist/commands/outdated.js +8 -8
- package/dist/commands/search.js +14 -15
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +9 -9
- package/dist/commands/update.js +10 -10
- package/dist/commands/validate.js +9 -9
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/skill-search/skill-search.js +3 -3
- package/dist/components/wizard/category-grid.js +4 -4
- package/dist/components/wizard/category-grid.test.js +18 -19
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +4 -4
- package/dist/components/wizard/checkbox-grid.test.js +4 -4
- package/dist/components/wizard/domain-selection.js +13 -13
- 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 +3 -3
- package/dist/components/wizard/search-modal.test.js +3 -3
- package/dist/components/wizard/section-progress.js +2 -2
- package/dist/components/wizard/section-progress.test.js +2 -2
- package/dist/components/wizard/selection-card.js +2 -2
- package/dist/components/wizard/source-grid.js +6 -6
- package/dist/components/wizard/source-grid.test.js +15 -15
- package/dist/components/wizard/stack-selection.js +11 -11
- package/dist/components/wizard/step-agents.js +12 -12
- package/dist/components/wizard/step-agents.test.js +15 -15
- package/dist/components/wizard/step-build.js +12 -12
- package/dist/components/wizard/step-build.test.js +14 -14
- package/dist/components/wizard/step-confirm.js +5 -5
- package/dist/components/wizard/step-confirm.test.js +11 -11
- package/dist/components/wizard/step-refine.js +2 -2
- package/dist/components/wizard/step-refine.test.js +2 -2
- package/dist/components/wizard/step-settings.js +10 -10
- package/dist/components/wizard/step-settings.test.js +13 -13
- package/dist/components/wizard/step-sources.js +14 -14
- package/dist/components/wizard/step-sources.test.js +17 -17
- package/dist/components/wizard/step-stack.js +16 -16
- package/dist/components/wizard/step-stack.test.js +17 -17
- package/dist/components/wizard/wizard-layout.js +11 -11
- 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 +30 -30
- package/dist/config-exports.js +1 -1
- package/dist/hooks/init.js +33 -33
- package/dist/{loader-NHUCFMFQ.js → loader-7RQ4G4TH.js} +5 -5
- package/dist/plugins/dummy-skill/.claude-plugin/.content-hash +1 -0
- package/dist/plugins/dummy-skill/.claude-plugin/plugin.json +13 -0
- package/dist/{source-loader-42GVUFZA.js → source-loader-CXCIDGWV.js} +8 -8
- package/dist/source-manager-TPLO2DVS.js +19 -0
- package/dist/src/agents/_templates/agent.liquid +24 -0
- package/dist/src/agents/_templates/methodologies/anti-over-engineering.liquid +121 -0
- package/dist/src/agents/_templates/methodologies/context-management.liquid +162 -0
- package/dist/src/agents/_templates/methodologies/improvement-protocol.liquid +150 -0
- package/dist/src/agents/_templates/methodologies/investigation-requirements.liquid +49 -0
- package/dist/src/agents/_templates/methodologies/success-criteria.liquid +111 -0
- package/dist/src/agents/_templates/methodologies/write-verification.liquid +43 -0
- package/dist/src/agents/meta/agent-summoner/workflow.md +2 -2
- package/dist/src/agents/meta/skill-summoner/workflow.md +48 -3
- package/dist/stores/wizard-store.js +8 -8
- package/dist/stores/wizard-store.test.js +36 -36
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/_templates/agent.liquid +24 -0
- package/src/agents/_templates/methodologies/anti-over-engineering.liquid +121 -0
- package/src/agents/_templates/methodologies/context-management.liquid +162 -0
- package/src/agents/_templates/methodologies/improvement-protocol.liquid +150 -0
- package/src/agents/_templates/methodologies/investigation-requirements.liquid +49 -0
- package/src/agents/_templates/methodologies/success-criteria.liquid +111 -0
- package/src/agents/_templates/methodologies/write-verification.liquid +43 -0
- package/src/agents/meta/agent-summoner/workflow.md +2 -2
- package/src/agents/meta/skill-summoner/workflow.md +48 -3
- package/src/schemas/custom-metadata.schema.json +0 -7
- package/src/schemas/metadata.schema.json +0 -7
- package/dist/chunk-4CRWKTNQ.js.map +0 -1
- package/dist/chunk-4EPFKZB5.js.map +0 -1
- package/dist/chunk-6W4H2K3Z.js.map +0 -1
- package/dist/chunk-ARGCINJC.js.map +0 -1
- package/dist/chunk-EGMQ3SXN.js.map +0 -1
- package/dist/chunk-GHBZ7NUI.js.map +0 -1
- package/dist/chunk-HT5KOOUQ.js.map +0 -1
- package/dist/chunk-ICJV3JJF.js.map +0 -1
- package/dist/chunk-NG2GGK6P.js.map +0 -1
- package/dist/chunk-NKKYTCBH.js.map +0 -1
- package/dist/chunk-SRIH4U5Y.js.map +0 -1
- package/dist/chunk-ZU7AOE3X.js.map +0 -1
- package/dist/source-manager-WRZBOTEH.js +0 -19
- /package/dist/{chunk-SXGBPQY6.js.map → chunk-2I5SXGXR.js.map} +0 -0
- /package/dist/{chunk-MYSIW4HY.js.map → chunk-36YW5E7G.js.map} +0 -0
- /package/dist/{chunk-T5DJCIUP.js.map → chunk-3REKTRAN.js.map} +0 -0
- /package/dist/{chunk-RKZFLLER.js.map → chunk-7PMFIL5L.js.map} +0 -0
- /package/dist/{chunk-TKNPMYKJ.js.map → chunk-7PZFDI46.js.map} +0 -0
- /package/dist/{chunk-OZ4DXMRF.js.map → chunk-CBJTSEI2.js.map} +0 -0
- /package/dist/{chunk-W6NWOYMS.js.map → chunk-CKU7FJNV.js.map} +0 -0
- /package/dist/{chunk-SASGCSBZ.js.map → chunk-EEZSCHS2.js.map} +0 -0
- /package/dist/{chunk-CBXMOWQY.js.map → chunk-ERHTXNIF.js.map} +0 -0
- /package/dist/{chunk-2YFC7IJ6.js.map → chunk-EWBNSS5Y.js.map} +0 -0
- /package/dist/{chunk-TQLDQ3XZ.js.map → chunk-EYFBODHL.js.map} +0 -0
- /package/dist/{chunk-AUNBGZS4.js.map → chunk-FFMWFEUH.js.map} +0 -0
- /package/dist/{chunk-7Q6RMYR3.js.map → chunk-I2SUTL7S.js.map} +0 -0
- /package/dist/{chunk-RRBWNEG3.js.map → chunk-I534EWJQ.js.map} +0 -0
- /package/dist/{chunk-2PZ7LBFT.js.map → chunk-IDN2OZJY.js.map} +0 -0
- /package/dist/{chunk-MWGDG4QN.js.map → chunk-K63OEZW7.js.map} +0 -0
- /package/dist/{chunk-BM5Y6LIC.js.map → chunk-KPRCP3MZ.js.map} +0 -0
- /package/dist/{chunk-746DCNGM.js.map → chunk-LO5QGAP2.js.map} +0 -0
- /package/dist/{chunk-CXRVM7BA.js.map → chunk-M76LNKMY.js.map} +0 -0
- /package/dist/{chunk-WF5PMBIR.js.map → chunk-MLXAZODL.js.map} +0 -0
- /package/dist/{chunk-UFKDY45I.js.map → chunk-NWW3OJH5.js.map} +0 -0
- /package/dist/{chunk-EWGFIBBU.js.map → chunk-PRG7PKZM.js.map} +0 -0
- /package/dist/{chunk-Q3F36QZZ.js.map → chunk-R7F5YQMI.js.map} +0 -0
- /package/dist/{chunk-JQSJH72Q.js.map → chunk-S6DKM6MJ.js.map} +0 -0
- /package/dist/{chunk-XMLCXRTS.js.map → chunk-SQ7WINEU.js.map} +0 -0
- /package/dist/{chunk-LVNNP7T4.js.map → chunk-UBNHVBSV.js.map} +0 -0
- /package/dist/{chunk-NPMGVQM4.js.map → chunk-VQV3DSHD.js.map} +0 -0
- /package/dist/{chunk-7X4F4HCO.js.map → chunk-WZ5S4LGX.js.map} +0 -0
- /package/dist/{chunk-IJLAVOKZ.js.map → chunk-XYZ7B5BY.js.map} +0 -0
- /package/dist/{loader-NHUCFMFQ.js.map → loader-7RQ4G4TH.js.map} +0 -0
- /package/dist/{source-loader-42GVUFZA.js.map → source-loader-CXCIDGWV.js.map} +0 -0
- /package/dist/{source-manager-WRZBOTEH.js.map → source-manager-TPLO2DVS.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,43 @@ Each release has detailed notes in its own file under [`changelogs/`](./changelo
|
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
8
8
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
9
9
|
|
|
10
|
+
## [0.76.0] - 2026-03-16
|
|
11
|
+
|
|
12
|
+
**Shared meta category consolidation, web-tooling category**
|
|
13
|
+
|
|
14
|
+
- Merge `shared-methodology` + `shared-research` + `shared-reviewing` → `shared-meta`
|
|
15
|
+
- Add `web-tooling` category for build tools (Vite, Webpack)
|
|
16
|
+
- Update all 9 default stacks and generated types
|
|
17
|
+
|
|
18
|
+
See [changelogs/0.76.0.md](./changelogs/0.76.0.md) for full details.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## [0.75.1] - 2026-03-16
|
|
23
|
+
|
|
24
|
+
**Meta-framework ID rename, tags removal, schema reference**
|
|
25
|
+
|
|
26
|
+
- Rename meta-framework skill IDs for category consistency (web-framework-_ → web-meta-framework-_)
|
|
27
|
+
- Remove `tags` field from skill metadata entirely (D-103)
|
|
28
|
+
- Add `$schema` reference to generated metadata.yaml (D-108)
|
|
29
|
+
|
|
30
|
+
See [changelogs/0.75.1.md](./changelogs/0.75.1.md) for full details.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## [0.75.0] - 2026-03-16
|
|
35
|
+
|
|
36
|
+
**Framework restructuring, new stacks and categories**
|
|
37
|
+
|
|
38
|
+
- Split web-framework into base + meta-framework categories (D-38)
|
|
39
|
+
- Required-by label and block-deselect for meta-frameworks (D-39)
|
|
40
|
+
- 3 new stacks: T3, SvelteKit, Astro (9 total)
|
|
41
|
+
- 9 new skills: Svelte, SvelteKit, Astro, NextAuth, NestJS, Supabase, AI SDK, Clerk, MongoDB
|
|
42
|
+
|
|
43
|
+
See [changelogs/0.75.0.md](./changelogs/0.75.0.md) for full details.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
10
47
|
## [0.74.13] - 2026-03-15
|
|
11
48
|
|
|
12
49
|
**Wizard UI polish, source choice flag, e2e test updates**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CLI_COLORS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FMYAYX6W.js";
|
|
5
5
|
import {
|
|
6
6
|
init_esm_shims
|
|
7
7
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -81,4 +81,4 @@ export {
|
|
|
81
81
|
formatStepLabel,
|
|
82
82
|
WizardTabs
|
|
83
83
|
};
|
|
84
|
-
//# sourceMappingURL=chunk-
|
|
84
|
+
//# sourceMappingURL=chunk-2I5SXGXR.js.map
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getDomainDisplayName,
|
|
4
4
|
orderDomains
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UBNHVBSV.js";
|
|
6
6
|
import {
|
|
7
7
|
CheckboxGrid
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ERHTXNIF.js";
|
|
9
9
|
import {
|
|
10
10
|
useWizardStore
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-PRG7PKZM.js";
|
|
12
12
|
import {
|
|
13
13
|
matrix,
|
|
14
14
|
typedEntries
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-JWMYAJHD.js";
|
|
16
16
|
import {
|
|
17
17
|
init_esm_shims
|
|
18
18
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -63,4 +63,4 @@ var DomainSelection = () => {
|
|
|
63
63
|
export {
|
|
64
64
|
DomainSelection
|
|
65
65
|
};
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-36YW5E7G.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CLI_COLORS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FMYAYX6W.js";
|
|
5
5
|
import {
|
|
6
6
|
init_esm_shims
|
|
7
7
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -78,4 +78,4 @@ var cliTheme = extendTheme(defaultTheme, {
|
|
|
78
78
|
export {
|
|
79
79
|
cliTheme
|
|
80
80
|
};
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-3REKTRAN.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
FRAMEWORK_CATEGORY
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-M4ZDKHJV.js";
|
|
5
5
|
import {
|
|
6
6
|
SKILLS,
|
|
7
7
|
TEST_CATEGORIES,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
createTestSkill,
|
|
16
16
|
renderSkillMd,
|
|
17
17
|
testSkillToResolvedSkill
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-WMMU5FOO.js";
|
|
19
19
|
import {
|
|
20
20
|
init_esm_shims
|
|
21
21
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -35,52 +35,38 @@ var VITEST_SINGLE_FILE_SKILL = {
|
|
|
35
35
|
};
|
|
36
36
|
var METHODOLOGY_TEST_SKILLS = [
|
|
37
37
|
{
|
|
38
|
-
id: "meta-
|
|
39
|
-
slug: "
|
|
38
|
+
id: "shared-meta-reviewing",
|
|
39
|
+
slug: "reviewing",
|
|
40
40
|
displayName: "Anti Over-Engineering",
|
|
41
41
|
description: "Surgical implementation, not architectural innovation",
|
|
42
|
-
category: "shared-
|
|
42
|
+
category: "shared-meta",
|
|
43
43
|
author: "@test",
|
|
44
|
-
domain: "shared"
|
|
45
|
-
tags: ["methodology", "foundational"]
|
|
44
|
+
domain: "shared"
|
|
46
45
|
}
|
|
47
46
|
];
|
|
48
47
|
var reactSkill = createTestSkill(
|
|
49
48
|
"web-framework-react",
|
|
50
49
|
"React framework for building user interfaces",
|
|
51
|
-
{
|
|
52
|
-
tags: ["react", "web", "ui"]
|
|
53
|
-
}
|
|
50
|
+
{}
|
|
54
51
|
);
|
|
55
|
-
var zustandSkill = createTestSkill("web-state-zustand", "Bear necessities state management"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
var vitestSkill = createTestSkill("web-testing-vitest", "Next generation testing framework", {
|
|
59
|
-
tags: ["testing", "vitest", "unit"]
|
|
60
|
-
});
|
|
61
|
-
var honoSkill = createTestSkill("api-framework-hono", "Lightweight web framework for the edge", {
|
|
62
|
-
tags: ["api", "hono", "edge"]
|
|
63
|
-
});
|
|
52
|
+
var zustandSkill = createTestSkill("web-state-zustand", "Bear necessities state management");
|
|
53
|
+
var vitestSkill = createTestSkill("web-testing-vitest", "Next generation testing framework");
|
|
54
|
+
var honoSkill = createTestSkill("api-framework-hono", "Lightweight web framework for the edge");
|
|
64
55
|
var vueSkill = createTestSkill(
|
|
65
56
|
"web-framework-vue-composition-api",
|
|
66
57
|
"Progressive JavaScript framework",
|
|
67
|
-
{
|
|
68
|
-
tags: ["vue", "web"]
|
|
69
|
-
}
|
|
58
|
+
{}
|
|
70
59
|
);
|
|
71
60
|
var scssSkill = createTestSkill("web-styling-scss-modules", "CSS Modules with SCSS", {
|
|
72
|
-
displayName: "SCSS Modules"
|
|
73
|
-
tags: ["css", "scss"]
|
|
74
|
-
});
|
|
75
|
-
var drizzleSkill = createTestSkill("api-database-drizzle", "TypeScript ORM for SQL databases", {
|
|
76
|
-
tags: ["database", "orm"]
|
|
61
|
+
displayName: "SCSS Modules"
|
|
77
62
|
});
|
|
63
|
+
var drizzleSkill = createTestSkill("api-database-drizzle", "TypeScript ORM for SQL databases");
|
|
78
64
|
var EXTRA_DOMAIN_TEST_SKILLS = [vueSkill, scssSkill, drizzleSkill];
|
|
79
65
|
var COMPILE_LOCAL_SKILL = createTestSkill(
|
|
80
66
|
// Boundary cast: fictional skill ID for testing local skill compilation
|
|
81
67
|
"web-tooling-local-skill",
|
|
82
68
|
"A local project skill",
|
|
83
|
-
{ slug: "tooling", displayName: "Local Skill"
|
|
69
|
+
{ slug: "tooling", displayName: "Local Skill" }
|
|
84
70
|
);
|
|
85
71
|
var DEFAULT_TEST_SKILLS = [reactSkill, zustandSkill, vitestSkill, honoSkill];
|
|
86
72
|
var PIPELINE_TEST_SKILLS = [
|
|
@@ -94,8 +80,7 @@ var DOCKER_TOOLING_SKILL = createTestSkill(
|
|
|
94
80
|
{
|
|
95
81
|
slug: "tooling",
|
|
96
82
|
displayName: "Docker",
|
|
97
|
-
domain: "shared"
|
|
98
|
-
tags: ["docker", "devops", "containers"]
|
|
83
|
+
domain: "shared"
|
|
99
84
|
}
|
|
100
85
|
);
|
|
101
86
|
var CI_CD_SKILLS = [
|
|
@@ -104,8 +89,7 @@ var CI_CD_SKILLS = [
|
|
|
104
89
|
slug: "github-actions",
|
|
105
90
|
displayName: "GitHub Actions",
|
|
106
91
|
category: "infra-ci-cd",
|
|
107
|
-
domain: "shared"
|
|
108
|
-
tags: ["ci-cd", "github-actions"]
|
|
92
|
+
domain: "shared"
|
|
109
93
|
}),
|
|
110
94
|
// Boundary cast: fictional skill ID for testing CI/CD skills
|
|
111
95
|
createTestSkill("infra-ci-cd-gitlab-ci", "gitlab-ci CI/CD pipeline", {
|
|
@@ -113,20 +97,18 @@ var CI_CD_SKILLS = [
|
|
|
113
97
|
slug: "gitlab-ci",
|
|
114
98
|
displayName: "GitLab CI",
|
|
115
99
|
category: "infra-ci-cd",
|
|
116
|
-
domain: "shared"
|
|
117
|
-
tags: ["ci-cd", "gitlab-ci"]
|
|
100
|
+
domain: "shared"
|
|
118
101
|
})
|
|
119
102
|
];
|
|
120
103
|
var DATADOG_OBSERVABILITY_SKILL = createTestSkill(
|
|
121
104
|
// Boundary cast: fictional skill ID for testing observability skills
|
|
122
105
|
"api-observability-datadog",
|
|
123
106
|
"Datadog APM integration",
|
|
124
|
-
{
|
|
107
|
+
{}
|
|
125
108
|
);
|
|
126
|
-
function contentSkill(id, description,
|
|
109
|
+
function contentSkill(id, description, body, author) {
|
|
127
110
|
return createTestSkill(id, description, {
|
|
128
111
|
...author ? { author } : {},
|
|
129
|
-
tags,
|
|
130
112
|
content: renderSkillMd(id, description, body)
|
|
131
113
|
});
|
|
132
114
|
}
|
|
@@ -134,25 +116,21 @@ var SWITCHABLE_SKILLS = [
|
|
|
134
116
|
contentSkill(
|
|
135
117
|
"web-framework-react",
|
|
136
118
|
"React framework for building user interfaces",
|
|
137
|
-
["react", "web"],
|
|
138
119
|
"# React (Marketplace Version)\n\nReact is a JavaScript library for building user interfaces.\nUse component-based architecture with JSX."
|
|
139
120
|
),
|
|
140
121
|
contentSkill(
|
|
141
122
|
"web-state-zustand",
|
|
142
123
|
"Bear necessities state management",
|
|
143
|
-
["state", "zustand"],
|
|
144
124
|
"# Zustand (Marketplace Version)\n\nZustand is a minimal state management library for React."
|
|
145
125
|
),
|
|
146
126
|
contentSkill(
|
|
147
127
|
"api-framework-hono",
|
|
148
128
|
"Lightweight web framework for the edge",
|
|
149
|
-
["api", "hono"],
|
|
150
129
|
"# Hono (Marketplace Version)\n\nHono is a fast web framework for the edge."
|
|
151
130
|
),
|
|
152
131
|
contentSkill(
|
|
153
132
|
"web-testing-vitest",
|
|
154
133
|
"Next generation testing framework",
|
|
155
|
-
["testing", "vitest"],
|
|
156
134
|
"# Vitest (Marketplace Version)\n\nVitest is a fast unit test framework powered by Vite."
|
|
157
135
|
)
|
|
158
136
|
];
|
|
@@ -160,40 +138,31 @@ var LOCAL_SKILL_VARIANTS = [
|
|
|
160
138
|
contentSkill(
|
|
161
139
|
"web-framework-react",
|
|
162
140
|
"React framework (local customized version)",
|
|
163
|
-
["react", "web"],
|
|
164
141
|
"# React (Local Version)\n\nThis is my customized React skill with project-specific patterns.",
|
|
165
142
|
"@local-user"
|
|
166
143
|
),
|
|
167
144
|
contentSkill(
|
|
168
145
|
"web-state-zustand",
|
|
169
146
|
"Zustand state management (local customized version)",
|
|
170
|
-
["state", "zustand"],
|
|
171
147
|
"# Zustand (Local Version)\n\nMy customized Zustand patterns with project-specific stores.",
|
|
172
148
|
"@local-user"
|
|
173
149
|
)
|
|
174
150
|
];
|
|
175
151
|
var RESOLUTION_PIPELINE_SKILLS = [
|
|
176
|
-
createTestSkill("web-framework-react", "React framework (public source)",
|
|
177
|
-
tags: ["react", "web"]
|
|
178
|
-
}),
|
|
152
|
+
createTestSkill("web-framework-react", "React framework (public source)"),
|
|
179
153
|
createTestSkill("api-framework-hono", "Hono framework (acme source)", {
|
|
180
|
-
author: "@acme"
|
|
181
|
-
tags: ["api", "hono"]
|
|
154
|
+
author: "@acme"
|
|
182
155
|
}),
|
|
183
156
|
// Boundary cast: fictional skill ID for testing multi-source resolution
|
|
184
157
|
createTestSkill("web-animation-framer", "Framer Motion (internal source)", {
|
|
185
158
|
slug: "framer-motion",
|
|
186
159
|
displayName: "Framer Motion",
|
|
187
|
-
author: "@internal"
|
|
188
|
-
tags: ["animation"]
|
|
160
|
+
author: "@internal"
|
|
189
161
|
}),
|
|
190
162
|
createTestSkill("api-database-drizzle", "Drizzle ORM (acme source)", {
|
|
191
|
-
author: "@acme"
|
|
192
|
-
tags: ["database"]
|
|
163
|
+
author: "@acme"
|
|
193
164
|
}),
|
|
194
|
-
createTestSkill("web-testing-vitest", "Vitest testing (public source)"
|
|
195
|
-
tags: ["testing"]
|
|
196
|
-
})
|
|
165
|
+
createTestSkill("web-testing-vitest", "Vitest testing (public source)")
|
|
197
166
|
];
|
|
198
167
|
var ALL_TEST_SKILLS = [
|
|
199
168
|
...DEFAULT_TEST_SKILLS,
|
|
@@ -210,8 +179,7 @@ var INIT_TEST_SKILLS = DEFAULT_TEST_SKILLS.filter(
|
|
|
210
179
|
);
|
|
211
180
|
var REACT_EXTRACTED = createMockExtractedSkill("web-framework-react", {
|
|
212
181
|
description: "React framework",
|
|
213
|
-
author: "@vince"
|
|
214
|
-
tags: ["react"]
|
|
182
|
+
author: "@vince"
|
|
215
183
|
});
|
|
216
184
|
var REACT_EXTRACTED_BASIC = createMockExtractedSkill("web-framework-react", {
|
|
217
185
|
description: "React"
|
|
@@ -286,18 +254,9 @@ var CATEGORY_GRID_SKILLS = [
|
|
|
286
254
|
{ id: "web-framework-vue-composition-api", displayName: "Vue", category: "web-framework" },
|
|
287
255
|
{ id: "web-framework-angular-standalone", displayName: "Angular", category: "web-framework" },
|
|
288
256
|
{ id: "web-framework-solidjs", displayName: "SolidJS", category: "web-framework" },
|
|
289
|
-
{ id: "web-framework-nuxt", displayName: "Nuxt", category: "web-framework" },
|
|
290
|
-
{ id: "web-framework-remix", displayName: "Remix", category: "web-framework" },
|
|
291
|
-
{
|
|
292
|
-
id: "web-framework-nextjs-app-router",
|
|
293
|
-
displayName: "Next.js App Router",
|
|
294
|
-
category: "web-framework"
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
id: "web-framework-nextjs-server-actions",
|
|
298
|
-
displayName: "Next.js Server Actions",
|
|
299
|
-
category: "web-framework"
|
|
300
|
-
},
|
|
257
|
+
{ id: "web-meta-framework-nuxt", displayName: "Nuxt", category: "web-meta-framework" },
|
|
258
|
+
{ id: "web-meta-framework-remix", displayName: "Remix", category: "web-meta-framework" },
|
|
259
|
+
{ id: "web-meta-framework-nextjs", displayName: "Next.js", category: "web-meta-framework" },
|
|
301
260
|
{ id: "web-styling-scss-modules", displayName: "SCSS Modules", category: "web-styling" },
|
|
302
261
|
{ id: "web-styling-tailwind", displayName: "Tailwind", category: "web-styling" },
|
|
303
262
|
{ id: "web-styling-cva", displayName: "CVA", category: "web-styling" },
|
|
@@ -457,18 +416,18 @@ var ALL_SKILLS_WEB_AND_API_MATRIX = createMockMatrix(...Object.values(SKILLS), {
|
|
|
457
416
|
});
|
|
458
417
|
var ALL_SKILLS_METHODOLOGY_MATRIX = createMockMatrix(...Object.values(SKILLS), {
|
|
459
418
|
categories: {
|
|
460
|
-
"shared-
|
|
419
|
+
"shared-meta": { domain: "shared" }
|
|
461
420
|
}
|
|
462
421
|
});
|
|
463
422
|
var ALL_SKILLS_METHODOLOGY_BARE_MATRIX = createMockMatrix(...Object.values(SKILLS), {
|
|
464
423
|
categories: {
|
|
465
|
-
"shared-
|
|
424
|
+
"shared-meta": {}
|
|
466
425
|
}
|
|
467
426
|
});
|
|
468
427
|
var ALL_SKILLS_MULTI_DOMAIN_MATRIX = createMockMatrix(...Object.values(SKILLS), {
|
|
469
428
|
categories: {
|
|
470
429
|
"web-framework": { domain: "web" },
|
|
471
|
-
"shared-
|
|
430
|
+
"shared-meta": { domain: "shared" },
|
|
472
431
|
"api-api": { domain: "api" }
|
|
473
432
|
}
|
|
474
433
|
});
|
|
@@ -766,4 +725,4 @@ export {
|
|
|
766
725
|
ALL_SKILLS_MULTI_DOMAIN_MATRIX,
|
|
767
726
|
REACT_HONO_FRAMEWORK_API_MATRIX
|
|
768
727
|
};
|
|
769
|
-
//# sourceMappingURL=chunk-
|
|
728
|
+
//# sourceMappingURL=chunk-6F3CZLD6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/lib/__tests__/mock-data/mock-matrices.ts","../src/cli/lib/__tests__/mock-data/mock-skills.ts"],"sourcesContent":["// Shared matrix configs and compile configs for test files.\n// Uses createMockMatrixConfig/createMockCompileConfig from helpers.ts.\n\nimport { groupBy, mapValues } from \"remeda\";\n\nimport {\n createMockMatrixConfig,\n createMockCompileConfig,\n createMockCategory,\n createMockMatrix,\n createMockMultiSourceSkill,\n createMockSkill,\n testSkillToResolvedSkill,\n} from \"../helpers.js\";\nimport { SKILLS, TEST_CATEGORIES } from \"../test-fixtures.js\";\nimport { FRAMEWORK_CATEGORY, MULTI_SOURCE_CATEGORIES } from \"./mock-categories.js\";\nimport {\n CATEGORY_GRID_SKILLS,\n HEALTH_ALL_REFS_RESOLVED_SKILL,\n HEALTH_MULTIPLE_UNRESOLVED_REFS_SKILL,\n HEALTH_ORPHAN_SKILL,\n HEALTH_PARTIAL_UNRESOLVED_REQUIRES_SKILL,\n HEALTH_UNRESOLVED_COMPATIBLE_WITH_SKILL,\n HEALTH_UNRESOLVED_CONFLICTS_WITH_SKILL,\n HEALTH_UNRESOLVED_REQUIRES_SKILL,\n HEALTH_ZUSTAND_RECOMMENDED,\n MULTI_SOURCE_PUBLIC_SKILLS,\n MULTI_SOURCE_ACME_SKILLS,\n MULTI_SOURCE_INTERNAL_SKILLS,\n PIPELINE_TEST_SKILLS,\n} from \"./mock-skills.js\";\nimport type { MultiSourceSkillEntry } from \"./mock-skills.js\";\nimport { PUBLIC_SOURCE, ACME_SOURCE, INTERNAL_SOURCE } from \"./mock-sources.js\";\nimport type {\n Category,\n CategoryDefinition,\n CategoryPath,\n MergedSkillsMatrix,\n SkillId,\n SkillSlug,\n SkillSource,\n} from \"../../../types\";\n\n// ---------------------------------------------------------------------------\n// Canonical matrix shapes — use these instead of inline createMockMatrix() calls\n// ---------------------------------------------------------------------------\n\nexport const EMPTY_MATRIX = createMockMatrix();\nexport const SINGLE_REACT_MATRIX = createMockMatrix(SKILLS.react);\nexport const WEB_PAIR_MATRIX = createMockMatrix(SKILLS.react, SKILLS.zustand);\nexport const FULLSTACK_PAIR_MATRIX = createMockMatrix(SKILLS.react, SKILLS.hono);\nexport const WEB_TRIO_MATRIX = createMockMatrix(SKILLS.react, SKILLS.zustand, SKILLS.vitest);\nexport const FULLSTACK_TRIO_MATRIX = createMockMatrix(SKILLS.react, SKILLS.hono, SKILLS.vitest);\nexport const VITEST_REACT_HONO_MATRIX = createMockMatrix(SKILLS.vitest, SKILLS.react, SKILLS.hono);\nexport const REACT_SCSS_MATRIX = createMockMatrix(SKILLS.react, SKILLS.scss);\nexport const REACT_SCSS_HONO_MATRIX = createMockMatrix(SKILLS.react, SKILLS.scss, SKILLS.hono);\nexport const SCSS_HONO_REACT_MATRIX = createMockMatrix(SKILLS.scss, SKILLS.hono, SKILLS.react);\nexport const HONO_REACT_MATRIX = createMockMatrix(SKILLS.hono, SKILLS.react);\nexport const REACT_ZUSTAND_HONO_MATRIX = createMockMatrix(\n SKILLS.react,\n SKILLS.zustand,\n SKILLS.hono,\n);\n\nexport const CATEGORY_GRID_MATRIX = createMockMatrix(\n ...CATEGORY_GRID_SKILLS.map(({ id, displayName, category }) =>\n createMockSkill(id, { displayName, category }),\n ),\n);\n\n// ---------------------------------------------------------------------------\n// All-skills matrices with category overrides — for wizard store tests\n// ---------------------------------------------------------------------------\n\nexport const ALL_SKILLS_TEST_CATEGORIES_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: TEST_CATEGORIES as unknown as Record<Category, CategoryDefinition>,\n});\n\nexport const ALL_SKILLS_WEB_FRAMEWORK_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: {\n \"web-framework\": { domain: \"web\" },\n } as Record<Category, CategoryDefinition>,\n});\n\nexport const ALL_SKILLS_WEB_PAIR_CATEGORIES_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: {\n \"web-framework\": { domain: \"web\" },\n \"web-client-state\": { domain: \"web\" },\n } as Record<Category, CategoryDefinition>,\n});\n\nexport const ALL_SKILLS_FULLSTACK_CATEGORIES_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: {\n \"web-framework\": { domain: \"web\" },\n \"web-client-state\": { domain: \"web\" },\n \"api-api\": { domain: \"api\" },\n } as Record<Category, CategoryDefinition>,\n});\n\nexport const ALL_SKILLS_WEB_AND_API_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: {\n \"web-framework\": { domain: \"web\" },\n \"api-api\": { domain: \"api\" },\n } as Record<Category, CategoryDefinition>,\n});\n\nexport const ALL_SKILLS_METHODOLOGY_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: {\n \"shared-meta\": { domain: \"shared\" },\n } as Record<Category, CategoryDefinition>,\n});\n\nexport const ALL_SKILLS_METHODOLOGY_BARE_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: {\n \"shared-meta\": {},\n } as Record<Category, CategoryDefinition>,\n});\n\nexport const ALL_SKILLS_MULTI_DOMAIN_MATRIX = createMockMatrix(...Object.values(SKILLS), {\n categories: {\n \"web-framework\": { domain: \"web\" },\n \"shared-meta\": { domain: \"shared\" },\n \"api-api\": { domain: \"api\" },\n } as Record<Category, CategoryDefinition>,\n});\n\nexport const REACT_HONO_FRAMEWORK_API_MATRIX = createMockMatrix(SKILLS.react, SKILLS.hono, {\n categories: {\n \"web-framework\": TEST_CATEGORIES.framework,\n \"api-api\": TEST_CATEGORIES.api,\n } as Record<Category, CategoryDefinition>,\n});\n\n// ---------------------------------------------------------------------------\n// Matrix configs from matrix-loader.test.ts\n// ---------------------------------------------------------------------------\n\nexport const MERGE_BASIC_MATRIX = createMockMatrixConfig({ \"web-framework\": FRAMEWORK_CATEGORY });\n\nexport const CONFLICT_MATRIX = createMockMatrixConfig(\n {},\n {\n relationships: {\n conflicts: [{ skills: [\"react\", \"vue-composition-api\"], reason: \"Pick one framework\" }],\n },\n },\n);\n\nexport const ALTERNATIVES_MATRIX = createMockMatrixConfig(\n {},\n {\n relationships: {\n alternatives: [\n {\n purpose: \"State management\",\n skills: [\"zustand\", \"jotai\"],\n },\n ],\n },\n },\n);\n\nexport const REQUIRES_MATRIX = createMockMatrixConfig(\n {},\n {\n relationships: {\n requires: [\n {\n skill: \"zustand\",\n needs: [\"react\"],\n reason: \"Zustand needs React\",\n },\n ],\n },\n },\n);\n\n// ---------------------------------------------------------------------------\n// MergedSkillsMatrix instances from config-generator.test.ts\n// ---------------------------------------------------------------------------\n\nexport const LOCAL_SKILL_MATRIX = createMockMatrix(\n // Boundary cast: fictional skill ID for testing local skill matrix\n createMockSkill(\"web-local-skill\" as SkillId, {\n local: true,\n localPath: \".claude/skills/my-local-skill/\",\n }),\n);\n\nexport const MIXED_LOCAL_REMOTE_MATRIX = createMockMatrix(\n SKILLS.react,\n // Boundary cast: fictional skill ID for testing mixed local/remote matrix\n createMockSkill(\"meta-company-patterns\" as SkillId, {\n local: true,\n localPath: \".claude/skills/company-patterns/\",\n }),\n);\n\nexport const METHODOLOGY_MATRIX = createMockMatrix(SKILLS.antiOverEng);\n\nexport const VITEST_MATRIX = createMockMatrix(SKILLS.vitest);\n\n// ---------------------------------------------------------------------------\n// Compile configs from resolver.test.ts\n// ---------------------------------------------------------------------------\n\nexport const WEB_AND_API_COMPILE_CONFIG = createMockCompileConfig({\n \"web-developer\": {},\n \"api-developer\": {},\n});\n\nexport const WEB_ONLY_COMPILE_CONFIG = createMockCompileConfig({\n \"web-developer\": {},\n});\n\n// ---------------------------------------------------------------------------\n// Matrix configs from consumer-stacks-matrix.integration.test.ts\n// ---------------------------------------------------------------------------\n\nexport const TOOLING_AND_FRAMEWORK_CONFIG = createMockMatrixConfig({\n \"shared-tooling\": {\n ...TEST_CATEGORIES.tooling,\n description: \"Development tooling and infrastructure\",\n domain: \"shared\" as const,\n exclusive: false,\n order: 20,\n },\n \"web-framework\": {\n ...TEST_CATEGORIES.framework,\n description: \"UI Framework\",\n required: true,\n order: 1,\n },\n});\n\nexport const CI_CD_CONFIG = createMockMatrixConfig({\n \"shared-ci-cd\": createMockCategory(\"shared-ci-cd\", \"CI/CD\", {\n description: \"Continuous integration and deployment\",\n domain: \"shared\",\n exclusive: true,\n required: false,\n order: 30,\n }),\n});\n\nexport const FRAMEWORK_AND_STYLING_CONFIG = createMockMatrixConfig(\n {\n \"web-framework\": {\n ...TEST_CATEGORIES.framework,\n description: \"UI Framework\",\n required: true,\n order: 1,\n },\n \"web-styling\": {\n ...TEST_CATEGORIES.styling,\n description: \"CSS approach\",\n exclusive: false,\n order: 2,\n },\n },\n {\n relationships: {\n discourages: [\n {\n skills: [\"react\", \"scss-modules\"],\n reason: \"These tools have conflicting design philosophies\",\n },\n ],\n recommends: [\n {\n skill: \"vue-composition-api\",\n reason: \"These work great together\",\n },\n ],\n },\n },\n);\n\nexport const OBSERVABILITY_CONFIG = createMockMatrixConfig({\n \"api-observability\": createMockCategory(\"api-observability\", \"Observability\", {\n description: \"Monitoring and observability tools\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 15,\n }),\n});\n\nexport const FRAMEWORK_AND_TESTING_CONFIG = createMockMatrixConfig(\n {\n \"web-framework\": {\n ...TEST_CATEGORIES.framework,\n description: \"UI Framework\",\n required: true,\n order: 1,\n },\n \"web-testing\": {\n ...TEST_CATEGORIES.testing,\n description: \"Testing tools\",\n domain: \"shared\" as const,\n exclusive: false,\n order: 10,\n },\n },\n {\n relationships: {\n requires: [\n {\n skill: \"vitest\",\n needs: [\"react\"],\n reason: \"RTL requires React to function\",\n },\n ],\n },\n },\n);\n\n// ---------------------------------------------------------------------------\n// Matrix configs from skill-resolution.test.ts\n// ---------------------------------------------------------------------------\n\nexport const EMPTY_MATRIX_CONFIG = createMockMatrixConfig({});\n\nexport const UNRESOLVED_CONFLICT_MATRIX = createMockMatrixConfig(\n {},\n {\n relationships: {\n conflicts: [\n {\n // Boundary cast: deliberately invalid slug to test unresolved reference handling\n skills: [\"react\", \"nonexistent\" as SkillSlug],\n reason: \"Conflict with missing skill\",\n },\n ],\n },\n },\n);\n\n// ---------------------------------------------------------------------------\n// Pipeline matrix from wizard-init-compile-pipeline.test.ts\n// ---------------------------------------------------------------------------\n\nexport const PIPELINE_MATRIX = createMockMatrix(\n Object.fromEntries(\n PIPELINE_TEST_SKILLS.map((skill) => [skill.id, testSkillToResolvedSkill(skill)]),\n ),\n);\n\n// ---------------------------------------------------------------------------\n// Health-check matrices from matrix-health-check.test.ts\n// ---------------------------------------------------------------------------\n\nconst HEALTH_MISSING_DOMAIN_FRAMEWORK_CATEGORY = {\n ...TEST_CATEGORIES.framework,\n domain: undefined,\n};\n\nconst HEALTH_MISSING_DOMAIN_STYLING_CATEGORY = {\n ...TEST_CATEGORIES.styling,\n domain: undefined,\n};\n\nexport const HEALTH_HEALTHY_MATRIX = createMockMatrix(SKILLS.react, HEALTH_ZUSTAND_RECOMMENDED, {\n categories: {\n \"web-framework\": TEST_CATEGORIES.framework,\n \"web-client-state\": TEST_CATEGORIES.clientState,\n },\n});\n\nexport const HEALTH_SINGLE_SKILL_MATRIX = createMockMatrix(SKILLS.react, {\n categories: {\n \"web-framework\": TEST_CATEGORIES.framework,\n },\n});\n\nexport const HEALTH_MISSING_DOMAIN_MATRIX = createMockMatrix(SKILLS.react, {\n categories: {\n \"web-framework\": HEALTH_MISSING_DOMAIN_FRAMEWORK_CATEGORY,\n },\n});\n\nexport const HEALTH_MULTIPLE_MISSING_DOMAINS_MATRIX = createMockMatrix(\n {},\n {\n categories: {\n \"web-framework\": HEALTH_MISSING_DOMAIN_FRAMEWORK_CATEGORY,\n \"web-styling\": HEALTH_MISSING_DOMAIN_STYLING_CATEGORY,\n \"web-client-state\": TEST_CATEGORIES.clientState,\n },\n },\n);\n\nexport const HEALTH_UNKNOWN_CATEGORY_MATRIX = createMockMatrix(HEALTH_ORPHAN_SKILL, {\n categories: {\n \"web-framework\": TEST_CATEGORIES.framework,\n },\n});\n\nexport const HEALTH_ORPHAN_SKILL_WITH_MISSING_DOMAIN_MATRIX = createMockMatrix(\n HEALTH_ORPHAN_SKILL,\n {\n categories: {\n \"web-framework\": HEALTH_MISSING_DOMAIN_FRAMEWORK_CATEGORY,\n },\n },\n);\n\nexport const HEALTH_UNRESOLVED_COMPATIBLE_WITH_MATRIX = createMockMatrix(\n HEALTH_UNRESOLVED_COMPATIBLE_WITH_SKILL,\n {\n categories: {\n \"web-client-state\": TEST_CATEGORIES.clientState,\n },\n },\n);\n\nexport const HEALTH_UNRESOLVED_CONFLICTS_WITH_MATRIX = createMockMatrix(\n HEALTH_UNRESOLVED_CONFLICTS_WITH_SKILL,\n {\n categories: {\n \"web-framework\": TEST_CATEGORIES.framework,\n },\n },\n);\n\nexport const HEALTH_UNRESOLVED_REQUIRES_MATRIX = createMockMatrix(\n HEALTH_UNRESOLVED_REQUIRES_SKILL,\n {\n categories: {\n \"web-testing\": TEST_CATEGORIES.testing,\n },\n },\n);\n\nexport const HEALTH_MULTIPLE_UNRESOLVED_REFS_MATRIX = createMockMatrix(\n HEALTH_MULTIPLE_UNRESOLVED_REFS_SKILL,\n {\n categories: {\n \"web-client-state\": TEST_CATEGORIES.clientState,\n },\n },\n);\n\nexport const HEALTH_ALL_REFS_RESOLVED_MATRIX = createMockMatrix(\n SKILLS.react,\n HEALTH_ALL_REFS_RESOLVED_SKILL,\n {\n categories: {\n \"web-framework\": TEST_CATEGORIES.framework,\n \"web-client-state\": TEST_CATEGORIES.clientState,\n },\n },\n);\n\nexport const HEALTH_PARTIAL_UNRESOLVED_REQUIRES_MATRIX = createMockMatrix(\n SKILLS.react,\n HEALTH_PARTIAL_UNRESOLVED_REQUIRES_SKILL,\n {\n categories: {\n \"web-framework\": TEST_CATEGORIES.framework,\n \"web-testing\": TEST_CATEGORIES.testing,\n },\n },\n);\n\n// ---------------------------------------------------------------------------\n// Multi-source matrix from skill-resolution.integration.test.ts\n// ---------------------------------------------------------------------------\n\ntype TaggedMultiSourceEntry = MultiSourceSkillEntry & { source: SkillSource };\n\nexport function buildMultiSourceMatrix(\n overrides?: Partial<MergedSkillsMatrix>,\n): MergedSkillsMatrix {\n const taggedEntries: TaggedMultiSourceEntry[] = [\n ...MULTI_SOURCE_PUBLIC_SKILLS.map((s) => ({ ...s, source: { ...PUBLIC_SOURCE } })),\n ...MULTI_SOURCE_ACME_SKILLS.map((s) => ({ ...s, source: { ...ACME_SOURCE } })),\n ...MULTI_SOURCE_INTERNAL_SKILLS.map((s) => ({ ...s, source: { ...INTERNAL_SOURCE } })),\n ];\n const grouped = groupBy(taggedEntries, (e) => e.id);\n const skills = mapValues(grouped, (entries) => {\n const first = entries[0]!;\n const sources = entries.map((e) => e.source);\n // Boundary cast: MultiSourceSkillEntry.id is string, but contains valid skill IDs\n return createMockMultiSourceSkill(first.id as SkillId, sources, {\n category: first.category as CategoryPath,\n description: first.description,\n });\n });\n\n return createMockMatrix(skills, {\n categories: MULTI_SOURCE_CATEGORIES,\n ...overrides,\n });\n}\n","// Shared skill entries and TestSkill arrays for test files.\n// Uses createMockSkillEntry from helpers.ts.\n\nimport type {\n Category,\n CategoryPath,\n ResolvedSkill,\n Skill,\n SkillId,\n SkillSlug,\n} from \"../../../types\";\nimport type { TestSkill } from \"../fixtures/create-test-source\";\nimport {\n createMockExtractedSkill,\n createMockSkill,\n createMockSkillEntry,\n createTestSkill,\n SKILLS,\n} from \"../helpers.js\";\nimport { renderSkillMd } from \"../content-generators\";\n\n// Skill entries from compiler.test.ts\n\nexport const REACT_SKILL_PRELOADED = createMockSkillEntry(\"web-framework-react\", true);\n\nexport const REACT_SKILL = createMockSkillEntry(\"web-framework-react\");\n\nexport const VITEST_SKILL = createMockSkillEntry(\"web-testing-vitest\");\n\nexport const VITEST_SINGLE_FILE_SKILL: Skill = {\n ...VITEST_SKILL,\n path: \"skills/web-testing-vitest.md\",\n};\n\nconst METHODOLOGY_TEST_SKILLS: TestSkill[] = [\n {\n id: \"shared-meta-reviewing\",\n slug: \"reviewing\",\n displayName: \"Anti Over-Engineering\",\n description: \"Surgical implementation, not architectural innovation\",\n category: \"shared-meta\",\n author: \"@test\",\n domain: \"shared\",\n },\n];\n\n// Individual TestSkill constants — each skill defined exactly once\n\nconst reactSkill = createTestSkill(\n \"web-framework-react\",\n \"React framework for building user interfaces\",\n {},\n);\n\nconst zustandSkill = createTestSkill(\"web-state-zustand\", \"Bear necessities state management\");\n\nconst vitestSkill = createTestSkill(\"web-testing-vitest\", \"Next generation testing framework\");\n\nconst honoSkill = createTestSkill(\"api-framework-hono\", \"Lightweight web framework for the edge\");\n\nconst vueSkill = createTestSkill(\n \"web-framework-vue-composition-api\",\n \"Progressive JavaScript framework\",\n {},\n);\n\nconst scssSkill = createTestSkill(\"web-styling-scss-modules\", \"CSS Modules with SCSS\", {\n displayName: \"SCSS Modules\",\n});\n\nconst drizzleSkill = createTestSkill(\"api-database-drizzle\", \"TypeScript ORM for SQL databases\");\n\n// Composed TestSkill arrays\n\nexport const EXTRA_DOMAIN_TEST_SKILLS: TestSkill[] = [vueSkill, scssSkill, drizzleSkill];\n\nexport const COMPILE_LOCAL_SKILL: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for testing local skill compilation\n \"web-tooling-local-skill\" as SkillId,\n \"A local project skill\",\n { slug: \"tooling\" as SkillSlug, displayName: \"Local Skill\" },\n);\n\nexport const DEFAULT_TEST_SKILLS: TestSkill[] = [reactSkill, zustandSkill, vitestSkill, honoSkill];\n\nexport const PIPELINE_TEST_SKILLS: TestSkill[] = [\n ...DEFAULT_TEST_SKILLS,\n ...EXTRA_DOMAIN_TEST_SKILLS,\n];\n\n// TestSkill constants from consumer-stacks-matrix.integration.test.ts\n\nexport const DOCKER_TOOLING_SKILL: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for testing infra tooling\n \"infra-tooling-docker\" as SkillId,\n \"Docker containerization patterns\",\n {\n slug: \"tooling\" as SkillSlug,\n displayName: \"Docker\",\n domain: \"shared\",\n },\n);\n\nexport const CI_CD_SKILLS: TestSkill[] = [\n // Boundary cast: fictional skill ID for testing CI/CD skills\n createTestSkill(\"infra-ci-cd-github-actions\" as SkillId, \"github-actions CI/CD pipeline\", {\n slug: \"github-actions\",\n displayName: \"GitHub Actions\",\n category: \"infra-ci-cd\",\n domain: \"shared\",\n }),\n // Boundary cast: fictional skill ID for testing CI/CD skills\n createTestSkill(\"infra-ci-cd-gitlab-ci\" as SkillId, \"gitlab-ci CI/CD pipeline\", {\n // Boundary cast: fictional slug for test isolation\n slug: \"gitlab-ci\" as SkillSlug,\n displayName: \"GitLab CI\",\n category: \"infra-ci-cd\",\n domain: \"shared\",\n }),\n];\n\nexport const DISCOURAGES_RELATIONSHIP_SKILLS: TestSkill[] = [reactSkill, scssSkill, vueSkill];\n\nexport const DATADOG_OBSERVABILITY_SKILL: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for testing observability skills\n \"api-observability-datadog\" as SkillId,\n \"Datadog APM integration\",\n {},\n);\n\nexport const REQUIRES_RELATIONSHIP_SKILLS: TestSkill[] = [reactSkill, vitestSkill];\n\n// Source-switching TestSkill arrays (with rendered SKILL.md content)\n\n/** Creates a TestSkill with rendered SKILL.md content for source-switching tests */\nfunction contentSkill(id: SkillId, description: string, body: string, author?: string): TestSkill {\n return createTestSkill(id, description, {\n ...(author ? { author } : {}),\n content: renderSkillMd(id, description, body),\n });\n}\n\nexport const SWITCHABLE_SKILLS: TestSkill[] = [\n contentSkill(\n \"web-framework-react\",\n \"React framework for building user interfaces\",\n \"# React (Marketplace Version)\\n\\nReact is a JavaScript library for building user interfaces.\\nUse component-based architecture with JSX.\",\n ),\n contentSkill(\n \"web-state-zustand\",\n \"Bear necessities state management\",\n \"# Zustand (Marketplace Version)\\n\\nZustand is a minimal state management library for React.\",\n ),\n contentSkill(\n \"api-framework-hono\",\n \"Lightweight web framework for the edge\",\n \"# Hono (Marketplace Version)\\n\\nHono is a fast web framework for the edge.\",\n ),\n contentSkill(\n \"web-testing-vitest\",\n \"Next generation testing framework\",\n \"# Vitest (Marketplace Version)\\n\\nVitest is a fast unit test framework powered by Vite.\",\n ),\n];\n\nexport const LOCAL_SKILL_VARIANTS: TestSkill[] = [\n contentSkill(\n \"web-framework-react\",\n \"React framework (local customized version)\",\n \"# React (Local Version)\\n\\nThis is my customized React skill with project-specific patterns.\",\n \"@local-user\",\n ),\n contentSkill(\n \"web-state-zustand\",\n \"Zustand state management (local customized version)\",\n \"# Zustand (Local Version)\\n\\nMy customized Zustand patterns with project-specific stores.\",\n \"@local-user\",\n ),\n];\n\nexport const RESOLUTION_PIPELINE_SKILLS: TestSkill[] = [\n createTestSkill(\"web-framework-react\", \"React framework (public source)\"),\n createTestSkill(\"api-framework-hono\", \"Hono framework (acme source)\", {\n author: \"@acme\",\n }),\n // Boundary cast: fictional skill ID for testing multi-source resolution\n createTestSkill(\"web-animation-framer\" as SkillId, \"Framer Motion (internal source)\", {\n slug: \"framer-motion\",\n displayName: \"Framer Motion\",\n author: \"@internal\",\n }),\n createTestSkill(\"api-database-drizzle\", \"Drizzle ORM (acme source)\", {\n author: \"@acme\",\n }),\n createTestSkill(\"web-testing-vitest\", \"Vitest testing (public source)\"),\n];\n\n// Composed skill ID collections\n\nexport const ALL_TEST_SKILLS = [\n ...DEFAULT_TEST_SKILLS,\n ...EXTRA_DOMAIN_TEST_SKILLS,\n ...METHODOLOGY_TEST_SKILLS,\n];\n\nexport const INIT_SKILL_IDS: SkillId[] = [\n \"web-framework-react\",\n \"api-framework-hono\",\n \"web-testing-vitest\",\n];\n\nexport const INIT_TEST_SKILLS = DEFAULT_TEST_SKILLS.filter((s) =>\n INIT_SKILL_IDS.includes(s.id as SkillId),\n);\n\n// ExtractedSkillMetadata constants for skill-resolution tests\n\nexport const REACT_EXTRACTED = createMockExtractedSkill(\"web-framework-react\", {\n description: \"React framework\",\n author: \"@vince\",\n});\n\nexport const REACT_EXTRACTED_BASIC = createMockExtractedSkill(\"web-framework-react\", {\n description: \"React\",\n});\n\nexport const VUE_EXTRACTED_BASIC = createMockExtractedSkill(\"web-framework-vue-composition-api\", {\n description: \"Vue\",\n});\n\nexport const ZUSTAND_EXTRACTED = createMockExtractedSkill(\"web-state-zustand\", {\n description: \"Zustand\",\n category: \"web-client-state\",\n});\n\nexport const JOTAI_EXTRACTED = createMockExtractedSkill(\"web-state-jotai\", {\n description: \"Jotai\",\n category: \"web-client-state\",\n});\n\n// ---------------------------------------------------------------------------\n// Health-check skill variants (matrix-health-check.test.ts)\n// ---------------------------------------------------------------------------\n\nexport const HEALTH_ZUSTAND_RECOMMENDED = {\n ...SKILLS.zustand,\n isRecommended: true,\n recommendedReason: \"Works well with React\",\n};\n\nexport const HEALTH_ORPHAN_SKILL = {\n ...SKILLS.react,\n category: \"nonexistent-category\" as Category,\n};\n\nexport const HEALTH_UNRESOLVED_COMPATIBLE_WITH_SKILL = {\n ...SKILLS.zustand,\n // Boundary cast: fake SkillId for unresolved-ref testing\n compatibleWith: [\"web-framework-nonexistent\" as SkillId],\n};\n\nexport const HEALTH_UNRESOLVED_CONFLICTS_WITH_SKILL = {\n ...SKILLS.react,\n // Boundary cast: fake SkillId for unresolved-ref testing\n conflictsWith: [{ skillId: \"web-framework-ghost\" as SkillId, reason: \"Conflicts\" }],\n};\n\nexport const HEALTH_UNRESOLVED_REQUIRES_SKILL = createMockSkill(\"web-testing-cypress-e2e\", {\n requires: [\n {\n skillIds: [\"web-framework-missing\" as SkillId],\n needsAny: false,\n reason: \"Needs a framework\",\n },\n ],\n});\n\nexport const HEALTH_MULTIPLE_UNRESOLVED_REFS_SKILL = {\n ...SKILLS.zustand,\n // Boundary casts: fake SkillIds for unresolved-ref testing\n compatibleWith: [\"web-framework-missing\" as SkillId],\n conflictsWith: [{ skillId: \"web-state-ghost\" as SkillId, reason: \"Conflicts\" }],\n};\n\nexport const HEALTH_ALL_REFS_RESOLVED_SKILL: ResolvedSkill = {\n ...SKILLS.zustand,\n conflictsWith: [{ skillId: \"web-framework-react\", reason: \"Test\" }],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason: \"Needs React\",\n },\n ],\n};\n\nexport const HEALTH_PARTIAL_UNRESOLVED_REQUIRES_SKILL = createMockSkill(\"web-testing-cypress-e2e\", {\n requires: [\n {\n skillIds: [\"web-framework-react\", \"web-framework-missing\" as SkillId],\n needsAny: true,\n reason: \"Needs one framework\",\n },\n ],\n});\n\n// ---------------------------------------------------------------------------\n// Category grid test skills (category-grid.test.tsx)\n// ---------------------------------------------------------------------------\n\nexport const CATEGORY_GRID_SKILLS: {\n id: SkillId;\n displayName: string;\n category: CategoryPath;\n}[] = [\n { id: \"web-framework-react\", displayName: \"React\", category: \"web-framework\" },\n { id: \"web-framework-vue-composition-api\", displayName: \"Vue\", category: \"web-framework\" },\n { id: \"web-framework-angular-standalone\", displayName: \"Angular\", category: \"web-framework\" },\n { id: \"web-framework-solidjs\", displayName: \"SolidJS\", category: \"web-framework\" },\n { id: \"web-meta-framework-nuxt\", displayName: \"Nuxt\", category: \"web-meta-framework\" },\n { id: \"web-meta-framework-remix\", displayName: \"Remix\", category: \"web-meta-framework\" },\n { id: \"web-meta-framework-nextjs\", displayName: \"Next.js\", category: \"web-meta-framework\" },\n { id: \"web-styling-scss-modules\", displayName: \"SCSS Modules\", category: \"web-styling\" },\n { id: \"web-styling-tailwind\", displayName: \"Tailwind\", category: \"web-styling\" },\n { id: \"web-styling-cva\", displayName: \"CVA\", category: \"web-styling\" },\n { id: \"web-state-zustand\", displayName: \"Zustand\", category: \"web-client-state\" },\n { id: \"web-state-jotai\", displayName: \"Jotai\", category: \"web-client-state\" },\n { id: \"web-state-redux-toolkit\", displayName: \"Redux\", category: \"web-client-state\" },\n { id: \"web-state-mobx\", displayName: \"MobX\", category: \"web-client-state\" },\n { id: \"web-server-state-react-query\", displayName: \"React Query\", category: \"web-server-state\" },\n { id: \"web-data-fetching-swr\", displayName: \"SWR\", category: \"web-server-state\" },\n { id: \"web-data-fetching-graphql-apollo\", displayName: \"Apollo\", category: \"web-server-state\" },\n { id: \"api-analytics-posthog-analytics\", displayName: \"PostHog\", category: \"api-analytics\" },\n { id: \"web-forms-react-hook-form\", displayName: \"React Hook Form\", category: \"web-forms\" },\n { id: \"web-forms-vee-validate\", displayName: \"Vee Validate\", category: \"web-forms\" },\n { id: \"web-forms-zod-validation\", displayName: \"Zod Validation\", category: \"web-forms\" },\n { id: \"web-testing-vitest\", displayName: \"Vitest\", category: \"web-testing\" },\n { id: \"web-testing-playwright-e2e\", displayName: \"Playwright\", category: \"web-testing\" },\n { id: \"web-testing-cypress-e2e\", displayName: \"Cypress\", category: \"web-testing\" },\n { id: \"web-mocks-msw\", displayName: \"MSW\", category: \"web-mocking\" },\n {\n id: \"web-testing-react-testing-library\",\n displayName: \"React Testing Library\",\n category: \"web-testing\",\n },\n { id: \"web-testing-vue-test-utils\", displayName: \"Vue Test Utils\", category: \"web-testing\" },\n { id: \"web-i18n-next-intl\", displayName: \"Next Intl\", category: \"web-i18n\" },\n { id: \"web-i18n-react-intl\", displayName: \"React Intl\", category: \"web-i18n\" },\n { id: \"web-i18n-vue-i18n\", displayName: \"Vue I18n\", category: \"web-i18n\" },\n];\n\n// ---------------------------------------------------------------------------\n// Multi-source integration test skill entries (skill-resolution.integration.test.ts)\n// ---------------------------------------------------------------------------\n\ntype MultiSourceSkillEntry = { id: string; category: string; description: string };\n\nexport const MULTI_SOURCE_PUBLIC_SKILLS: MultiSourceSkillEntry[] = [\n { id: \"web-framework-react\", category: \"web-framework\", description: \"React framework\" },\n {\n id: \"web-framework-vue-composition-api\",\n category: \"web-framework\",\n description: \"Vue.js framework\",\n },\n {\n id: \"web-state-zustand\",\n category: \"web-client-state\",\n description: \"Zustand state management\",\n },\n { id: \"web-styling-scss-modules\", category: \"web-styling\", description: \"SCSS Modules styling\" },\n { id: \"web-testing-vitest\", category: \"web-testing\", description: \"Vitest testing framework\" },\n];\n\nexport const MULTI_SOURCE_ACME_SKILLS: MultiSourceSkillEntry[] = [\n { id: \"web-framework-react\", category: \"web-framework\", description: \"React (acme custom fork)\" },\n { id: \"api-framework-hono\", category: \"api-api\", description: \"Hono web framework\" },\n { id: \"api-database-drizzle\", category: \"api-database\", description: \"Drizzle ORM\" },\n { id: \"api-security-auth-patterns\", category: \"shared-security\", description: \"Auth patterns\" },\n { id: \"web-testing-vitest\", category: \"web-testing\", description: \"Vitest (acme custom)\" },\n];\n\nexport const MULTI_SOURCE_INTERNAL_SKILLS: MultiSourceSkillEntry[] = [\n { id: \"web-framework-react\", category: \"web-framework\", description: \"React (internal build)\" },\n { id: \"web-animation-framer\", category: \"web-animation\", description: \"Framer Motion\" },\n {\n id: \"meta-methodology-investigation\",\n category: \"shared-meta\",\n description: \"Investigation first\",\n },\n { id: \"web-accessibility-a11y\", category: \"web-accessibility\", description: \"Web accessibility\" },\n {\n id: \"api-monitoring-sentry\",\n category: \"api-observability\",\n description: \"Sentry error tracking\",\n },\n];\n\nexport type { MultiSourceSkillEntry };\n\n// ---------------------------------------------------------------------------\n// Local/compile skill constants (from create-test-source.ts)\n// ---------------------------------------------------------------------------\n\n/** Valid local skill with SKILL.md and metadata.yaml */\nexport const VALID_LOCAL_SKILL: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for test isolation\n \"web-tooling-valid\" as SkillId,\n \"A valid skill\",\n { slug: \"tooling\" as SkillSlug, displayName: \"Valid\" },\n);\n\n/** Skill created WITHOUT metadata.yaml (for testing missing-metadata warnings) */\nexport const SKILL_WITHOUT_METADATA: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for test isolation\n \"web-tooling-incomplete\" as SkillId,\n \"Missing metadata\",\n { slug: \"storybook\", displayName: \"Incomplete\", skipMetadata: true },\n);\n\n/** Another skill without metadata.yaml (for path warning tests) */\nexport const SKILL_WITHOUT_METADATA_CUSTOM: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for test isolation\n \"web-tooling-custom\" as SkillId,\n \"No metadata\",\n { slug: \"security\" as SkillSlug, displayName: \"Custom\", skipMetadata: true },\n);\n\n/** A basic local-only skill (no forkedFrom) with SKILL.md and metadata.yaml */\nexport const LOCAL_SKILL_BASIC: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for test isolation\n \"web-tooling-my-skill\" as SkillId,\n \"A test skill\",\n {\n slug: \"tooling\" as SkillSlug,\n displayName: \"My Skill\",\n content: `---\nname: my-skill\ndescription: A test skill\ncategory: test\n---\n\n# My Skill\n\nTest content here.\n`,\n },\n);\n\n/** A forked local skill with forkedFrom metadata for diff/update/outdated commands */\nexport const LOCAL_SKILL_FORKED: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for test isolation\n \"web-tooling-forked-skill\" as SkillId,\n \"A forked skill\",\n {\n slug: \"tooling\" as SkillSlug,\n displayName: \"Forked Skill\",\n content: `---\nname: forked-skill\ndescription: A forked skill\ncategory: test\n---\n\n# Forked Skill\n\nLocal modifications here.\n`,\n forkedFrom: {\n skillId: \"web-framework-react\",\n contentHash: \"abc123\",\n date: \"2025-01-01\",\n },\n },\n);\n\n/** A minimal local skill for error handling tests (with forkedFrom) */\nexport const LOCAL_SKILL_FORKED_MINIMAL: TestSkill = createTestSkill(\n // Boundary cast: fictional skill ID for test isolation\n \"web-tooling-test-minimal\" as SkillId,\n \"Test skill\",\n {\n slug: \"env\" as SkillSlug,\n displayName: \"Test Minimal\",\n content: `---\nname: test\n---\n# Test`,\n forkedFrom: {\n skillId: \"web-framework-react\",\n contentHash: \"abc\",\n date: \"2025-01-01\",\n },\n },\n);\n\n// ---------------------------------------------------------------------------\n// Import source skill constants (import-skill.integration.test.ts)\n// ---------------------------------------------------------------------------\n\n/**\n * Skills used by import:skill integration tests with richer content.\n * These use a plain object type (not TestSkill) because import sources use\n * simple directory names that don't follow the SkillId pattern.\n */\nexport type ImportSourceSkill = {\n name: string;\n content: string;\n metadata?: Record<string, unknown>;\n};\n\n/** React patterns skill with metadata for import integration tests */\nexport const IMPORT_REACT_PATTERNS_SKILL: ImportSourceSkill = {\n name: \"react-patterns\",\n content: `---\nname: react-patterns\ndescription: React design patterns and best practices\n---\n\n# React Patterns\n\n## Component Composition\n\nUse composition over inheritance for flexible component design.\n\n## Hooks Patterns\n\n- Custom hooks for shared logic\n- useReducer for complex state\n- useMemo for expensive computations\n`,\n metadata: {\n author: \"@external-author\",\n category: \"web-framework\",\n },\n};\n\n/** Testing utils skill with metadata for import integration tests */\nexport const IMPORT_TESTING_UTILS_SKILL: ImportSourceSkill = {\n name: \"testing-utils\",\n content: `---\nname: testing-utils\ndescription: Testing utilities and best practices\n---\n\n# Testing Utilities\n\n## Unit Testing\n\nWrite focused tests that verify single behaviors.\n\n## Integration Testing\n\nTest component interactions and data flow.\n`,\n metadata: {\n author: \"@external-author\",\n category: \"web-testing\",\n },\n};\n\n/** API security skill without metadata for import integration tests */\nexport const IMPORT_API_SECURITY_SKILL: ImportSourceSkill = {\n name: \"api-security\",\n content: `---\nname: api-security\ndescription: API security patterns and middleware\n---\n\n# API Security\n\n## Authentication\n\nImplement JWT-based authentication with refresh tokens.\n\n## Rate Limiting\n\nApply rate limiting to prevent abuse.\n`,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -4,17 +4,17 @@ import {
|
|
|
4
4
|
} from "./chunk-P2FHS5IS.js";
|
|
5
5
|
import {
|
|
6
6
|
useSectionScroll
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FFMWFEUH.js";
|
|
8
8
|
import {
|
|
9
9
|
HOTKEY_TOGGLE_LABELS,
|
|
10
10
|
isHotkey
|
|
11
11
|
} from "./chunk-CBYRFAUN.js";
|
|
12
12
|
import {
|
|
13
13
|
getSkillById
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-JWMYAJHD.js";
|
|
15
15
|
import {
|
|
16
16
|
CLI_COLORS
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-FMYAYX6W.js";
|
|
18
18
|
import {
|
|
19
19
|
init_esm_shims
|
|
20
20
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -153,6 +153,9 @@ var findNextValidOption = (options, currentIndex, direction, wrap = true) => {
|
|
|
153
153
|
return index;
|
|
154
154
|
};
|
|
155
155
|
var getCompatibilityLabel = (option) => {
|
|
156
|
+
if (option.selected && option.requiredBy) {
|
|
157
|
+
return `(required by ${option.requiredBy})`;
|
|
158
|
+
}
|
|
156
159
|
if (option.selected && option.hasUnmetRequirements && option.unmetRequirementsReason) {
|
|
157
160
|
return `(${option.unmetRequirementsReason})`;
|
|
158
161
|
}
|
|
@@ -178,8 +181,9 @@ var SkillTag = ({ option, isFocused, isLocked, showLabels }) => {
|
|
|
178
181
|
return CLI_COLORS.UNFOCUSED;
|
|
179
182
|
};
|
|
180
183
|
const textColor = getTextColor();
|
|
184
|
+
const hasRequiredBy = option.selected && !!option.requiredBy;
|
|
181
185
|
const hasUnmetDeps = option.selected && !!option.hasUnmetRequirements;
|
|
182
|
-
const compatibilityLabel = hasUnmetDeps ? getCompatibilityLabel(option) : showLabels && isFocused ? getCompatibilityLabel(option) : null;
|
|
186
|
+
const compatibilityLabel = hasRequiredBy ? getCompatibilityLabel(option) : hasUnmetDeps ? getCompatibilityLabel(option) : showLabels && isFocused ? getCompatibilityLabel(option) : null;
|
|
183
187
|
return /* @__PURE__ */ jsx(
|
|
184
188
|
Box,
|
|
185
189
|
{
|
|
@@ -194,10 +198,18 @@ var SkillTag = ({ option, isFocused, isLocked, showLabels }) => {
|
|
|
194
198
|
/* @__PURE__ */ jsx(Text, { color: "#eee", backgroundColor: "#383838", children: option.scope === "global" ? " G " : " P " }),
|
|
195
199
|
/* @__PURE__ */ jsx(Text, { children: " " })
|
|
196
200
|
] }),
|
|
197
|
-
/* @__PURE__ */ jsxs(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
+
/* @__PURE__ */ jsxs(
|
|
202
|
+
Text,
|
|
203
|
+
{
|
|
204
|
+
color: textColor,
|
|
205
|
+
bold: true,
|
|
206
|
+
dimColor: option.selected && !!option.hasUnmetRequirements || option.selected && !!option.requiredBy,
|
|
207
|
+
children: [
|
|
208
|
+
getSkillById(option.id).displayName,
|
|
209
|
+
" "
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
),
|
|
201
213
|
compatibilityLabel && /* @__PURE__ */ jsxs(Text, { color: textColor, dimColor: true, children: [
|
|
202
214
|
compatibilityLabel,
|
|
203
215
|
" "
|
|
@@ -350,4 +362,4 @@ var CategoryGrid = ({
|
|
|
350
362
|
export {
|
|
351
363
|
CategoryGrid
|
|
352
364
|
};
|
|
353
|
-
//# sourceMappingURL=chunk-
|
|
365
|
+
//# sourceMappingURL=chunk-7NACNRFG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/wizard/category-grid.tsx","../src/cli/components/hooks/use-category-grid-input.ts"],"sourcesContent":["import React, { useCallback, useMemo, useRef } from \"react\";\n\nimport { Box, Text } from \"ink\";\n\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { getSkillById } from \"../../lib/matrix/matrix-provider.js\";\nimport type { Category, OptionState, SkillId } from \"../../types/index.js\";\nimport { isSectionLocked, useCategoryGridInput } from \"../hooks/use-category-grid-input.js\";\nimport { useFocusedListItem } from \"../hooks/use-focused-list-item.js\";\nimport { useSectionScroll } from \"../hooks/use-section-scroll.js\";\n\nexport type CategoryOption = {\n id: SkillId;\n state: OptionState;\n selected: boolean;\n local?: boolean;\n installed?: boolean;\n scope?: \"project\" | \"global\";\n /** True when selected but has unmet dependency requirements (shown dimmed) */\n hasUnmetRequirements?: boolean;\n /** Explains unmet requirements (shown in label when D pressed) */\n unmetRequirementsReason?: string;\n /** Display name of the skill that requires this one (e.g. \"Next.js\") */\n requiredBy?: string;\n};\n\nexport type CategoryRow = {\n id: Category;\n displayName: string;\n required: boolean;\n exclusive: boolean;\n options: CategoryOption[];\n};\n\nexport type CategoryGridProps = {\n categories: CategoryRow[];\n /** Available height in terminal lines for the scrollable viewport. 0 = no constraint. */\n availableHeight?: number;\n showLabels: boolean;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n /** Optional initial focus row (default: 0). Use with React `key` to reset. */\n defaultFocusedRow?: number;\n /** Optional initial focus col (default: 0). Use with React `key` to reset. */\n defaultFocusedCol?: number;\n /** Optional callback fired whenever the focused position changes */\n onFocusChange?: (row: number, col: number) => void;\n /** Optional callback fired with the resolved SkillId of the focused cell */\n onFocusedSkillChange?: (skillId: SkillId | null) => void;\n};\n\nconst SYMBOL_REQUIRED = \"*\";\n\nconst findNextValidOption = (\n options: CategoryOption[],\n currentIndex: number,\n direction: 1 | -1,\n wrap = true,\n): number => {\n const length = options.length;\n if (length === 0) return currentIndex;\n\n let index = currentIndex + direction;\n\n if (wrap) {\n if (index < 0) index = length - 1;\n if (index >= length) index = 0;\n } else {\n if (index < 0) index = 0;\n if (index >= length) index = length - 1;\n }\n\n return index;\n};\n\ntype SkillTagProps = {\n option: CategoryOption;\n isFocused: boolean;\n isLocked: boolean;\n showLabels: boolean;\n};\n\nconst getCompatibilityLabel = (option: CategoryOption): string | null => {\n if (option.selected && option.requiredBy) {\n return `(required by ${option.requiredBy})`;\n }\n if (option.selected && option.hasUnmetRequirements && option.unmetRequirementsReason) {\n return `(${option.unmetRequirementsReason})`;\n }\n if (option.selected) return null;\n if (option.state.status === \"incompatible\") return \"(incompatible)\";\n if (option.state.status === \"recommended\") return \"(recommended)\";\n if (option.state.status === \"discouraged\") return \"(discouraged)\";\n return null;\n};\n\nconst SkillTag: React.FC<SkillTagProps> = ({ option, isFocused, isLocked, showLabels }) => {\n const getTextColor = (): string => {\n if (option.selected) return CLI_COLORS.PRIMARY;\n if (option.state.status === \"incompatible\") return CLI_COLORS.ERROR;\n if (option.state.status === \"recommended\") return CLI_COLORS.UNFOCUSED;\n if (option.state.status === \"discouraged\") return CLI_COLORS.WARNING;\n\n return CLI_COLORS.NEUTRAL;\n };\n\n const getStateBorderColor = (): string => {\n if (option.selected) return CLI_COLORS.PRIMARY;\n if (option.state.status === \"incompatible\") return CLI_COLORS.ERROR;\n if (option.state.status === \"recommended\") return CLI_COLORS.UNFOCUSED;\n if (option.state.status === \"discouraged\") return CLI_COLORS.WARNING;\n return CLI_COLORS.UNFOCUSED;\n };\n\n const textColor = getTextColor();\n const hasRequiredBy = option.selected && !!option.requiredBy;\n const hasUnmetDeps = option.selected && !!option.hasUnmetRequirements;\n const compatibilityLabel = hasRequiredBy\n ? getCompatibilityLabel(option)\n : hasUnmetDeps\n ? getCompatibilityLabel(option)\n : showLabels && isFocused\n ? getCompatibilityLabel(option)\n : null;\n\n return (\n <Box\n marginRight={1}\n borderColor={isFocused ? getStateBorderColor() : CLI_COLORS.NEUTRAL}\n borderStyle=\"single\"\n flexShrink={0}\n paddingLeft={1}\n >\n <>\n <Text />\n {option.scope && (\n <>\n <Text color={\"#eee\"} backgroundColor={\"#383838\"}>\n {option.scope === \"global\" ? \" G \" : \" P \"}\n </Text>\n <Text> </Text>\n </>\n )}\n <Text\n color={textColor}\n bold\n dimColor={\n (option.selected && !!option.hasUnmetRequirements) ||\n (option.selected && !!option.requiredBy)\n }\n >\n {getSkillById(option.id).displayName}{\" \"}\n </Text>\n {compatibilityLabel && (\n <Text color={textColor} dimColor>\n {compatibilityLabel}{\" \"}\n </Text>\n )}\n </>\n </Box>\n );\n};\n\ntype CategorySectionProps = {\n isFirst: boolean;\n category: CategoryRow;\n options: CategoryOption[];\n isLocked: boolean;\n isFocused: boolean;\n focusedOptionIndex: number;\n showLabels: boolean;\n};\n\nconst CategorySection: React.FC<CategorySectionProps> = ({\n isFirst,\n category,\n options,\n isLocked,\n isFocused,\n focusedOptionIndex,\n showLabels,\n}) => {\n const selectedCount = options.filter((o) => o.selected).length;\n\n const selectionCounter = category.exclusive ? `(${selectedCount} of 1)` : null;\n\n return (\n <Box flexDirection=\"column\" marginTop={isFirst ? 0 : 1}>\n <Box flexDirection=\"row\">\n {isFocused ? (\n <Text color={CLI_COLORS.WHITE} backgroundColor=\"#383838\">\n {` ${category.displayName}${category.required ? ` ${SYMBOL_REQUIRED}` : \"\"}${selectionCounter ? ` ${selectionCounter}` : \"\"} `}\n </Text>\n ) : (\n <>\n <Text color=\"gray\">{category.displayName}</Text>\n {category.required && <Text color=\"gray\"> {SYMBOL_REQUIRED}</Text>}\n {selectionCounter && <Text dimColor> {selectionCounter}</Text>}\n </>\n )}\n </Box>\n\n <Box flexDirection=\"row\" flexWrap=\"wrap\" marginTop={0}>\n {options.map((option, index) => (\n <SkillTag\n key={option.id}\n option={option}\n isFocused={isFocused && index === focusedOptionIndex && !isLocked}\n isLocked={isLocked}\n showLabels={showLabels}\n />\n ))}\n </Box>\n </Box>\n );\n};\n\ntype ProcessedCategory = CategoryRow & { sortedOptions: CategoryOption[] };\n\nexport const CategoryGrid: React.FC<CategoryGridProps> = ({\n categories,\n availableHeight = 0,\n showLabels,\n onToggle,\n onToggleLabels,\n defaultFocusedRow = 0,\n defaultFocusedCol = 0,\n onFocusChange,\n onFocusedSkillChange,\n}) => {\n const processedCategories = useMemo(\n () => categories.map((category) => ({ ...category, sortedOptions: category.options })),\n [categories],\n );\n\n const getColCount = useCallback(\n (row: number): number => processedCategories[row]?.sortedOptions.length ?? 0,\n [processedCategories],\n );\n\n const isRowLocked = useCallback(\n (row: number): boolean => {\n const cat = processedCategories[row];\n return cat ? isSectionLocked(cat.id, categories) : false;\n },\n [processedCategories, categories],\n );\n\n const findValidCol = useCallback(\n (row: number, currentCol: number, direction: 1 | -1): number => {\n const options = processedCategories[row]?.sortedOptions || [];\n const catId = processedCategories[row]?.id;\n if (catId && isSectionLocked(catId, categories)) return currentCol;\n return findNextValidOption(options, currentCol, direction, true);\n },\n [processedCategories, categories],\n );\n\n const handleFocusChange = useCallback(\n (row: number, col: number) => {\n if (showLabels) onToggleLabels();\n onFocusChange?.(row, col);\n const skill = processedCategories[row]?.sortedOptions[col];\n onFocusedSkillChange?.(skill?.id ?? null);\n },\n [showLabels, onToggleLabels, onFocusChange, processedCategories, onFocusedSkillChange],\n );\n\n const { focusedRow, focusedCol, setFocused, moveFocus } = useFocusedListItem(\n processedCategories.length,\n getColCount,\n {\n wrap: true,\n isRowLocked,\n findValidCol,\n onChange: handleFocusChange,\n initialRow: defaultFocusedRow,\n initialCol: defaultFocusedCol,\n },\n );\n\n const mountedRef = useRef(false);\n if (!mountedRef.current) {\n mountedRef.current = true;\n const skill = processedCategories[defaultFocusedRow]?.sortedOptions[defaultFocusedCol];\n onFocusedSkillChange?.(skill?.id ?? null);\n }\n\n useCategoryGridInput({\n processedCategories,\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n });\n\n const { setSectionRef, scrollEnabled, scrollTopPx } = useSectionScroll({\n sectionCount: processedCategories.length,\n focusedIndex: focusedRow,\n availableHeight,\n });\n\n if (categories.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>No categories to display.</Text>\n </Box>\n );\n }\n\n const noShrink = scrollEnabled ? { flexShrink: 0 } : {};\n\n const sectionElements = processedCategories.map((category, index) => {\n const isLocked = isSectionLocked(category.id, categories);\n\n return (\n <Box key={category.id} ref={(el) => setSectionRef(index, el)} {...noShrink}>\n <CategorySection\n category={category}\n options={category.sortedOptions}\n isLocked={isLocked}\n isFocused={index === focusedRow}\n focusedOptionIndex={focusedCol}\n showLabels={showLabels}\n isFirst={index === 0}\n />\n </Box>\n );\n });\n\n return (\n <Box\n flexDirection=\"column\"\n {...(scrollEnabled\n ? { height: availableHeight, overflow: \"hidden\" as const }\n : { flexGrow: 1 })}\n >\n <Box flexDirection=\"column\" marginTop={scrollTopPx > 0 ? -scrollTopPx : 0} {...noShrink}>\n {sectionElements}\n </Box>\n </Box>\n );\n};\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { useInput } from \"ink\";\n\nimport type { Category, SkillId } from \"../../types/index.js\";\nimport type { CategoryOption, CategoryRow } from \"../wizard/category-grid.js\";\nimport { HOTKEY_TOGGLE_LABELS, isHotkey } from \"../wizard/hotkeys.js\";\n\nconst FRAMEWORK_CATEGORY_ID = \"web-framework\";\n\n// Locked = non-framework section when no framework is selected\nexport const isSectionLocked = (categoryId: Category, categories: CategoryRow[]): boolean => {\n if (categoryId === FRAMEWORK_CATEGORY_ID) {\n return false;\n }\n\n const frameworkCategory = categories.find((cat) => cat.id === FRAMEWORK_CATEGORY_ID);\n if (!frameworkCategory) return false;\n\n return !frameworkCategory.options.some((opt) => opt.selected);\n};\n\nexport const findValidStartColumn = (_options: CategoryOption[]): number => {\n return 0;\n};\n\n/** Find next unlocked section index (wrapping, direction: forward) */\nexport const findNextUnlockedIndex = (\n processed: { id: Category; sortedOptions: CategoryOption[] }[],\n currentIndex: number,\n allCategories: CategoryRow[],\n): number => {\n const length = processed.length;\n if (length === 0) return currentIndex;\n\n let index = currentIndex;\n let attempts = 0;\n\n while (attempts < length) {\n index += 1;\n if (index >= length) index = 0;\n\n const category = processed[index];\n if (category && !isSectionLocked(category.id, allCategories)) {\n return index;\n }\n\n attempts++;\n }\n\n return currentIndex;\n};\n\ntype ProcessedCategory = CategoryRow & { sortedOptions: CategoryOption[] };\n\ntype UseCategoryGridInputOptions = {\n processedCategories: ProcessedCategory[];\n categories: CategoryRow[];\n focusedRow: number;\n focusedCol: number;\n setFocused: (row: number, col: number) => void;\n moveFocus: (direction: \"up\" | \"down\" | \"left\" | \"right\") => void;\n onToggle: (categoryId: Category, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n};\n\nexport function useCategoryGridInput({\n processedCategories,\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n}: UseCategoryGridInputOptions): void {\n const currentRow = processedCategories[focusedRow];\n const currentOptions = currentRow?.sortedOptions || [];\n const currentLocked = currentRow ? isSectionLocked(currentRow.id, categories) : false;\n\n // Adjust column when current row's options change externally (e.g. option becomes disabled)\n useEffect(() => {\n if (!currentRow) return;\n\n const maxCol = currentOptions.length - 1;\n if (focusedCol > maxCol) {\n const newCol = Math.max(0, maxCol);\n setFocused(focusedRow, newCol);\n }\n }, [focusedRow, currentOptions, focusedCol, setFocused, currentRow]);\n\n // Bounce off locked sections when a section becomes locked (e.g. framework deselected)\n useEffect(() => {\n if (currentRow && currentLocked) {\n const nextUnlocked = findNextUnlockedIndex(processedCategories, focusedRow, categories);\n if (nextUnlocked !== focusedRow) {\n const newRowOptions = processedCategories[nextUnlocked]?.sortedOptions || [];\n const newCol = findValidStartColumn(newRowOptions);\n setFocused(nextUnlocked, newCol);\n }\n }\n }, [currentRow, currentLocked, focusedRow, processedCategories, categories, setFocused]);\n\n // Store the latest handler in a ref so that the useInput effect never needs to\n // re-register on the event emitter. This avoids a stale-closure race condition\n // where, after a domain switch (CategoryGrid remount via key={activeDomain}),\n // the useInput effect may not yet have re-registered the updated handler when\n // the first keypress arrives — causing the first space press to be silently lost.\n type InputKey = {\n leftArrow: boolean;\n rightArrow: boolean;\n upArrow: boolean;\n downArrow: boolean;\n tab: boolean;\n shift: boolean;\n };\n\n const handlerRef = useRef<((input: string, key: InputKey) => void) | null>(null);\n handlerRef.current = (input: string, key: InputKey) => {\n if (key.tab && key.shift) {\n onToggleLabels();\n return;\n }\n\n if (key.tab && !key.shift) {\n const nextSection = findNextUnlockedIndex(processedCategories, focusedRow, categories);\n if (nextSection !== focusedRow) {\n const newRowOptions = processedCategories[nextSection]?.sortedOptions || [];\n const newCol = findValidStartColumn(newRowOptions);\n setFocused(nextSection, newCol);\n }\n return;\n }\n\n if (isHotkey(input, HOTKEY_TOGGLE_LABELS)) {\n onToggleLabels();\n return;\n }\n\n if (input === \" \") {\n if (currentLocked) return;\n const currentOption = currentOptions[focusedCol];\n if (currentOption) {\n onToggle(currentRow.id, currentOption.id);\n }\n return;\n }\n\n const isLeft = key.leftArrow || input === \"h\";\n const isRight = key.rightArrow || input === \"l\";\n const isUp = key.upArrow || input === \"k\";\n const isDown = key.downArrow || input === \"j\";\n\n if (isLeft) {\n if (currentLocked) return;\n moveFocus(\"left\");\n } else if (isRight) {\n if (currentLocked) return;\n moveFocus(\"right\");\n } else if (isUp) {\n moveFocus(\"up\");\n } else if (isDown) {\n moveFocus(\"down\");\n }\n };\n\n // Stable handler reference — never changes, so useInput's effect registers once\n const stableHandler = useCallback((input: string, key: InputKey) => {\n handlerRef.current?.(input, key);\n }, []);\n\n useInput(stableHandler);\n}\n"],"mappings":"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","names":["useCallback","useRef","useCallback","useRef"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getDomainDisplayName
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UBNHVBSV.js";
|
|
5
5
|
import {
|
|
6
6
|
ViewTitle
|
|
7
7
|
} from "./chunk-JNQKCZA3.js";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./chunk-CBYRFAUN.js";
|
|
12
12
|
import {
|
|
13
13
|
CLI_COLORS
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FMYAYX6W.js";
|
|
15
15
|
import {
|
|
16
16
|
init_esm_shims
|
|
17
17
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -123,4 +123,4 @@ var StepConfirm = ({
|
|
|
123
123
|
export {
|
|
124
124
|
StepConfirm
|
|
125
125
|
};
|
|
126
|
-
//# sourceMappingURL=chunk-
|
|
126
|
+
//# sourceMappingURL=chunk-7PMFIL5L.js.map
|