@@ -1126,6 +1126,118 @@ describe('validate', () => {
11261126 expect ( result . valid ) . toBe ( false ) ;
11271127 expect ( result . error ) . toContain ( 'does not match the expected schema' ) ;
11281128 } ) ;
1129+
1130+ // Indexed keys: requires LTM strategy
1131+ it ( 'rejects --indexed-key without any LTM strategy' , ( ) => {
1132+ const result = validateAddMemoryOptions ( {
1133+ ...validMemoryOptions ,
1134+ strategies : undefined ,
1135+ indexedKey : [ 'priority:NUMBER' ] ,
1136+ } ) ;
1137+ expect ( result . valid ) . toBe ( false ) ;
1138+ expect ( result . error ) . toContain ( 'requires at least one long-term memory strategy' ) ;
1139+ } ) ;
1140+
1141+ it ( 'accepts --indexed-key with an LTM strategy' , ( ) => {
1142+ expect (
1143+ validateAddMemoryOptions ( {
1144+ ...validMemoryOptions ,
1145+ strategies : 'SEMANTIC' ,
1146+ indexedKey : [ 'priority:NUMBER' ] ,
1147+ } )
1148+ ) . toEqual ( { valid : true } ) ;
1149+ } ) ;
1150+
1151+ it ( 'rejects more than 10 indexed keys' , ( ) => {
1152+ const eleven = Array . from ( { length : 11 } , ( _ , i ) => `k${ i } :STRING` ) ;
1153+ const result = validateAddMemoryOptions ( {
1154+ ...validMemoryOptions ,
1155+ strategies : 'SEMANTIC' ,
1156+ indexedKey : eleven ,
1157+ } ) ;
1158+ expect ( result . valid ) . toBe ( false ) ;
1159+ expect ( result . error ) . toContain ( 'Maximum 10 indexed keys' ) ;
1160+ } ) ;
1161+
1162+ it ( 'accepts exactly 10 indexed keys (boundary)' , ( ) => {
1163+ const ten = Array . from ( { length : 10 } , ( _ , i ) => `k${ i } :STRING` ) ;
1164+ expect ( validateAddMemoryOptions ( { ...validMemoryOptions , strategies : 'SEMANTIC' , indexedKey : ten } ) ) . toEqual ( {
1165+ valid : true ,
1166+ } ) ;
1167+ } ) ;
1168+
1169+ it ( 'rejects an empty key (":STRING")' , ( ) => {
1170+ const result = validateAddMemoryOptions ( {
1171+ ...validMemoryOptions ,
1172+ strategies : 'SEMANTIC' ,
1173+ indexedKey : [ ':STRING' ] ,
1174+ } ) ;
1175+ expect ( result . valid ) . toBe ( false ) ;
1176+ expect ( result . error ) . toContain ( 'Key name cannot be empty' ) ;
1177+ } ) ;
1178+
1179+ it ( 'rejects a key longer than 128 characters' , ( ) => {
1180+ const longKey = 'a' . repeat ( 129 ) ;
1181+ const result = validateAddMemoryOptions ( {
1182+ ...validMemoryOptions ,
1183+ strategies : 'SEMANTIC' ,
1184+ indexedKey : [ `${ longKey } :STRING` ] ,
1185+ } ) ;
1186+ expect ( result . valid ) . toBe ( false ) ;
1187+ expect ( result . error ) . toContain ( 'exceeds maximum length' ) ;
1188+ } ) ;
1189+
1190+ it ( 'rejects an invalid type token' , ( ) => {
1191+ const result = validateAddMemoryOptions ( {
1192+ ...validMemoryOptions ,
1193+ strategies : 'SEMANTIC' ,
1194+ indexedKey : [ 'priority:INTEGER' ] ,
1195+ } ) ;
1196+ expect ( result . valid ) . toBe ( false ) ;
1197+ expect ( result . error ) . toContain ( 'Invalid type' ) ;
1198+ } ) ;
1199+
1200+ it ( 'rejects duplicate keys' , ( ) => {
1201+ const result = validateAddMemoryOptions ( {
1202+ ...validMemoryOptions ,
1203+ strategies : 'SEMANTIC' ,
1204+ indexedKey : [ 'priority:NUMBER' , 'priority:STRING' ] ,
1205+ } ) ;
1206+ expect ( result . valid ) . toBe ( false ) ;
1207+ expect ( result . error ) . toContain ( 'Duplicate indexed key' ) ;
1208+ } ) ;
1209+
1210+ it ( 'rejects whitespace-only key' , ( ) => {
1211+ const result = validateAddMemoryOptions ( {
1212+ ...validMemoryOptions ,
1213+ strategies : 'SEMANTIC' ,
1214+ indexedKey : [ ' :STRING' ] ,
1215+ } ) ;
1216+ expect ( result . valid ) . toBe ( false ) ;
1217+ expect ( result . error ) . toContain ( 'whitespace' ) ;
1218+ } ) ;
1219+
1220+ it ( 'rejects malformed entry without colon' , ( ) => {
1221+ const result = validateAddMemoryOptions ( {
1222+ ...validMemoryOptions ,
1223+ strategies : 'SEMANTIC' ,
1224+ indexedKey : [ 'priority' ] ,
1225+ } ) ;
1226+ expect ( result . valid ) . toBe ( false ) ;
1227+ expect ( result . error ) . toContain ( 'Expected key:TYPE' ) ;
1228+ } ) ;
1229+
1230+ it . each ( [
1231+ [ 'user.email:STRING' ] ,
1232+ [ 'tag/v2:STRINGLIST' ] ,
1233+ [ 'kebab-case:STRING' ] ,
1234+ [ 'x-custom:STRING' ] ,
1235+ [ 'has:colons:in:key:NUMBER' ] ,
1236+ ] ) ( 'accepts punctuation-rich key %s' , raw => {
1237+ expect ( validateAddMemoryOptions ( { ...validMemoryOptions , strategies : 'SEMANTIC' , indexedKey : [ raw ] } ) ) . toEqual ( {
1238+ valid : true ,
1239+ } ) ;
1240+ } ) ;
11291241 } ) ;
11301242
11311243 describe ( 'validateAddCredentialOptions' , ( ) => {
0 commit comments