agents-inc 0.151.0 → 0.152.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 +22 -0
- package/README.md +25 -25
- package/dist/{chunk-YA4QQKKE.js → chunk-5GUOIJSG.js} +3 -7
- package/dist/{chunk-YA4QQKKE.js.map → chunk-5GUOIJSG.js.map} +1 -1
- package/dist/{chunk-44LLPS2N.js → chunk-5UWKOOIS.js} +6 -26
- package/dist/chunk-5UWKOOIS.js.map +1 -0
- package/dist/{chunk-O5ASLZ2K.js → chunk-76ADG7LQ.js} +1 -5
- package/dist/{chunk-O5ASLZ2K.js.map → chunk-76ADG7LQ.js.map} +1 -1
- package/dist/{chunk-WK4J2CHH.js → chunk-BNSRA6HL.js} +13 -18
- package/dist/{chunk-WK4J2CHH.js.map → chunk-BNSRA6HL.js.map} +1 -1
- package/dist/{chunk-FYPUUYSG.js → chunk-DTSG5XZB.js} +3 -7
- package/dist/{chunk-FYPUUYSG.js.map → chunk-DTSG5XZB.js.map} +1 -1
- package/dist/{chunk-NGLQ5W7U.js → chunk-E5X6RJ4E.js} +5 -15
- package/dist/chunk-E5X6RJ4E.js.map +1 -0
- package/dist/{chunk-TVHRMRD3.js → chunk-EEPELKOM.js} +4008 -4084
- package/dist/chunk-EEPELKOM.js.map +1 -0
- package/dist/{chunk-NIKUMXE7.js → chunk-F7T5AFFN.js} +1 -5
- package/dist/{chunk-NIKUMXE7.js.map → chunk-F7T5AFFN.js.map} +1 -1
- package/dist/{chunk-LAXAQ3PZ.js → chunk-FVDKAVOL.js} +10 -14
- package/dist/{chunk-LAXAQ3PZ.js.map → chunk-FVDKAVOL.js.map} +1 -1
- package/dist/{chunk-BNE4HHIH.js → chunk-GRVKW3CC.js} +2 -6
- package/dist/{chunk-BNE4HHIH.js.map → chunk-GRVKW3CC.js.map} +1 -1
- package/dist/{chunk-3XFUQ6OL.js → chunk-IHUY4M22.js} +4 -8
- package/dist/{chunk-3XFUQ6OL.js.map → chunk-IHUY4M22.js.map} +1 -1
- package/dist/{chunk-OZZGXBCN.js → chunk-IUQBOCSU.js} +1 -5
- package/dist/{chunk-OZZGXBCN.js.map → chunk-IUQBOCSU.js.map} +1 -1
- package/dist/{chunk-LYYXX2W5.js → chunk-J27W6TXS.js} +4 -6
- package/dist/{chunk-LYYXX2W5.js.map → chunk-J27W6TXS.js.map} +1 -1
- package/dist/chunk-JFLVEFFP.js +16 -0
- package/dist/chunk-JFLVEFFP.js.map +1 -0
- package/dist/{chunk-PV2HNW4I.js → chunk-KFB5CRXZ.js} +7 -12
- package/dist/{chunk-PV2HNW4I.js.map → chunk-KFB5CRXZ.js.map} +1 -1
- package/dist/{chunk-SYUOXSPU.js → chunk-KR65TPKC.js} +168 -14
- package/dist/chunk-KR65TPKC.js.map +1 -0
- package/dist/{chunk-KOPEM3Q7.js → chunk-KXYVJGJP.js} +2 -6
- package/dist/{chunk-KOPEM3Q7.js.map → chunk-KXYVJGJP.js.map} +1 -1
- package/dist/{chunk-TYJLR32W.js → chunk-L7SZXUBJ.js} +9 -14
- package/dist/{chunk-TYJLR32W.js.map → chunk-L7SZXUBJ.js.map} +1 -1
- package/dist/{chunk-NHCGC6DG.js → chunk-LASI35KT.js} +4 -9
- package/dist/{chunk-NHCGC6DG.js.map → chunk-LASI35KT.js.map} +1 -1
- package/dist/{chunk-VG2TVBFN.js → chunk-LDP5ASDM.js} +2 -6
- package/dist/{chunk-VG2TVBFN.js.map → chunk-LDP5ASDM.js.map} +1 -1
- package/dist/{chunk-5V2O6C3T.js → chunk-LZ52XEPR.js} +4 -8
- package/dist/{chunk-5V2O6C3T.js.map → chunk-LZ52XEPR.js.map} +1 -1
- package/dist/{chunk-WFWCZEMS.js → chunk-M7HO7NBK.js} +4 -8
- package/dist/{chunk-WFWCZEMS.js.map → chunk-M7HO7NBK.js.map} +1 -1
- package/dist/{chunk-XA57SX4T.js → chunk-MJ2KHG24.js} +4 -8
- package/dist/{chunk-XA57SX4T.js.map → chunk-MJ2KHG24.js.map} +1 -1
- package/dist/{chunk-DAG2ULNF.js → chunk-MM7CTTAV.js} +2 -6
- package/dist/chunk-MM7CTTAV.js.map +1 -0
- package/dist/{chunk-UFURYGD3.js → chunk-MQ7FLIYS.js} +2 -6
- package/dist/{chunk-UFURYGD3.js.map → chunk-MQ7FLIYS.js.map} +1 -1
- package/dist/{chunk-SI5FOARI.js → chunk-MVR3SYMN.js} +6 -8
- package/dist/chunk-MVR3SYMN.js.map +1 -0
- package/dist/{chunk-UTFN6UJS.js → chunk-MWG4VU64.js} +12 -17
- package/dist/{chunk-UTFN6UJS.js.map → chunk-MWG4VU64.js.map} +1 -1
- package/dist/{chunk-ES3NJZON.js → chunk-NR3OZGL4.js} +1 -5
- package/dist/{chunk-ES3NJZON.js.map → chunk-NR3OZGL4.js.map} +1 -1
- package/dist/{chunk-GYG5SE2D.js → chunk-ODNDXQH2.js} +2 -6
- package/dist/{chunk-GYG5SE2D.js.map → chunk-ODNDXQH2.js.map} +1 -1
- package/dist/{chunk-2RSNKBXC.js → chunk-P44SXVH3.js} +6 -10
- package/dist/{chunk-2RSNKBXC.js.map → chunk-P44SXVH3.js.map} +1 -1
- package/dist/{chunk-3LIU2ZEF.js → chunk-PMM2MYMA.js} +3 -16
- package/dist/{chunk-3LIU2ZEF.js.map → chunk-PMM2MYMA.js.map} +1 -1
- package/dist/{chunk-QTFQEYDA.js → chunk-PZIZNMHK.js} +24 -36
- package/dist/chunk-PZIZNMHK.js.map +1 -0
- package/dist/{chunk-C55DN7GE.js → chunk-Q2KG7UV3.js} +3 -5
- package/dist/chunk-Q2KG7UV3.js.map +1 -0
- package/dist/{chunk-QQLRX4KI.js → chunk-Q45ZU6HD.js} +2 -6
- package/dist/{chunk-QQLRX4KI.js.map → chunk-Q45ZU6HD.js.map} +1 -1
- package/dist/{chunk-6RBQBOBS.js → chunk-QRDTLVXG.js} +9 -14
- package/dist/{chunk-6RBQBOBS.js.map → chunk-QRDTLVXG.js.map} +1 -1
- package/dist/{chunk-YBVA7GPW.js → chunk-QZZJFYUQ.js} +3 -7
- package/dist/{chunk-YBVA7GPW.js.map → chunk-QZZJFYUQ.js.map} +1 -1
- package/dist/{chunk-OJIESW5B.js → chunk-R5NOI2LP.js} +13 -17
- package/dist/{chunk-OJIESW5B.js.map → chunk-R5NOI2LP.js.map} +1 -1
- package/dist/{chunk-DUVWGO6E.js → chunk-RNJWAKMO.js} +3 -7
- package/dist/{chunk-DUVWGO6E.js.map → chunk-RNJWAKMO.js.map} +1 -1
- package/dist/{chunk-4R6PGHQQ.js → chunk-SBHBBZKF.js} +7 -23
- package/dist/chunk-SBHBBZKF.js.map +1 -0
- package/dist/{chunk-NM3EDGB5.js → chunk-SKQWRUPX.js} +10 -14
- package/dist/{chunk-NM3EDGB5.js.map → chunk-SKQWRUPX.js.map} +1 -1
- package/dist/{chunk-Y4CXDA3I.js → chunk-STMHDOZD.js} +4 -21
- package/dist/chunk-STMHDOZD.js.map +1 -0
- package/dist/{chunk-SHHOMVWC.js → chunk-SX5H6TSC.js} +7 -11
- package/dist/chunk-SX5H6TSC.js.map +1 -0
- package/dist/{chunk-RBHYLCUB.js → chunk-TJJPWUMA.js} +2 -6
- package/dist/{chunk-RBHYLCUB.js.map → chunk-TJJPWUMA.js.map} +1 -1
- package/dist/{chunk-IOJR5TOY.js → chunk-TSIU7DME.js} +1 -5
- package/dist/{chunk-IOJR5TOY.js.map → chunk-TSIU7DME.js.map} +1 -1
- package/dist/{chunk-EVXG3X6G.js → chunk-TUPYW2IQ.js} +3 -7
- package/dist/{chunk-EVXG3X6G.js.map → chunk-TUPYW2IQ.js.map} +1 -1
- package/dist/{chunk-YU2VGX5R.js → chunk-UBEDZ4FD.js} +1 -8
- package/dist/{chunk-YU2VGX5R.js.map → chunk-UBEDZ4FD.js.map} +1 -1
- package/dist/{chunk-VEP23B5W.js → chunk-VASLW636.js} +1 -5
- package/dist/{chunk-VEP23B5W.js.map → chunk-VASLW636.js.map} +1 -1
- package/dist/{chunk-PG4G4IIK.js → chunk-VY6MNOXL.js} +2 -6
- package/dist/{chunk-PG4G4IIK.js.map → chunk-VY6MNOXL.js.map} +1 -1
- package/dist/{chunk-IHO75PMZ.js → chunk-WBCPLH66.js} +15 -13
- package/dist/chunk-WBCPLH66.js.map +1 -0
- package/dist/{chunk-DG2NGZ7S.js → chunk-WKTHWQKM.js} +2 -7
- package/dist/{chunk-DG2NGZ7S.js.map → chunk-WKTHWQKM.js.map} +1 -1
- package/dist/{chunk-EZ7STXUV.js → chunk-XHUODHZ4.js} +19 -25
- package/dist/{chunk-EZ7STXUV.js.map → chunk-XHUODHZ4.js.map} +1 -1
- package/dist/{chunk-KIR7VYQD.js → chunk-XVAQG2CV.js} +1 -5
- package/dist/{chunk-KIR7VYQD.js.map → chunk-XVAQG2CV.js.map} +1 -1
- package/dist/{chunk-P3PN5SVI.js → chunk-ZL7PFNHN.js} +2 -6
- package/dist/{chunk-P3PN5SVI.js.map → chunk-ZL7PFNHN.js.map} +1 -1
- package/dist/{chunk-3YGUHWLR.js → chunk-ZPPHXXAP.js} +9 -15
- package/dist/{chunk-3YGUHWLR.js.map → chunk-ZPPHXXAP.js.map} +1 -1
- package/dist/commands/build/marketplace.js +10 -15
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +9 -14
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +14 -19
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +13 -18
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +51 -55
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +13 -18
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +9 -14
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/init.js +50 -51
- package/dist/commands/list.js +14 -16
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +12 -16
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +15 -20
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +11 -13
- package/dist/commands/search.js +14 -19
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +17 -21
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +17 -21
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +10 -16
- package/dist/commands/validate.js.map +1 -1
- package/dist/components/common/confirm.js +1 -2
- package/dist/components/common/prompt-confirm.js +2 -2
- package/dist/components/common/select-list.js +3 -4
- package/dist/components/common/spinner.js +1 -2
- package/dist/components/wizard/category-grid.js +8 -9
- package/dist/components/wizard/checkbox-grid.js +6 -7
- package/dist/components/wizard/domain-selection.js +14 -15
- package/dist/components/wizard/run-wizard-session.js +40 -40
- package/dist/components/wizard/scroll-affordance.js +2 -3
- package/dist/components/wizard/search-modal.js +6 -7
- package/dist/components/wizard/selection-card.js +2 -3
- package/dist/components/wizard/skill-agent-summary.js +8 -9
- package/dist/components/wizard/source-grid.js +13 -14
- package/dist/components/wizard/stack-selection.js +12 -13
- package/dist/components/wizard/step-agents.js +14 -15
- package/dist/components/wizard/step-build.js +14 -15
- package/dist/components/wizard/step-confirm.js +13 -14
- package/dist/components/wizard/step-settings.js +11 -12
- package/dist/components/wizard/step-sources.js +20 -21
- package/dist/components/wizard/step-stack.js +13 -14
- package/dist/components/wizard/summary-panel.js +12 -13
- package/dist/components/wizard/toast.js +2 -3
- package/dist/components/wizard/wizard-layout.js +18 -19
- package/dist/components/wizard/wizard-tabs.js +8 -9
- package/dist/components/wizard/wizard.js +38 -39
- package/dist/config-exports.js +1 -7
- package/dist/config-exports.js.map +1 -1
- package/dist/copy-local-skills-6EMVN7RB.js +14 -0
- package/dist/hooks/init.js +50 -54
- package/dist/hooks/init.js.map +1 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/load-agent-defs-BWOUVEAR.js +15 -0
- package/dist/{loader-E2ERJYVA.js → loader-5JP4S7CJ.js} +4 -5
- package/dist/recompile-project-agents-6DL45TDI.js +19 -0
- package/dist/{source-loader-5UNRU7EZ.js → source-loader-MZYCPL2S.js} +7 -8
- package/dist/stores/wizard-store.js +7 -8
- package/package.json +15 -14
- package/dist/chunk-44LLPS2N.js.map +0 -1
- package/dist/chunk-4R6PGHQQ.js.map +0 -1
- package/dist/chunk-7QIHKQL5.js +0 -181
- package/dist/chunk-7QIHKQL5.js.map +0 -1
- package/dist/chunk-C55DN7GE.js.map +0 -1
- package/dist/chunk-DAG2ULNF.js.map +0 -1
- package/dist/chunk-DIBCRIMR.js +0 -36
- package/dist/chunk-DIBCRIMR.js.map +0 -1
- package/dist/chunk-EKWAUOQB.js +0 -96
- package/dist/chunk-EKWAUOQB.js.map +0 -1
- package/dist/chunk-I3XKEGHM.js +0 -16383
- package/dist/chunk-I3XKEGHM.js.map +0 -1
- package/dist/chunk-IHO75PMZ.js.map +0 -1
- package/dist/chunk-K3OU6TGX.js +0 -77
- package/dist/chunk-K3OU6TGX.js.map +0 -1
- package/dist/chunk-KSZ6PCY4.js +0 -43
- package/dist/chunk-KSZ6PCY4.js.map +0 -1
- package/dist/chunk-NGLQ5W7U.js.map +0 -1
- package/dist/chunk-P56WJ5FA.js +0 -50
- package/dist/chunk-P56WJ5FA.js.map +0 -1
- package/dist/chunk-QTFQEYDA.js.map +0 -1
- package/dist/chunk-SHHOMVWC.js.map +0 -1
- package/dist/chunk-SI5FOARI.js.map +0 -1
- package/dist/chunk-SYUOXSPU.js.map +0 -1
- package/dist/chunk-THKIOI32.js +0 -939
- package/dist/chunk-THKIOI32.js.map +0 -1
- package/dist/chunk-TVHRMRD3.js.map +0 -1
- package/dist/chunk-V7QOSGQA.js +0 -298
- package/dist/chunk-V7QOSGQA.js.map +0 -1
- package/dist/chunk-Y4CXDA3I.js.map +0 -1
- package/dist/components/common/confirm.test.js +0 -203
- package/dist/components/common/confirm.test.js.map +0 -1
- package/dist/components/wizard/category-grid.test.js +0 -1253
- package/dist/components/wizard/category-grid.test.js.map +0 -1
- package/dist/components/wizard/checkbox-grid.test.js +0 -264
- package/dist/components/wizard/checkbox-grid.test.js.map +0 -1
- package/dist/components/wizard/search-modal.test.js +0 -212
- package/dist/components/wizard/search-modal.test.js.map +0 -1
- package/dist/components/wizard/source-grid.test.js +0 -1094
- package/dist/components/wizard/source-grid.test.js.map +0 -1
- package/dist/components/wizard/step-agents.test.js +0 -204
- package/dist/components/wizard/step-agents.test.js.map +0 -1
- package/dist/components/wizard/step-build.test.js +0 -552
- package/dist/components/wizard/step-build.test.js.map +0 -1
- package/dist/components/wizard/step-confirm.test.js +0 -744
- package/dist/components/wizard/step-confirm.test.js.map +0 -1
- package/dist/components/wizard/step-settings.test.js +0 -244
- package/dist/components/wizard/step-settings.test.js.map +0 -1
- package/dist/components/wizard/step-sources.test.js +0 -155
- package/dist/components/wizard/step-sources.test.js.map +0 -1
- package/dist/components/wizard/step-stack.test.js +0 -262
- package/dist/components/wizard/step-stack.test.js.map +0 -1
- package/dist/components/wizard/summary-panel.test.js +0 -317
- package/dist/components/wizard/summary-panel.test.js.map +0 -1
- package/dist/components/wizard/wizard-layout.test.js +0 -200
- package/dist/components/wizard/wizard-layout.test.js.map +0 -1
- package/dist/components/wizard/wizard-tabs.test.js +0 -290
- package/dist/components/wizard/wizard-tabs.test.js.map +0 -1
- package/dist/copy-local-skills-UPA2GUZV.js +0 -15
- package/dist/dist-VNJNNJK7.js +0 -550
- package/dist/dist-VNJNNJK7.js.map +0 -1
- package/dist/load-agent-defs-SB4XAOVB.js +0 -16
- package/dist/magic-string.es-5TV73NJD.js +0 -1316
- package/dist/magic-string.es-5TV73NJD.js.map +0 -1
- package/dist/recompile-project-agents-U4ZY2GDX.js +0 -20
- package/dist/source-manager-3O54SIIB.js +0 -18
- package/dist/source-manager-3O54SIIB.js.map +0 -1
- package/dist/stores/d227-same-scope-tombstone-duplicate.test.js +0 -118
- package/dist/stores/d227-same-scope-tombstone-duplicate.test.js.map +0 -1
- package/dist/stores/wizard-store.test.js +0 -3053
- package/dist/stores/wizard-store.test.js.map +0 -1
- /package/dist/{copy-local-skills-UPA2GUZV.js.map → copy-local-skills-6EMVN7RB.js.map} +0 -0
- /package/dist/{load-agent-defs-SB4XAOVB.js.map → load-agent-defs-BWOUVEAR.js.map} +0 -0
- /package/dist/{loader-E2ERJYVA.js.map → loader-5JP4S7CJ.js.map} +0 -0
- /package/dist/{recompile-project-agents-U4ZY2GDX.js.map → recompile-project-agents-6DL45TDI.js.map} +0 -0
- /package/dist/{source-loader-5UNRU7EZ.js.map → source-loader-MZYCPL2S.js.map} +0 -0
|
@@ -1,1094 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
ARROW_DOWN,
|
|
4
|
-
ARROW_LEFT,
|
|
5
|
-
ARROW_RIGHT,
|
|
6
|
-
ARROW_UP,
|
|
7
|
-
ENTER,
|
|
8
|
-
ESCAPE,
|
|
9
|
-
INPUT_DELAY_MS,
|
|
10
|
-
RENDER_DELAY_MS,
|
|
11
|
-
SPACE,
|
|
12
|
-
delay
|
|
13
|
-
} from "../../chunk-KSZ6PCY4.js";
|
|
14
|
-
import {
|
|
15
|
-
render
|
|
16
|
-
} from "../../chunk-EKWAUOQB.js";
|
|
17
|
-
import {
|
|
18
|
-
WEB_TRIO_MATRIX
|
|
19
|
-
} from "../../chunk-THKIOI32.js";
|
|
20
|
-
import "../../chunk-K3OU6TGX.js";
|
|
21
|
-
import {
|
|
22
|
-
createMockMatrix,
|
|
23
|
-
createMockSkill
|
|
24
|
-
} from "../../chunk-V7QOSGQA.js";
|
|
25
|
-
import {
|
|
26
|
-
afterEach,
|
|
27
|
-
beforeEach,
|
|
28
|
-
describe,
|
|
29
|
-
globalExpect,
|
|
30
|
-
it,
|
|
31
|
-
vi
|
|
32
|
-
} from "../../chunk-I3XKEGHM.js";
|
|
33
|
-
import {
|
|
34
|
-
SourceGrid
|
|
35
|
-
} from "../../chunk-WK4J2CHH.js";
|
|
36
|
-
import "../../chunk-NIKUMXE7.js";
|
|
37
|
-
import "../../chunk-KOPEM3Q7.js";
|
|
38
|
-
import "../../chunk-2RSNKBXC.js";
|
|
39
|
-
import "../../chunk-DUVWGO6E.js";
|
|
40
|
-
import "../../chunk-KIR7VYQD.js";
|
|
41
|
-
import "../../chunk-LYYXX2W5.js";
|
|
42
|
-
import "../../chunk-DAG2ULNF.js";
|
|
43
|
-
import "../../chunk-VG2TVBFN.js";
|
|
44
|
-
import "../../chunk-IHO75PMZ.js";
|
|
45
|
-
import {
|
|
46
|
-
source_default
|
|
47
|
-
} from "../../chunk-SYUOXSPU.js";
|
|
48
|
-
import {
|
|
49
|
-
BUILT_IN_MATRIX,
|
|
50
|
-
getSkillById,
|
|
51
|
-
initializeMatrix
|
|
52
|
-
} from "../../chunk-DG2NGZ7S.js";
|
|
53
|
-
import "../../chunk-VEP23B5W.js";
|
|
54
|
-
import {
|
|
55
|
-
CLI_COLORS,
|
|
56
|
-
UI_SYMBOLS
|
|
57
|
-
} from "../../chunk-O5ASLZ2K.js";
|
|
58
|
-
import {
|
|
59
|
-
init_esm_shims
|
|
60
|
-
} from "../../chunk-P56WJ5FA.js";
|
|
61
|
-
|
|
62
|
-
// src/cli/components/wizard/source-grid.test.tsx
|
|
63
|
-
init_esm_shims();
|
|
64
|
-
import { jsx } from "react/jsx-runtime";
|
|
65
|
-
var TRUECOLOR_CHALK_LEVEL = 3;
|
|
66
|
-
var createSourceOption = (id, overrides = {}) => ({
|
|
67
|
-
id,
|
|
68
|
-
selected: false,
|
|
69
|
-
installed: false,
|
|
70
|
-
...overrides
|
|
71
|
-
});
|
|
72
|
-
var createSourceRow = (skillId, options, scope, readOnly) => ({
|
|
73
|
-
skillId,
|
|
74
|
-
options,
|
|
75
|
-
scope,
|
|
76
|
-
...readOnly ? { readOnly } : {}
|
|
77
|
-
});
|
|
78
|
-
var createRemovedRow = (skillId, options, scope) => ({
|
|
79
|
-
...createSourceRow(skillId, options, scope),
|
|
80
|
-
disabled: true
|
|
81
|
-
});
|
|
82
|
-
var createAddedRow = (skillId, options, scope) => ({
|
|
83
|
-
...createSourceRow(skillId, options, scope),
|
|
84
|
-
added: true
|
|
85
|
-
});
|
|
86
|
-
var defaultRows = [
|
|
87
|
-
createSourceRow("web-framework-react", [createSourceOption("public", { selected: true })]),
|
|
88
|
-
createSourceRow("web-state-zustand", [createSourceOption("public", { selected: true })]),
|
|
89
|
-
createSourceRow("web-testing-vitest", [createSourceOption("public", { selected: true })])
|
|
90
|
-
];
|
|
91
|
-
var multiSourceRows = [
|
|
92
|
-
createSourceRow("web-framework-react", [
|
|
93
|
-
createSourceOption("public", { selected: true }),
|
|
94
|
-
createSourceOption("acme-corp")
|
|
95
|
-
]),
|
|
96
|
-
createSourceRow("web-state-zustand", [
|
|
97
|
-
createSourceOption("public", { selected: true }),
|
|
98
|
-
createSourceOption("acme-corp"),
|
|
99
|
-
createSourceOption("internal")
|
|
100
|
-
])
|
|
101
|
-
];
|
|
102
|
-
var defaultProps = {
|
|
103
|
-
rows: defaultRows,
|
|
104
|
-
defaultFocusedRow: 0,
|
|
105
|
-
defaultFocusedCol: 0,
|
|
106
|
-
onSelect: vi.fn(),
|
|
107
|
-
onFocusChange: vi.fn()
|
|
108
|
-
};
|
|
109
|
-
var renderGrid = (props = {}) => {
|
|
110
|
-
return render(/* @__PURE__ */ jsx(SourceGrid, { ...defaultProps, ...props }));
|
|
111
|
-
};
|
|
112
|
-
describe("SourceGrid component", () => {
|
|
113
|
-
let cleanup;
|
|
114
|
-
beforeEach(() => {
|
|
115
|
-
initializeMatrix(WEB_TRIO_MATRIX);
|
|
116
|
-
});
|
|
117
|
-
afterEach(() => {
|
|
118
|
-
cleanup?.();
|
|
119
|
-
cleanup = void 0;
|
|
120
|
-
initializeMatrix(BUILT_IN_MATRIX);
|
|
121
|
-
});
|
|
122
|
-
describe("rendering", () => {
|
|
123
|
-
it("should render all skill rows", () => {
|
|
124
|
-
const { lastFrame, unmount } = renderGrid();
|
|
125
|
-
cleanup = unmount;
|
|
126
|
-
const output = lastFrame();
|
|
127
|
-
globalExpect(output).toContain("React");
|
|
128
|
-
globalExpect(output).toContain("Zustand");
|
|
129
|
-
globalExpect(output).toContain("Vitest");
|
|
130
|
-
});
|
|
131
|
-
it("should render source option labels", () => {
|
|
132
|
-
const { lastFrame, unmount } = renderGrid();
|
|
133
|
-
cleanup = unmount;
|
|
134
|
-
const output = lastFrame();
|
|
135
|
-
globalExpect(output).toContain("Public");
|
|
136
|
-
});
|
|
137
|
-
it("should render multiple source options per row", () => {
|
|
138
|
-
const { lastFrame, unmount } = renderGrid({ rows: multiSourceRows });
|
|
139
|
-
cleanup = unmount;
|
|
140
|
-
const output = lastFrame();
|
|
141
|
-
globalExpect(output).toContain("Public");
|
|
142
|
-
globalExpect(output).toContain("acme-corp");
|
|
143
|
-
});
|
|
144
|
-
it("should handle empty rows array", () => {
|
|
145
|
-
const { lastFrame, unmount } = renderGrid({ rows: [] });
|
|
146
|
-
cleanup = unmount;
|
|
147
|
-
const output = lastFrame();
|
|
148
|
-
globalExpect(output).toContain("No skills to display");
|
|
149
|
-
});
|
|
150
|
-
it("should render single row", () => {
|
|
151
|
-
const rows = [
|
|
152
|
-
createSourceRow("web-framework-react", [createSourceOption("public", { selected: true })])
|
|
153
|
-
];
|
|
154
|
-
const { lastFrame, unmount } = renderGrid({ rows });
|
|
155
|
-
cleanup = unmount;
|
|
156
|
-
const output = lastFrame();
|
|
157
|
-
globalExpect(output).toContain("React");
|
|
158
|
-
globalExpect(output).toContain("Public");
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
describe("scope-grouped rendering", () => {
|
|
162
|
-
it("should head each scope block with its own row header and caption no column", () => {
|
|
163
|
-
const rows = [
|
|
164
|
-
createSourceRow(
|
|
165
|
-
"web-framework-react",
|
|
166
|
-
[createSourceOption("public", { selected: true })],
|
|
167
|
-
"global"
|
|
168
|
-
),
|
|
169
|
-
createSourceRow(
|
|
170
|
-
"web-state-zustand",
|
|
171
|
-
[createSourceOption("public", { selected: true })],
|
|
172
|
-
"project"
|
|
173
|
-
)
|
|
174
|
-
];
|
|
175
|
-
const { lastFrame, unmount } = renderGrid({ rows });
|
|
176
|
-
cleanup = unmount;
|
|
177
|
-
const output = lastFrame();
|
|
178
|
-
globalExpect(output).toContain("React");
|
|
179
|
-
globalExpect(output).toContain("Zustand");
|
|
180
|
-
globalExpect(output).toContain("Global");
|
|
181
|
-
globalExpect(output).toContain("Project");
|
|
182
|
-
globalExpect(output).not.toContain("Scope");
|
|
183
|
-
});
|
|
184
|
-
it("should show global rows before project rows", () => {
|
|
185
|
-
const rows = [
|
|
186
|
-
createSourceRow(
|
|
187
|
-
"web-state-zustand",
|
|
188
|
-
[createSourceOption("public", { selected: true })],
|
|
189
|
-
"project"
|
|
190
|
-
),
|
|
191
|
-
createSourceRow(
|
|
192
|
-
"web-framework-react",
|
|
193
|
-
[createSourceOption("public", { selected: true })],
|
|
194
|
-
"global"
|
|
195
|
-
)
|
|
196
|
-
];
|
|
197
|
-
const { lastFrame, unmount } = renderGrid({ rows });
|
|
198
|
-
cleanup = unmount;
|
|
199
|
-
const output = lastFrame();
|
|
200
|
-
const globalPos = output.indexOf("React");
|
|
201
|
-
const projectPos = output.indexOf("Zustand");
|
|
202
|
-
globalExpect(globalPos).toBeGreaterThan(-1);
|
|
203
|
-
globalExpect(projectPos).toBeGreaterThan(-1);
|
|
204
|
-
globalExpect(globalPos).toBeLessThan(projectPos);
|
|
205
|
-
});
|
|
206
|
-
it("heads each block in the gutter and lines the source captions up with their cells", () => {
|
|
207
|
-
const rows = [
|
|
208
|
-
createSourceRow(
|
|
209
|
-
"web-framework-react",
|
|
210
|
-
[createSourceOption("eject"), createSourceOption("agents-inc", { selected: true })],
|
|
211
|
-
"global"
|
|
212
|
-
),
|
|
213
|
-
createSourceRow(
|
|
214
|
-
"web-state-zustand",
|
|
215
|
-
[createSourceOption("eject", { selected: true }), createSourceOption("agents-inc")],
|
|
216
|
-
"project"
|
|
217
|
-
)
|
|
218
|
-
];
|
|
219
|
-
const { lastFrame, unmount } = renderGrid({ rows });
|
|
220
|
-
cleanup = unmount;
|
|
221
|
-
globalExpect(lastFrame()).toMatchInlineSnapshot(`
|
|
222
|
-
" Local Plugin
|
|
223
|
-
|
|
224
|
-
Global React \u276F Eject Agents Inc
|
|
225
|
-
|
|
226
|
-
Project Zustand Eject Agents Inc"
|
|
227
|
-
`);
|
|
228
|
-
});
|
|
229
|
-
it("renders one unseparated block in the flat layout", () => {
|
|
230
|
-
const rows = [
|
|
231
|
-
createSourceRow(
|
|
232
|
-
"web-framework-react",
|
|
233
|
-
[createSourceOption("eject"), createSourceOption("agents-inc", { selected: true })],
|
|
234
|
-
"project"
|
|
235
|
-
),
|
|
236
|
-
createSourceRow(
|
|
237
|
-
"web-state-zustand",
|
|
238
|
-
[createSourceOption("eject", { selected: true }), createSourceOption("agents-inc")],
|
|
239
|
-
"project"
|
|
240
|
-
)
|
|
241
|
-
];
|
|
242
|
-
const { lastFrame, unmount } = renderGrid({ rows });
|
|
243
|
-
cleanup = unmount;
|
|
244
|
-
globalExpect(lastFrame()).toMatchInlineSnapshot(`
|
|
245
|
-
" Local Plugin
|
|
246
|
-
|
|
247
|
-
React \u276F Eject Agents Inc
|
|
248
|
-
Zustand Eject Agents Inc"
|
|
249
|
-
`);
|
|
250
|
-
});
|
|
251
|
-
it("renders one unseparated block when no row has a scope", () => {
|
|
252
|
-
const rows = [
|
|
253
|
-
createSourceRow("web-framework-react", [
|
|
254
|
-
createSourceOption("eject"),
|
|
255
|
-
createSourceOption("agents-inc", { selected: true })
|
|
256
|
-
]),
|
|
257
|
-
createSourceRow("web-state-zustand", [
|
|
258
|
-
createSourceOption("eject", { selected: true }),
|
|
259
|
-
createSourceOption("agents-inc")
|
|
260
|
-
])
|
|
261
|
-
];
|
|
262
|
-
const { lastFrame, unmount } = renderGrid({ rows });
|
|
263
|
-
cleanup = unmount;
|
|
264
|
-
globalExpect(lastFrame()).toMatchInlineSnapshot(`
|
|
265
|
-
" Local Plugin
|
|
266
|
-
|
|
267
|
-
React \u276F Eject Agents Inc
|
|
268
|
-
Zustand Eject Agents Inc"
|
|
269
|
-
`);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
describe("keyboard navigation - vertical", () => {
|
|
273
|
-
it("should move down with arrow down", async () => {
|
|
274
|
-
const onFocusChange = vi.fn();
|
|
275
|
-
const { stdin, unmount } = renderGrid({
|
|
276
|
-
defaultFocusedRow: 0,
|
|
277
|
-
defaultFocusedCol: 0,
|
|
278
|
-
onFocusChange
|
|
279
|
-
});
|
|
280
|
-
cleanup = unmount;
|
|
281
|
-
await delay(RENDER_DELAY_MS);
|
|
282
|
-
stdin.write(ARROW_DOWN);
|
|
283
|
-
await delay(INPUT_DELAY_MS);
|
|
284
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(1, 0);
|
|
285
|
-
});
|
|
286
|
-
it("should move up with arrow up", async () => {
|
|
287
|
-
const onFocusChange = vi.fn();
|
|
288
|
-
const { stdin, unmount } = renderGrid({
|
|
289
|
-
defaultFocusedRow: 1,
|
|
290
|
-
defaultFocusedCol: 0,
|
|
291
|
-
onFocusChange
|
|
292
|
-
});
|
|
293
|
-
cleanup = unmount;
|
|
294
|
-
await delay(RENDER_DELAY_MS);
|
|
295
|
-
stdin.write(ARROW_UP);
|
|
296
|
-
await delay(INPUT_DELAY_MS);
|
|
297
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
|
|
298
|
-
});
|
|
299
|
-
it("should wrap down to first row from last row", async () => {
|
|
300
|
-
const onFocusChange = vi.fn();
|
|
301
|
-
const { stdin, unmount } = renderGrid({
|
|
302
|
-
defaultFocusedRow: 2,
|
|
303
|
-
// Last row (Vitest)
|
|
304
|
-
defaultFocusedCol: 0,
|
|
305
|
-
onFocusChange
|
|
306
|
-
});
|
|
307
|
-
cleanup = unmount;
|
|
308
|
-
await delay(RENDER_DELAY_MS);
|
|
309
|
-
stdin.write(ARROW_DOWN);
|
|
310
|
-
await delay(INPUT_DELAY_MS);
|
|
311
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
|
|
312
|
-
});
|
|
313
|
-
it("should wrap up to last row from first row", async () => {
|
|
314
|
-
const onFocusChange = vi.fn();
|
|
315
|
-
const { stdin, unmount } = renderGrid({
|
|
316
|
-
defaultFocusedRow: 0,
|
|
317
|
-
defaultFocusedCol: 0,
|
|
318
|
-
onFocusChange
|
|
319
|
-
});
|
|
320
|
-
cleanup = unmount;
|
|
321
|
-
await delay(RENDER_DELAY_MS);
|
|
322
|
-
stdin.write(ARROW_UP);
|
|
323
|
-
await delay(INPUT_DELAY_MS);
|
|
324
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(2, 0);
|
|
325
|
-
});
|
|
326
|
-
it("should clamp column when moving to row with fewer options", async () => {
|
|
327
|
-
const onFocusChange = vi.fn();
|
|
328
|
-
const { stdin, unmount } = renderGrid({
|
|
329
|
-
rows: multiSourceRows,
|
|
330
|
-
defaultFocusedRow: 1,
|
|
331
|
-
// Zustand has 3 options
|
|
332
|
-
defaultFocusedCol: 2,
|
|
333
|
-
// Internal (index 2)
|
|
334
|
-
onFocusChange
|
|
335
|
-
});
|
|
336
|
-
cleanup = unmount;
|
|
337
|
-
await delay(RENDER_DELAY_MS);
|
|
338
|
-
stdin.write(ARROW_UP);
|
|
339
|
-
await delay(INPUT_DELAY_MS);
|
|
340
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
describe("keyboard navigation - horizontal", () => {
|
|
344
|
-
it("should move right with arrow right", async () => {
|
|
345
|
-
const onFocusChange = vi.fn();
|
|
346
|
-
const { stdin, unmount } = renderGrid({
|
|
347
|
-
rows: multiSourceRows,
|
|
348
|
-
defaultFocusedRow: 0,
|
|
349
|
-
defaultFocusedCol: 0,
|
|
350
|
-
onFocusChange
|
|
351
|
-
});
|
|
352
|
-
cleanup = unmount;
|
|
353
|
-
await delay(RENDER_DELAY_MS);
|
|
354
|
-
stdin.write(ARROW_RIGHT);
|
|
355
|
-
await delay(INPUT_DELAY_MS);
|
|
356
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
|
|
357
|
-
});
|
|
358
|
-
it("should move left with arrow left", async () => {
|
|
359
|
-
const onFocusChange = vi.fn();
|
|
360
|
-
const { stdin, unmount } = renderGrid({
|
|
361
|
-
rows: multiSourceRows,
|
|
362
|
-
defaultFocusedRow: 0,
|
|
363
|
-
defaultFocusedCol: 1,
|
|
364
|
-
onFocusChange
|
|
365
|
-
});
|
|
366
|
-
cleanup = unmount;
|
|
367
|
-
await delay(RENDER_DELAY_MS);
|
|
368
|
-
stdin.write(ARROW_LEFT);
|
|
369
|
-
await delay(INPUT_DELAY_MS);
|
|
370
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
|
|
371
|
-
});
|
|
372
|
-
it("should wrap right to first column from last column", async () => {
|
|
373
|
-
const onFocusChange = vi.fn();
|
|
374
|
-
const { stdin, unmount } = renderGrid({
|
|
375
|
-
rows: multiSourceRows,
|
|
376
|
-
defaultFocusedRow: 0,
|
|
377
|
-
defaultFocusedCol: 1,
|
|
378
|
-
// Last option in React row
|
|
379
|
-
onFocusChange
|
|
380
|
-
});
|
|
381
|
-
cleanup = unmount;
|
|
382
|
-
await delay(RENDER_DELAY_MS);
|
|
383
|
-
stdin.write(ARROW_RIGHT);
|
|
384
|
-
await delay(INPUT_DELAY_MS);
|
|
385
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
|
|
386
|
-
});
|
|
387
|
-
it("should wrap left to last column from first column", async () => {
|
|
388
|
-
const onFocusChange = vi.fn();
|
|
389
|
-
const { stdin, unmount } = renderGrid({
|
|
390
|
-
rows: multiSourceRows,
|
|
391
|
-
defaultFocusedRow: 0,
|
|
392
|
-
defaultFocusedCol: 0,
|
|
393
|
-
onFocusChange
|
|
394
|
-
});
|
|
395
|
-
cleanup = unmount;
|
|
396
|
-
await delay(RENDER_DELAY_MS);
|
|
397
|
-
stdin.write(ARROW_LEFT);
|
|
398
|
-
await delay(INPUT_DELAY_MS);
|
|
399
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
|
|
400
|
-
});
|
|
401
|
-
});
|
|
402
|
-
describe("selection", () => {
|
|
403
|
-
it("should call onSelect when pressing space", async () => {
|
|
404
|
-
const onSelect = vi.fn();
|
|
405
|
-
const { stdin, unmount } = renderGrid({
|
|
406
|
-
defaultFocusedRow: 0,
|
|
407
|
-
defaultFocusedCol: 0,
|
|
408
|
-
onSelect
|
|
409
|
-
});
|
|
410
|
-
cleanup = unmount;
|
|
411
|
-
await delay(RENDER_DELAY_MS);
|
|
412
|
-
stdin.write(" ");
|
|
413
|
-
await delay(INPUT_DELAY_MS);
|
|
414
|
-
globalExpect(onSelect).toHaveBeenCalledWith("web-framework-react", "public");
|
|
415
|
-
});
|
|
416
|
-
it("should call onSelect with correct skill and source IDs", async () => {
|
|
417
|
-
const onSelect = vi.fn();
|
|
418
|
-
const { stdin, unmount } = renderGrid({
|
|
419
|
-
rows: multiSourceRows,
|
|
420
|
-
defaultFocusedRow: 0,
|
|
421
|
-
defaultFocusedCol: 1,
|
|
422
|
-
// Acme Corp
|
|
423
|
-
onSelect
|
|
424
|
-
});
|
|
425
|
-
cleanup = unmount;
|
|
426
|
-
await delay(RENDER_DELAY_MS);
|
|
427
|
-
stdin.write(" ");
|
|
428
|
-
await delay(INPUT_DELAY_MS);
|
|
429
|
-
globalExpect(onSelect).toHaveBeenCalledWith("web-framework-react", "acme-corp");
|
|
430
|
-
});
|
|
431
|
-
it("should call onSelect on second row", async () => {
|
|
432
|
-
const onSelect = vi.fn();
|
|
433
|
-
const { stdin, unmount } = renderGrid({
|
|
434
|
-
rows: multiSourceRows,
|
|
435
|
-
defaultFocusedRow: 1,
|
|
436
|
-
defaultFocusedCol: 2,
|
|
437
|
-
// Internal
|
|
438
|
-
onSelect
|
|
439
|
-
});
|
|
440
|
-
cleanup = unmount;
|
|
441
|
-
await delay(RENDER_DELAY_MS);
|
|
442
|
-
stdin.write(" ");
|
|
443
|
-
await delay(INPUT_DELAY_MS);
|
|
444
|
-
globalExpect(onSelect).toHaveBeenCalledWith("web-state-zustand", "internal");
|
|
445
|
-
});
|
|
446
|
-
});
|
|
447
|
-
describe("edge cases", () => {
|
|
448
|
-
it("should handle single option per row", async () => {
|
|
449
|
-
const onFocusChange = vi.fn();
|
|
450
|
-
const { stdin, unmount } = renderGrid({
|
|
451
|
-
defaultFocusedRow: 0,
|
|
452
|
-
defaultFocusedCol: 0,
|
|
453
|
-
onFocusChange
|
|
454
|
-
});
|
|
455
|
-
cleanup = unmount;
|
|
456
|
-
await delay(RENDER_DELAY_MS);
|
|
457
|
-
stdin.write(ARROW_RIGHT);
|
|
458
|
-
await delay(INPUT_DELAY_MS);
|
|
459
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
|
|
460
|
-
});
|
|
461
|
-
it("should handle many rows", () => {
|
|
462
|
-
const skillIds = [
|
|
463
|
-
"web-framework-react",
|
|
464
|
-
"web-framework-vue-composition-api",
|
|
465
|
-
"web-styling-tailwind",
|
|
466
|
-
"web-styling-scss-modules",
|
|
467
|
-
"web-state-zustand",
|
|
468
|
-
"web-state-mobx",
|
|
469
|
-
"web-testing-vitest",
|
|
470
|
-
"web-testing-playwright-e2e",
|
|
471
|
-
"web-server-state-react-query",
|
|
472
|
-
"web-tooling-vite"
|
|
473
|
-
];
|
|
474
|
-
const skills = Object.fromEntries(skillIds.map((id) => [id, createMockSkill(id)]));
|
|
475
|
-
initializeMatrix(createMockMatrix(skills));
|
|
476
|
-
const rows = skillIds.map(
|
|
477
|
-
(id) => createSourceRow(id, [createSourceOption("public", { selected: true })])
|
|
478
|
-
);
|
|
479
|
-
const { lastFrame, unmount } = renderGrid({ rows });
|
|
480
|
-
cleanup = unmount;
|
|
481
|
-
const output = lastFrame();
|
|
482
|
-
globalExpect(output).toContain("React");
|
|
483
|
-
globalExpect(output).toContain("Vite");
|
|
484
|
-
});
|
|
485
|
-
});
|
|
486
|
-
describe("search pill", () => {
|
|
487
|
-
const mockSearch = vi.fn();
|
|
488
|
-
const mockBind = vi.fn();
|
|
489
|
-
const mockSearchStateChange = vi.fn();
|
|
490
|
-
const searchCandidates = [
|
|
491
|
-
{
|
|
492
|
-
id: "web-framework-react-pro",
|
|
493
|
-
sourceUrl: "github:awesome-dev/skills",
|
|
494
|
-
sourceName: "awesome-dev",
|
|
495
|
-
alias: "react"
|
|
496
|
-
},
|
|
497
|
-
{
|
|
498
|
-
id: "web-framework-react-strict",
|
|
499
|
-
sourceUrl: "github:team-xyz/skills",
|
|
500
|
-
sourceName: "team-xyz",
|
|
501
|
-
alias: "react"
|
|
502
|
-
}
|
|
503
|
-
];
|
|
504
|
-
afterEach(() => {
|
|
505
|
-
mockSearch.mockReset();
|
|
506
|
-
mockBind.mockReset();
|
|
507
|
-
mockSearchStateChange.mockReset();
|
|
508
|
-
});
|
|
509
|
-
it("should render search pill at end of each row when onSearch is provided", () => {
|
|
510
|
-
const { lastFrame, unmount } = renderGrid({
|
|
511
|
-
onSearch: mockSearch
|
|
512
|
-
});
|
|
513
|
-
cleanup = unmount;
|
|
514
|
-
const output = lastFrame();
|
|
515
|
-
globalExpect(output).toContain("Search");
|
|
516
|
-
});
|
|
517
|
-
it("should not render search pill when onSearch is not provided", () => {
|
|
518
|
-
const { lastFrame, unmount } = renderGrid();
|
|
519
|
-
cleanup = unmount;
|
|
520
|
-
const output = lastFrame();
|
|
521
|
-
globalExpect(output).not.toContain("Search");
|
|
522
|
-
});
|
|
523
|
-
it("should navigate to search pill with arrow right", async () => {
|
|
524
|
-
const onFocusChange = vi.fn();
|
|
525
|
-
const { stdin, unmount } = renderGrid({
|
|
526
|
-
rows: defaultRows,
|
|
527
|
-
defaultFocusedRow: 0,
|
|
528
|
-
defaultFocusedCol: 0,
|
|
529
|
-
// On the only option (Public)
|
|
530
|
-
onFocusChange,
|
|
531
|
-
onSearch: mockSearch
|
|
532
|
-
});
|
|
533
|
-
cleanup = unmount;
|
|
534
|
-
await delay(RENDER_DELAY_MS);
|
|
535
|
-
stdin.write(ARROW_RIGHT);
|
|
536
|
-
await delay(INPUT_DELAY_MS);
|
|
537
|
-
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
|
|
538
|
-
});
|
|
539
|
-
it("should not call onSelect when space is pressed on search pill", async () => {
|
|
540
|
-
const onSelect = vi.fn();
|
|
541
|
-
const { stdin, unmount } = renderGrid({
|
|
542
|
-
rows: defaultRows,
|
|
543
|
-
defaultFocusedRow: 0,
|
|
544
|
-
defaultFocusedCol: 1,
|
|
545
|
-
// Search pill position (after Public)
|
|
546
|
-
onSelect,
|
|
547
|
-
onSearch: mockSearch
|
|
548
|
-
});
|
|
549
|
-
cleanup = unmount;
|
|
550
|
-
await delay(RENDER_DELAY_MS);
|
|
551
|
-
stdin.write(" ");
|
|
552
|
-
await delay(INPUT_DELAY_MS);
|
|
553
|
-
globalExpect(onSelect).not.toHaveBeenCalled();
|
|
554
|
-
});
|
|
555
|
-
it("should trigger search on Space when search pill is focused", async () => {
|
|
556
|
-
mockSearch.mockResolvedValue(searchCandidates);
|
|
557
|
-
const { stdin, unmount } = renderGrid({
|
|
558
|
-
rows: defaultRows,
|
|
559
|
-
defaultFocusedRow: 0,
|
|
560
|
-
defaultFocusedCol: 1,
|
|
561
|
-
// Search pill position
|
|
562
|
-
onSearch: mockSearch,
|
|
563
|
-
onSearchStateChange: mockSearchStateChange
|
|
564
|
-
});
|
|
565
|
-
cleanup = unmount;
|
|
566
|
-
await delay(RENDER_DELAY_MS);
|
|
567
|
-
stdin.write(SPACE);
|
|
568
|
-
await delay(INPUT_DELAY_MS);
|
|
569
|
-
globalExpect(mockSearch).toHaveBeenCalledWith("react");
|
|
570
|
-
globalExpect(mockSearchStateChange).toHaveBeenCalledWith(true);
|
|
571
|
-
});
|
|
572
|
-
it("should render modal with results after search completes", async () => {
|
|
573
|
-
mockSearch.mockResolvedValue(searchCandidates);
|
|
574
|
-
const { stdin, lastFrame, unmount } = renderGrid({
|
|
575
|
-
rows: defaultRows,
|
|
576
|
-
defaultFocusedRow: 0,
|
|
577
|
-
defaultFocusedCol: 1,
|
|
578
|
-
onSearch: mockSearch
|
|
579
|
-
});
|
|
580
|
-
cleanup = unmount;
|
|
581
|
-
await delay(RENDER_DELAY_MS);
|
|
582
|
-
stdin.write(SPACE);
|
|
583
|
-
await delay(RENDER_DELAY_MS);
|
|
584
|
-
const output = lastFrame();
|
|
585
|
-
globalExpect(output).toContain("react");
|
|
586
|
-
globalExpect(output).toContain("awesome-dev");
|
|
587
|
-
globalExpect(output).toContain("team-xyz");
|
|
588
|
-
});
|
|
589
|
-
it("should close modal on Escape without binding", async () => {
|
|
590
|
-
mockSearch.mockResolvedValue(searchCandidates);
|
|
591
|
-
const { stdin, lastFrame, unmount } = renderGrid({
|
|
592
|
-
rows: defaultRows,
|
|
593
|
-
defaultFocusedRow: 0,
|
|
594
|
-
defaultFocusedCol: 1,
|
|
595
|
-
onSearch: mockSearch,
|
|
596
|
-
onBind: mockBind,
|
|
597
|
-
onSearchStateChange: mockSearchStateChange
|
|
598
|
-
});
|
|
599
|
-
cleanup = unmount;
|
|
600
|
-
await delay(RENDER_DELAY_MS);
|
|
601
|
-
stdin.write(SPACE);
|
|
602
|
-
await delay(RENDER_DELAY_MS);
|
|
603
|
-
stdin.write(ESCAPE);
|
|
604
|
-
await delay(INPUT_DELAY_MS);
|
|
605
|
-
globalExpect(mockBind).not.toHaveBeenCalled();
|
|
606
|
-
globalExpect(mockSearchStateChange).toHaveBeenLastCalledWith(false);
|
|
607
|
-
const output = lastFrame();
|
|
608
|
-
globalExpect(output).not.toContain("awesome-dev");
|
|
609
|
-
});
|
|
610
|
-
it("should not respond to grid navigation while modal is open", async () => {
|
|
611
|
-
mockSearch.mockResolvedValue(searchCandidates);
|
|
612
|
-
const onFocusChange = vi.fn();
|
|
613
|
-
const { stdin, unmount } = renderGrid({
|
|
614
|
-
rows: defaultRows,
|
|
615
|
-
defaultFocusedRow: 0,
|
|
616
|
-
defaultFocusedCol: 1,
|
|
617
|
-
onSearch: mockSearch,
|
|
618
|
-
onFocusChange
|
|
619
|
-
});
|
|
620
|
-
cleanup = unmount;
|
|
621
|
-
await delay(RENDER_DELAY_MS);
|
|
622
|
-
stdin.write(SPACE);
|
|
623
|
-
await delay(RENDER_DELAY_MS);
|
|
624
|
-
onFocusChange.mockClear();
|
|
625
|
-
stdin.write(ARROW_LEFT);
|
|
626
|
-
await delay(INPUT_DELAY_MS);
|
|
627
|
-
stdin.write(ARROW_RIGHT);
|
|
628
|
-
await delay(INPUT_DELAY_MS);
|
|
629
|
-
globalExpect(onFocusChange).not.toHaveBeenCalled();
|
|
630
|
-
});
|
|
631
|
-
it("should bind result on Enter in modal", async () => {
|
|
632
|
-
mockSearch.mockResolvedValue(searchCandidates);
|
|
633
|
-
const { stdin, unmount } = renderGrid({
|
|
634
|
-
rows: defaultRows,
|
|
635
|
-
defaultFocusedRow: 0,
|
|
636
|
-
defaultFocusedCol: 1,
|
|
637
|
-
onSearch: mockSearch,
|
|
638
|
-
onBind: mockBind,
|
|
639
|
-
onSearchStateChange: mockSearchStateChange
|
|
640
|
-
});
|
|
641
|
-
cleanup = unmount;
|
|
642
|
-
await delay(RENDER_DELAY_MS);
|
|
643
|
-
stdin.write(SPACE);
|
|
644
|
-
await delay(RENDER_DELAY_MS);
|
|
645
|
-
stdin.write(ENTER);
|
|
646
|
-
await delay(INPUT_DELAY_MS);
|
|
647
|
-
globalExpect(mockBind).toHaveBeenCalledWith(searchCandidates[0]);
|
|
648
|
-
globalExpect(mockSearchStateChange).toHaveBeenLastCalledWith(false);
|
|
649
|
-
});
|
|
650
|
-
});
|
|
651
|
-
describe("read-only rows", () => {
|
|
652
|
-
const readOnlyRows = [
|
|
653
|
-
createSourceRow(
|
|
654
|
-
"web-framework-react",
|
|
655
|
-
[createSourceOption("public", { selected: true }), createSourceOption("eject")],
|
|
656
|
-
"global",
|
|
657
|
-
true
|
|
658
|
-
),
|
|
659
|
-
createSourceRow(
|
|
660
|
-
"web-state-zustand",
|
|
661
|
-
[createSourceOption("public", { selected: true })],
|
|
662
|
-
"project"
|
|
663
|
-
)
|
|
664
|
-
];
|
|
665
|
-
it("should render read-only rows with lock indicator", () => {
|
|
666
|
-
const { lastFrame, unmount } = renderGrid({ rows: readOnlyRows });
|
|
667
|
-
cleanup = unmount;
|
|
668
|
-
const output = lastFrame();
|
|
669
|
-
globalExpect(output).toContain(UI_SYMBOLS.LOCK);
|
|
670
|
-
});
|
|
671
|
-
it("should render read-only rows with dimmed styling", () => {
|
|
672
|
-
const { lastFrame, unmount } = renderGrid({ rows: readOnlyRows });
|
|
673
|
-
cleanup = unmount;
|
|
674
|
-
const output = lastFrame();
|
|
675
|
-
globalExpect(output).toContain("React");
|
|
676
|
-
globalExpect(output).toContain("Zustand");
|
|
677
|
-
});
|
|
678
|
-
it("should not fire onSelect for read-only rows (defense-in-depth guard)", async () => {
|
|
679
|
-
const onSelect = vi.fn();
|
|
680
|
-
const { stdin, unmount } = renderGrid({
|
|
681
|
-
rows: readOnlyRows,
|
|
682
|
-
defaultFocusedRow: 0,
|
|
683
|
-
defaultFocusedCol: 0,
|
|
684
|
-
onSelect
|
|
685
|
-
});
|
|
686
|
-
cleanup = unmount;
|
|
687
|
-
await delay(RENDER_DELAY_MS);
|
|
688
|
-
stdin.write(SPACE);
|
|
689
|
-
await delay(INPUT_DELAY_MS);
|
|
690
|
-
globalExpect(onSelect).toHaveBeenCalledWith("web-state-zustand", "public");
|
|
691
|
-
});
|
|
692
|
-
it("should skip read-only rows during navigation", async () => {
|
|
693
|
-
const threeRows = [
|
|
694
|
-
createSourceRow(
|
|
695
|
-
"web-framework-react",
|
|
696
|
-
[createSourceOption("public", { selected: true })],
|
|
697
|
-
"global",
|
|
698
|
-
true
|
|
699
|
-
),
|
|
700
|
-
createSourceRow(
|
|
701
|
-
"web-state-zustand",
|
|
702
|
-
[createSourceOption("public", { selected: true })],
|
|
703
|
-
"project"
|
|
704
|
-
),
|
|
705
|
-
createSourceRow(
|
|
706
|
-
"web-testing-vitest",
|
|
707
|
-
[createSourceOption("public", { selected: true })],
|
|
708
|
-
"global",
|
|
709
|
-
true
|
|
710
|
-
)
|
|
711
|
-
];
|
|
712
|
-
const onFocusChange = vi.fn();
|
|
713
|
-
const { stdin, unmount } = renderGrid({
|
|
714
|
-
rows: threeRows,
|
|
715
|
-
defaultFocusedRow: 0,
|
|
716
|
-
defaultFocusedCol: 0,
|
|
717
|
-
onFocusChange
|
|
718
|
-
});
|
|
719
|
-
cleanup = unmount;
|
|
720
|
-
await delay(RENDER_DELAY_MS);
|
|
721
|
-
stdin.write(ARROW_DOWN);
|
|
722
|
-
await delay(INPUT_DELAY_MS);
|
|
723
|
-
globalExpect(onFocusChange).toHaveBeenLastCalledWith(1, 0);
|
|
724
|
-
});
|
|
725
|
-
it("should allow selection on non-read-only rows after navigating past read-only", async () => {
|
|
726
|
-
const onSelect = vi.fn();
|
|
727
|
-
const { stdin, unmount } = renderGrid({
|
|
728
|
-
rows: readOnlyRows,
|
|
729
|
-
defaultFocusedRow: 1,
|
|
730
|
-
defaultFocusedCol: 0,
|
|
731
|
-
onSelect
|
|
732
|
-
});
|
|
733
|
-
cleanup = unmount;
|
|
734
|
-
await delay(RENDER_DELAY_MS);
|
|
735
|
-
stdin.write(SPACE);
|
|
736
|
-
await delay(INPUT_DELAY_MS);
|
|
737
|
-
globalExpect(onSelect).toHaveBeenCalledWith("web-state-zustand", "public");
|
|
738
|
-
});
|
|
739
|
-
it("should not show search pill on read-only rows", () => {
|
|
740
|
-
const mockSearch = vi.fn();
|
|
741
|
-
const { lastFrame, unmount } = renderGrid({
|
|
742
|
-
rows: [
|
|
743
|
-
createSourceRow(
|
|
744
|
-
"web-framework-react",
|
|
745
|
-
[createSourceOption("public", { selected: true })],
|
|
746
|
-
"global",
|
|
747
|
-
true
|
|
748
|
-
)
|
|
749
|
-
],
|
|
750
|
-
onSearch: mockSearch
|
|
751
|
-
});
|
|
752
|
-
cleanup = unmount;
|
|
753
|
-
const output = lastFrame();
|
|
754
|
-
globalExpect(output).toContain("React");
|
|
755
|
-
globalExpect(output).not.toContain("Search");
|
|
756
|
-
});
|
|
757
|
-
it("should not show focus highlight on read-only rows", () => {
|
|
758
|
-
const allReadOnlyRows = [
|
|
759
|
-
createSourceRow(
|
|
760
|
-
"web-framework-react",
|
|
761
|
-
[createSourceOption("public", { selected: true })],
|
|
762
|
-
"global",
|
|
763
|
-
true
|
|
764
|
-
),
|
|
765
|
-
createSourceRow(
|
|
766
|
-
"web-state-zustand",
|
|
767
|
-
[createSourceOption("public", { selected: true })],
|
|
768
|
-
"global",
|
|
769
|
-
true
|
|
770
|
-
)
|
|
771
|
-
];
|
|
772
|
-
const { lastFrame, unmount } = renderGrid({
|
|
773
|
-
rows: allReadOnlyRows,
|
|
774
|
-
defaultFocusedRow: 0,
|
|
775
|
-
defaultFocusedCol: 0
|
|
776
|
-
});
|
|
777
|
-
cleanup = unmount;
|
|
778
|
-
const output = lastFrame();
|
|
779
|
-
globalExpect(output).not.toContain(UI_SYMBOLS.CHEVRON);
|
|
780
|
-
});
|
|
781
|
-
it("should render re-scoped skill once per scope group", () => {
|
|
782
|
-
const reSccopedRows = [
|
|
783
|
-
createSourceRow(
|
|
784
|
-
"web-framework-react",
|
|
785
|
-
[createSourceOption("eject"), createSourceOption("public", { selected: true })],
|
|
786
|
-
"global",
|
|
787
|
-
true
|
|
788
|
-
),
|
|
789
|
-
createSourceRow(
|
|
790
|
-
"web-framework-react",
|
|
791
|
-
[createSourceOption("eject"), createSourceOption("public", { selected: true })],
|
|
792
|
-
"project"
|
|
793
|
-
)
|
|
794
|
-
];
|
|
795
|
-
const { lastFrame, unmount } = renderGrid({ rows: reSccopedRows });
|
|
796
|
-
cleanup = unmount;
|
|
797
|
-
const output = lastFrame();
|
|
798
|
-
const reactMatches = output.split("React").length - 1;
|
|
799
|
-
globalExpect(reactMatches).toBe(2);
|
|
800
|
-
globalExpect(output).toContain(UI_SYMBOLS.LOCK);
|
|
801
|
-
});
|
|
802
|
-
});
|
|
803
|
-
describe("removed (disabled) rows", () => {
|
|
804
|
-
const removedRows = [
|
|
805
|
-
createSourceRow(
|
|
806
|
-
"web-framework-react",
|
|
807
|
-
[createSourceOption("public", { selected: true })],
|
|
808
|
-
"project"
|
|
809
|
-
),
|
|
810
|
-
createRemovedRow(
|
|
811
|
-
"web-testing-vitest",
|
|
812
|
-
[createSourceOption("eject", { selected: true }), createSourceOption("public")],
|
|
813
|
-
"project"
|
|
814
|
-
)
|
|
815
|
-
];
|
|
816
|
-
it("should keep the removed skill visible", () => {
|
|
817
|
-
const { lastFrame, unmount } = renderGrid({ rows: removedRows });
|
|
818
|
-
cleanup = unmount;
|
|
819
|
-
globalExpect(lastFrame()).toContain("Vitest");
|
|
820
|
-
});
|
|
821
|
-
it("should mark the removed skill with the pending-removal marker and no lock", () => {
|
|
822
|
-
const { lastFrame, unmount } = renderGrid({ rows: removedRows });
|
|
823
|
-
cleanup = unmount;
|
|
824
|
-
const output = lastFrame();
|
|
825
|
-
globalExpect(output).toContain(`${UI_SYMBOLS.REMOVED} Vitest`);
|
|
826
|
-
globalExpect(output).not.toContain(UI_SYMBOLS.LOCK);
|
|
827
|
-
});
|
|
828
|
-
it("should not fire onSelect when space is pressed with a removed row focused", async () => {
|
|
829
|
-
const onSelect = vi.fn();
|
|
830
|
-
const { stdin, unmount } = renderGrid({
|
|
831
|
-
rows: [removedRows[1]],
|
|
832
|
-
defaultFocusedRow: 0,
|
|
833
|
-
defaultFocusedCol: 0,
|
|
834
|
-
onSelect
|
|
835
|
-
});
|
|
836
|
-
cleanup = unmount;
|
|
837
|
-
await delay(RENDER_DELAY_MS);
|
|
838
|
-
stdin.write(SPACE);
|
|
839
|
-
await delay(INPUT_DELAY_MS);
|
|
840
|
-
globalExpect(onSelect).not.toHaveBeenCalled();
|
|
841
|
-
});
|
|
842
|
-
it("should skip removed rows during navigation", async () => {
|
|
843
|
-
const onFocusChange = vi.fn();
|
|
844
|
-
const { stdin, unmount } = renderGrid({
|
|
845
|
-
rows: removedRows,
|
|
846
|
-
defaultFocusedRow: 0,
|
|
847
|
-
defaultFocusedCol: 0,
|
|
848
|
-
onFocusChange
|
|
849
|
-
});
|
|
850
|
-
cleanup = unmount;
|
|
851
|
-
await delay(RENDER_DELAY_MS);
|
|
852
|
-
stdin.write(ARROW_DOWN);
|
|
853
|
-
await delay(INPUT_DELAY_MS);
|
|
854
|
-
globalExpect(onFocusChange).toHaveBeenLastCalledWith(0, 0);
|
|
855
|
-
});
|
|
856
|
-
it("should not focus a removed row when it is the default focus target", async () => {
|
|
857
|
-
const onSelect = vi.fn();
|
|
858
|
-
const { stdin, unmount } = renderGrid({
|
|
859
|
-
rows: removedRows,
|
|
860
|
-
defaultFocusedRow: 1,
|
|
861
|
-
// The removed row — focus must fall back to the editable row.
|
|
862
|
-
defaultFocusedCol: 0,
|
|
863
|
-
onSelect
|
|
864
|
-
});
|
|
865
|
-
cleanup = unmount;
|
|
866
|
-
await delay(RENDER_DELAY_MS);
|
|
867
|
-
stdin.write(SPACE);
|
|
868
|
-
await delay(INPUT_DELAY_MS);
|
|
869
|
-
globalExpect(onSelect).toHaveBeenCalledWith("web-framework-react", "public");
|
|
870
|
-
});
|
|
871
|
-
it("should not show search pill on removed rows", () => {
|
|
872
|
-
const mockSearch = vi.fn();
|
|
873
|
-
const { lastFrame, unmount } = renderGrid({
|
|
874
|
-
rows: [removedRows[1]],
|
|
875
|
-
onSearch: mockSearch
|
|
876
|
-
});
|
|
877
|
-
cleanup = unmount;
|
|
878
|
-
const output = lastFrame();
|
|
879
|
-
globalExpect(output).toContain("Vitest");
|
|
880
|
-
globalExpect(output).not.toContain("Search");
|
|
881
|
-
});
|
|
882
|
-
it("should not show focus highlight on removed rows", () => {
|
|
883
|
-
const { lastFrame, unmount } = renderGrid({
|
|
884
|
-
rows: [removedRows[1]],
|
|
885
|
-
defaultFocusedRow: 0,
|
|
886
|
-
defaultFocusedCol: 0
|
|
887
|
-
});
|
|
888
|
-
cleanup = unmount;
|
|
889
|
-
globalExpect(lastFrame()).not.toContain(UI_SYMBOLS.CHEVRON);
|
|
890
|
-
});
|
|
891
|
-
describe("collapsed dual-scope pair", () => {
|
|
892
|
-
const COLLAPSED_SKILL_ID = "web-framework-react";
|
|
893
|
-
const UNTOUCHED_SKILL_ID = "web-state-zustand";
|
|
894
|
-
const collapsedPairRows = [
|
|
895
|
-
createSourceRow(
|
|
896
|
-
COLLAPSED_SKILL_ID,
|
|
897
|
-
[createSourceOption("public", { selected: true })],
|
|
898
|
-
"global",
|
|
899
|
-
true
|
|
900
|
-
),
|
|
901
|
-
createRemovedRow(
|
|
902
|
-
COLLAPSED_SKILL_ID,
|
|
903
|
-
[createSourceOption("public", { selected: true })],
|
|
904
|
-
"project"
|
|
905
|
-
)
|
|
906
|
-
];
|
|
907
|
-
let previousChalkLevel;
|
|
908
|
-
beforeEach(() => {
|
|
909
|
-
previousChalkLevel = source_default.level;
|
|
910
|
-
source_default.level = TRUECOLOR_CHALK_LEVEL;
|
|
911
|
-
});
|
|
912
|
-
afterEach(() => {
|
|
913
|
-
source_default.level = previousChalkLevel;
|
|
914
|
-
});
|
|
915
|
-
it("should render the same skill in both scope sections, locked at global and pending removal at project", () => {
|
|
916
|
-
const { lastFrame, unmount } = renderGrid({ rows: collapsedPairRows });
|
|
917
|
-
cleanup = unmount;
|
|
918
|
-
const output = lastFrame();
|
|
919
|
-
const skillName = getSkillById(COLLAPSED_SKILL_ID).displayName;
|
|
920
|
-
globalExpect(
|
|
921
|
-
output,
|
|
922
|
-
`the surviving global install must keep its lock. Frame:
|
|
923
|
-
${JSON.stringify(output)}`
|
|
924
|
-
).toContain(`${UI_SYMBOLS.LOCK} ${skillName}`);
|
|
925
|
-
globalExpect(
|
|
926
|
-
output,
|
|
927
|
-
`the emptied project slot must carry the removal marker. Frame:
|
|
928
|
-
${JSON.stringify(output)}`
|
|
929
|
-
).toContain(`${UI_SYMBOLS.REMOVED} ${skillName}`);
|
|
930
|
-
globalExpect(output).not.toContain(`${UI_SYMBOLS.ADDED} ${skillName}`);
|
|
931
|
-
});
|
|
932
|
-
it("should render the project instance of the pair in the removed-diff colour", () => {
|
|
933
|
-
const { lastFrame, unmount } = renderGrid({ rows: collapsedPairRows });
|
|
934
|
-
cleanup = unmount;
|
|
935
|
-
const output = lastFrame();
|
|
936
|
-
const skillName = getSkillById(COLLAPSED_SKILL_ID).displayName;
|
|
937
|
-
globalExpect(
|
|
938
|
-
output,
|
|
939
|
-
`the pending-removal row must render in the removed-diff colour. Frame:
|
|
940
|
-
${JSON.stringify(output)}`
|
|
941
|
-
).toContain(source_default.hex(CLI_COLORS.ERROR)(`${UI_SYMBOLS.REMOVED} ${skillName}`));
|
|
942
|
-
});
|
|
943
|
-
it("should not fire onSelect when space is pressed on an all-inert collapsed pair", async () => {
|
|
944
|
-
const onSelect = vi.fn();
|
|
945
|
-
const { stdin, unmount } = renderGrid({
|
|
946
|
-
rows: collapsedPairRows,
|
|
947
|
-
defaultFocusedRow: 0,
|
|
948
|
-
defaultFocusedCol: 0,
|
|
949
|
-
onSelect
|
|
950
|
-
});
|
|
951
|
-
cleanup = unmount;
|
|
952
|
-
await delay(RENDER_DELAY_MS);
|
|
953
|
-
stdin.write(SPACE);
|
|
954
|
-
await delay(INPUT_DELAY_MS);
|
|
955
|
-
globalExpect(onSelect).not.toHaveBeenCalled();
|
|
956
|
-
});
|
|
957
|
-
it("should not show focus highlight on either row of the collapsed pair", () => {
|
|
958
|
-
const { lastFrame, unmount } = renderGrid({
|
|
959
|
-
rows: collapsedPairRows,
|
|
960
|
-
defaultFocusedRow: 0,
|
|
961
|
-
defaultFocusedCol: 0
|
|
962
|
-
});
|
|
963
|
-
cleanup = unmount;
|
|
964
|
-
globalExpect(lastFrame()).not.toContain(UI_SYMBOLS.CHEVRON);
|
|
965
|
-
});
|
|
966
|
-
it("should skip both rows of the collapsed pair and act on the editable row instead", async () => {
|
|
967
|
-
const onSelect = vi.fn();
|
|
968
|
-
const { stdin, unmount } = renderGrid({
|
|
969
|
-
rows: [
|
|
970
|
-
...collapsedPairRows,
|
|
971
|
-
createSourceRow(
|
|
972
|
-
UNTOUCHED_SKILL_ID,
|
|
973
|
-
[createSourceOption("public", { selected: true })],
|
|
974
|
-
"project"
|
|
975
|
-
)
|
|
976
|
-
],
|
|
977
|
-
// The locked half of the pair — focus must fall through it AND the pending-removal row.
|
|
978
|
-
defaultFocusedRow: 0,
|
|
979
|
-
defaultFocusedCol: 0,
|
|
980
|
-
onSelect
|
|
981
|
-
});
|
|
982
|
-
cleanup = unmount;
|
|
983
|
-
await delay(RENDER_DELAY_MS);
|
|
984
|
-
stdin.write(SPACE);
|
|
985
|
-
await delay(INPUT_DELAY_MS);
|
|
986
|
-
globalExpect(onSelect).toHaveBeenCalledWith(UNTOUCHED_SKILL_ID, "public");
|
|
987
|
-
globalExpect(onSelect).not.toHaveBeenCalledWith(COLLAPSED_SKILL_ID, "public");
|
|
988
|
-
});
|
|
989
|
-
});
|
|
990
|
-
});
|
|
991
|
-
describe("added rows", () => {
|
|
992
|
-
const ADDED_SKILL_ID = "web-framework-react";
|
|
993
|
-
const addedRows = [
|
|
994
|
-
createAddedRow(ADDED_SKILL_ID, [createSourceOption("public", { selected: true })], "project"),
|
|
995
|
-
createSourceRow(
|
|
996
|
-
"web-state-zustand",
|
|
997
|
-
[createSourceOption("public", { selected: true })],
|
|
998
|
-
"project"
|
|
999
|
-
)
|
|
1000
|
-
];
|
|
1001
|
-
let previousChalkLevel;
|
|
1002
|
-
beforeEach(() => {
|
|
1003
|
-
previousChalkLevel = source_default.level;
|
|
1004
|
-
source_default.level = TRUECOLOR_CHALK_LEVEL;
|
|
1005
|
-
});
|
|
1006
|
-
afterEach(() => {
|
|
1007
|
-
source_default.level = previousChalkLevel;
|
|
1008
|
-
});
|
|
1009
|
-
it("should mark the added skill with the added marker", () => {
|
|
1010
|
-
const { lastFrame, unmount } = renderGrid({
|
|
1011
|
-
rows: addedRows,
|
|
1012
|
-
defaultFocusedRow: 1,
|
|
1013
|
-
defaultFocusedCol: 0
|
|
1014
|
-
});
|
|
1015
|
-
cleanup = unmount;
|
|
1016
|
-
const output = lastFrame();
|
|
1017
|
-
globalExpect(output).toContain(`${UI_SYMBOLS.ADDED} ${getSkillById(ADDED_SKILL_ID).displayName}`);
|
|
1018
|
-
});
|
|
1019
|
-
it("should keep the added-diff colour on the added row while it is focused", () => {
|
|
1020
|
-
const { lastFrame, unmount } = renderGrid({
|
|
1021
|
-
rows: addedRows,
|
|
1022
|
-
defaultFocusedRow: 0,
|
|
1023
|
-
defaultFocusedCol: 0
|
|
1024
|
-
});
|
|
1025
|
-
cleanup = unmount;
|
|
1026
|
-
const focusedLabel = `${UI_SYMBOLS.ADDED} ${getSkillById(ADDED_SKILL_ID).displayName} `;
|
|
1027
|
-
const output = lastFrame();
|
|
1028
|
-
globalExpect(
|
|
1029
|
-
output,
|
|
1030
|
-
`a focused added row must keep its added-diff colour. Frame:
|
|
1031
|
-
${JSON.stringify(output)}`
|
|
1032
|
-
).toContain(source_default.bgHex(CLI_COLORS.LABEL_BG)(source_default.hex(CLI_COLORS.SUCCESS)(focusedLabel)));
|
|
1033
|
-
globalExpect(
|
|
1034
|
-
output,
|
|
1035
|
-
"a focused added row must not fall back to the plain white label colour"
|
|
1036
|
-
).not.toContain(source_default.bgHex(CLI_COLORS.LABEL_BG)(source_default.hex(CLI_COLORS.WHITE)(focusedLabel)));
|
|
1037
|
-
});
|
|
1038
|
-
});
|
|
1039
|
-
describe("inert row source selection", () => {
|
|
1040
|
-
const LOCKED_ROW = createSourceRow(
|
|
1041
|
-
"web-framework-react",
|
|
1042
|
-
[createSourceOption("public", { selected: true }), createSourceOption("eject")],
|
|
1043
|
-
"global",
|
|
1044
|
-
true
|
|
1045
|
-
);
|
|
1046
|
-
const REMOVAL_ROW = createRemovedRow(
|
|
1047
|
-
"web-testing-vitest",
|
|
1048
|
-
[createSourceOption("eject", { selected: true }), createSourceOption("public")],
|
|
1049
|
-
"project"
|
|
1050
|
-
);
|
|
1051
|
-
const INERT_PREFIX = `${UI_SYMBOLS.CHEVRON_SPACER} `;
|
|
1052
|
-
let previousChalkLevel;
|
|
1053
|
-
beforeEach(() => {
|
|
1054
|
-
previousChalkLevel = source_default.level;
|
|
1055
|
-
source_default.level = TRUECOLOR_CHALK_LEVEL;
|
|
1056
|
-
});
|
|
1057
|
-
afterEach(() => {
|
|
1058
|
-
source_default.level = previousChalkLevel;
|
|
1059
|
-
});
|
|
1060
|
-
it("should carry the locked row's selection in weight and brightness, not a check", () => {
|
|
1061
|
-
const { lastFrame, unmount } = renderGrid({ rows: [LOCKED_ROW] });
|
|
1062
|
-
cleanup = unmount;
|
|
1063
|
-
const output = lastFrame();
|
|
1064
|
-
globalExpect(
|
|
1065
|
-
output,
|
|
1066
|
-
`the locked row's selected source must render bold. Frame:
|
|
1067
|
-
${JSON.stringify(output)}`
|
|
1068
|
-
).toContain(source_default.bold(`${INERT_PREFIX}Public`));
|
|
1069
|
-
globalExpect(
|
|
1070
|
-
output,
|
|
1071
|
-
`the locked row's unselected sources must stay dimmed. Frame:
|
|
1072
|
-
${JSON.stringify(output)}`
|
|
1073
|
-
).toContain(source_default.dim(`${INERT_PREFIX}Eject`));
|
|
1074
|
-
globalExpect(output).not.toContain(UI_SYMBOLS.SELECTED);
|
|
1075
|
-
});
|
|
1076
|
-
it("should carry the pending-removal row's selection in weight while keeping its removal colour", () => {
|
|
1077
|
-
const { lastFrame, unmount } = renderGrid({ rows: [REMOVAL_ROW] });
|
|
1078
|
-
cleanup = unmount;
|
|
1079
|
-
const output = lastFrame();
|
|
1080
|
-
globalExpect(
|
|
1081
|
-
output,
|
|
1082
|
-
`the removal row's selected source must render bold in the removal colour. Frame:
|
|
1083
|
-
${JSON.stringify(output)}`
|
|
1084
|
-
).toContain(source_default.bold(source_default.hex(CLI_COLORS.ERROR)(`${INERT_PREFIX}Eject`)));
|
|
1085
|
-
globalExpect(
|
|
1086
|
-
output,
|
|
1087
|
-
`the removal row's unselected sources must keep the removal colour unbolded. Frame:
|
|
1088
|
-
${JSON.stringify(output)}`
|
|
1089
|
-
).toContain(source_default.hex(CLI_COLORS.ERROR)(`${INERT_PREFIX}Public`));
|
|
1090
|
-
globalExpect(output).not.toContain(UI_SYMBOLS.SELECTED);
|
|
1091
|
-
});
|
|
1092
|
-
});
|
|
1093
|
-
});
|
|
1094
|
-
//# sourceMappingURL=source-grid.test.js.map
|